5

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?

2 Answers 2

6
+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. Commented May 7, 2021 at 13:46
  • +1 this is neat
    – DG'
    Commented May 7, 2021 at 15:39
3

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. Commented May 7, 2021 at 13:40
  • 1
    @PedroTiagoMartins It was a fun problem to look at, nonetheless. Commented May 7, 2021 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. Commented May 7, 2021 at 13:43

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .