2

How do I create a bibcheck that would only print publications between two dates, let's say between May 1st, 2017 and April 30th, 2018? Using biblatex 3.9, biber 2.10 on Mac OS X 10.13.4, compiling with XeLatex in TexShop.

The Biblatex manual provides \defbibcheck. In the example below, \defbibcheck is used to print publications since the year 2000. But I don't know how to modify it to print only publications between two dates.

\defbibcheck{recent}{%
\iffieldint{year}
{\ifnumless{\thefield{year}}{2000}
{\skipentry}
{}}
{\skipentry}}

MWE Below

\documentclass{article}
\usepackage{biblatex}

\usepackage{filecontents}
\begin{filecontents}{\jobname.bib}
    @article{greenwade93,
        author  = "A Guy",
        title   = "A document",
        date    = "2016-01-05",
        journal = "Journal of Post-Modern Mysticisms",
        volume  = "14",
        number  = "3",
        pages   = "342--351"
    }

    @book{abook,
        author    = "An Other Auther",
        title     = "Something Really Important",
        date      = "2017-06-01",
        publisher = "Addison-Wesley",
        address   = "Somewhere Town"
    }
    \end{filecontents}



\addbibresource{\jobname.bib}
\begin{document}
Test
\nocite{*}
\printbibliography
\end{document}
  • \defbibcheck{recent}{% \iffieldint{year} {\ifnumless{\thefield{year}}{2000} {\skipentry} {\ifnumgreater{\thefield{year}}{2012} {\skipentry} {}}} {\skipentry}} prints all entries with 2000 <= year <= 2012. – moewe Apr 12 '18 at 20:37
  • 1
    Ha! I knew there was something similar: tex.stackexchange.com/q/346270/35864 – moewe Apr 12 '18 at 20:39
  • 1
    I understand you want to cut up to "day precision" of the date. But, for example, what should happen if an entry had date = {2017}, that is, only with the year information? Should it be included in that interval? – gusbrs Apr 12 '18 at 20:41
  • Sadly, I do want to specify the day. It's for my annual report, and the year runs from May 1st to April 30th. So I'd like to only print documents that appear in those days, or, possibly just after May 1st. So I realize I do need to be accurate in the underlying bib file, but it's not that many documents. – spindoctor Apr 13 '18 at 2:18
2

A straightforward way is to add a test if your entry was written (on or) after a specific date. That can then be used as in biblatex, biber, is it possible to \printbibliography between two years?. The test is very naive at the moment and will throw an error if an entry without month or day information is encountered - of course one could guard against that, but it is not sure whether something written in year = {2018} is from after 2018-05-08 or not.

\ifdateafter{yyyy}{mm}{dd} checks if an entry's date is after yyyy-mm-dd (">"), \ifdateonorafter{yyyy}{mm}{dd} checks if the date is not before yyyy-mm-dd (">="). The commands have an optional argument that can be used to check different dates, use \ifdateonorafter[url] to check the URL date of an entry or \ifdateonorafter[orig] to check the origdate field; the default is an empty optional argument, which checks date.

You can now use \ifdateonorafter in \defbibcheck to only select entries written on or after 2017-05-01 but before 2018-05-01.

\documentclass{article}
\usepackage{biblatex}

% this macro is not used in the check below, but might still be useful
% check if entry's date > {yyyy}{mm}{dd} 
\newcommand*{\ifdateafter}[4][]{%
  \ifboolexpr{test {\ifnumgreater{\thefield{#1year}}{#2}}
              or (test {\ifnumequal{\thefield{#1year}}{#2}}
                  and (test {\ifnumgreater{\thefield{#1month}}{#3}}
                       or (test {\ifnumequal{\thefield{#1month}}{#3}}
                           and test {\ifnumgreater{\thefield{#1day}}{#4}})))}}

% check if entry's date >= {yyyy}{mm}{dd} 
\newcommand*{\ifdateonorafter}[4][]{%
  \ifboolexpr{test {\ifnumgreater{\thefield{#1year}}{#2}}
              or (test {\ifnumequal{\thefield{#1year}}{#2}}
                  and (test {\ifnumgreater{\thefield{#1month}}{#3}}
                       or (test {\ifnumequal{\thefield{#1month}}{#3}}
                           and not test {\ifnumless{\thefield{#1day}}{#4}})))}}

\defbibcheck{thisyear}{%
  \iffieldint{year}
    {\ifdateonorafter{2017}{5}{1}      % date >= 2017-05-01?
       {\ifdateonorafter{2018}{5}{1}   % date >= 2018-05-01
          {\skipentry}                 % too new for us (date >= 2018-05-01)
          {}}                          % just right (2017-05-01 <= date < 2018-05-01)
       {\skipentry}}                   % too old (date <2017-05-01)
    {\skipentry}}

\usepackage{filecontents}
\begin{filecontents}{\jobname.bib}
@article{greenwade93,
  author  = "A Guy",
  title   = "A document",
  date    = "2018-05-01",
  journal = "Journal of Post-Modern Mysticisms",
  volume  = "14",
  number  = "3",
  pages   = "342--351"
}

@book{abook,
  author    = "An Other Auther",
  title     = "Something Really Important",
  date      = "2017-06-01",
  publisher = "Addison-Wesley",
  address   = "Somewhere Town"
}
\end{filecontents}

\addbibresource{\jobname.bib}
\begin{document}
Test
\nocite{*}
\printbibliography[check=thisyear]
\end{document}

enter image description here

  • Shouldn't this be testing the "date" field, not the "year" field? – spindoctor Apr 13 '18 at 13:35
  • @spindoctor Nope. Internally for biblatex there is no date field. All date fields are decomposed into their date parts: year, month, day, .... Only the latter are available to the programming layer of biblatex. date is only the input field. – moewe Apr 13 '18 at 13:38
  • OK, and I see you've defined two new commands here ifdateonorafter and ifdateafter, but in the bibcheck, you only use the ifdateonorafter`. Is this an oversight? Should I be using both? – spindoctor Apr 13 '18 at 14:10
  • @spindoctor I first defined \ifdateafter, then I defined and used \ifdateonorafter because it was more natural for your particular question. Because both are useful I kept both of them. In the answer we defined $<$ and $\leq$ and with that we can define $=$ as $\leq \setminus <$. On second thoughts I expected $\leq$ to be the most useful command, so I did not want to define it in terms of the other two as $< \cup =$ to save a few macro calls. – moewe Apr 13 '18 at 14:24
  • One last question: Does it matter if the bibtex entries are wrapped in curly braces {} or "" ? All my entries are in {}. – spindoctor Apr 13 '18 at 14:53
0

An alternative method would be to use a regex on the date in a sourcemap to add a keyword to the entries of interest (That's an adaptation to your requirements of jon's answer in the link provided by moewe in the comments, that is: https://tex.stackexchange.com/a/346299/105447).

For your case, as your interval stretches from the first day of a month to the last day of another, we only need to control for the months. But the technique is extensible for the case in which the day is actually needed or to the case in which the date might not always be specified in full.

\documentclass{article}
\usepackage{biblatex}

\usepackage{filecontents}
\begin{filecontents}{\jobname.bib}
  @article{greenwade93,
    author  = "A Guy",
    title   = "A document",
    date    = "2016-01-05",
    journal = "Journal of Post-Modern Mysticisms",
    volume  = "14",
    number  = "3",
    pages   = "342--351"
  }

  @book{abook,
    author    = "An Other Auther",
    title     = "Something Really Important",
    date      = "2017-06-01",
    publisher = "Addison-Wesley",
    address   = "Somewhere Town"
  }
\end{filecontents}

\DeclareSourcemap{
  \maps[datatype=bibtex]{
    \map[overwrite]{
      \step[fieldsource=date,  match=\regexp{^(2017-(0[5-9]|1[1-2])|2018-0[1-4])}, final]
      \step[fieldset=keywords, fieldvalue={,daterange}, append]
      \step[fieldsource=keywords, match=\regexp{\A,}, replace={}]
    }
  }
}

\addbibresource{\jobname.bib}

\begin{document}
\nocite{*}
\printbibliography[keyword=daterange]
\end{document}

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.