4

biblatex (with biber) supports all kinds of date information, including ranges. Dates follow ISO 8601, which is great, and they are localized (plays nice with babel).

I would like to get localized date ranges in-text, not associated with bib entries. Basically, the biblatex way of handling dates but not while using bibliographies. I want to do something like \datecommand{2012-10-01/2012-10-12) and get

Oct. 1–12, 2012

Then switch to portuges and get

1–12 de out. de 2012

And so on for several more languages. I've tried two options, to no avail:

  • datetime2: localized, but no date ranges (I've seen code for how to create a date range, but I gather one would need to rewrite it for each language)
  • isodate: date ranges, but not localized beyond several English varieties and a few (but not many) languages; it doesn't cover all the languages I need.

Is there any obvious way to do what I'm looking for?

5
+50

well you could use biblatex + biber:

\documentclass{article}
\usepackage{biblatex}
\addbibresource{autogenerated-dates.bib}
\newwrite\mydates
\newcounter{datecnt}
\NewDocumentCommand\datecommand {m}
{%
  \stepcounter{datecnt}%
  \immediate\write\mydates{@misc{date\thedatecnt,date={#1}}}%
  \citedate{date\thedatecnt}%
}
\AtBeginDocument{\immediate\openout\mydates=autogenerated-dates.bib}
\AtEndDocument{\immediate\closeout\mydates}
\begin{document}
\datecommand{2012-10-01/2012-10-12}

\datecommand{2018/2020}
\end{document}

enter image description here

2
  • This solves my problem.So it seems that a solution is to actually use biblatex. It actually crossed my mind before to have ad hoc entries for each date I wanted, but that would soon get cumbersome, and I had no idea how to generate the entries on the fly. May 7 at 13:46
  • +1 this is neat
    – DG'
    May 7 at 15:39
2

The strategy here has several components to develop \datecommand, as requested by the OP. First, I had to examine which of three different branches to use:

  1. sharing a common month and year (\dayrange)

  2. sharing a common year (\monthrange)

  3. spanning beyond a year's boundary (\yearrange}

Then, for branches 1 and 2, I had to develop special routines to override the checks and behavior employed by datetime2. In the end, I found that a routine \DTMifbool, with four arguments, was used to typeset the various pieces. Therefore, I had to selectively replace this macro with an alternative, when needed.

In case 1, I had to compare argument #2 to the string showdayofmonth. If I found a match, I replaced \DTMifbool with \altADTMifbool, which did no checks on day's format, so that I could replace the day with a range like 1--12. The replacement also prevented the day's suffix like st, nd and rd from being printed.

In case 2, I had to compare argument #2 to the string showyear. If I found a match, I replaced DTMifbool with \altBDTMifbool, which basically shut down the call altogether, so that no separator nor year were printed (example de 2012). I then restored \DTMifbool and finished up with -- <closing date>/

In case 3, I simply typeset <opening date> -- <closing date>.

In the MWE, I show the three branches, each for british, french, and portuges language styles.

\documentclass{article}
\usepackage[french,british,portuges]{babel}
\usepackage[useregional,calc]{datetime2}
%%%%%%%%%%%%% WORKS FOR LUA + XELATEX + PDFLATEX ENGINES
%\usepackage{pdftexcmds}
%\makeatletter
%\let\strcmp\pdf@strcmp
%\makeatother
%%%%%%%%%%%%% WORKS ONLY FOR PDFLATEX AND XELATEX ENGINES
\let\strcmp\pdfstrcmp
%%%%%%%%%%%%% END
\DTMusemodule{british}{en-GB}
\DTMusemodule{french}{french}
\DTMusemodule{portuges}{portuges}

\newcommand\datecommand[1]{\dcaux(#1)}
\def\dcaux(#1-#2-#3/#4-#5-#6){%
  \ifnum\strcmp{#1}{#4}=0\relax
    \ifnum\strcmp{#2}{#5}=0\relax
      \dayrange{#1}{#2}{#3}{#6}%
    \else
      \monthrange{#1}{#2}{#3}{#5}{#6}%
    \fi
  \else
    \yearrange{#1}{#2}{#3}{#4}{#5}{#6}%
  \fi
}

\let\svDTMifbool\DTMifbool

\newcommand\altADTMifbool[4]{%
  \ifnum\strcmp{#2}{showdayofmonth}=0\relax
    \expandafter\noparsedayofmonth
  \else
    \svDTMifbool{#1}{#2}{#3}{#4}%
  \fi
}
\newcommand\altBDTMifbool[4]{%
  \ifnum\strcmp{#2}{showyear}=0\relax
  \else
    \svDTMifbool{#1}{#2}{#3}{#4}%
  \fi
}

\newcommand\dayrange[4]{%
  \begingroup
  \let\DTMifbool\altADTMifbool
  \def\noparsedayofmonth{\number#3--\number#4\ }%
  \DTMdate{#1-#2-1}
  \endgroup
}
\newcommand\monthrange[5]{%
  \begingroup
  \let\DTMifbool\altBDTMifbool
  \DTMdate{#1-#2-#3}
  \endgroup
  -- \DTMdate{#1-#4-#5}%
}
\newcommand\yearrange[6]{%
  \DTMdate{#1-#2-#3} -- \DTMdate{#4-#5-#6}%
}
\begin{document}
\newcommand\branchtests{%
\par\datecommand{2012-10-01/2012-10-12}
\par\datecommand{2012-10-01/2012-11-3}
\par\datecommand{2012-10-01/2013-1-4}\par}

\selectlanguage{british}\branchtests
\hrulefill\selectlanguage{french}\branchtests
\hrulefill\selectlanguage{portuges}\branchtests
\end{document}

enter image description here

3
  • This is quite a nice solution for dates and date ranges with a specified year, month, and day, but it does not work in any other case (say, 2009, 2010-10, and 2010-10/2011-09 would not work). I should perhaps have been clearer in my question, because this does of course work for the examples I gave, but it's not the biblatex, ISO 8601 compliant way of handling dates, and will not handle other examples I will use but didn't provide. May 7 at 13:40
  • 1
    @PedroTiagoMartins It was a fun problem to look at, nonetheless. May 7 at 13:41
  • For sure! Both your answer and the one I accepted are above my ability and I learned a lot just going through how you tackled it. May 7 at 13:43

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.