datetime2从指定日期中提取年、月、日

datetime2从指定日期中提取年、月、日

我制作了一个如下命令:

\newcommand*{\numdash}{\,--\,}

\ExplSyntaxOn
\NewDocumentCommand{\dateRange}{mmmmmm}
    {
        \str_case:nnF { #1 }
        {
        {#4}  { 
            \str_case:nnF { #2 }
            {
            {#5}  { 
                \str_case:nnF { #3 }
                {
                {#6}  { \DTMdisplaydate{#4}{#5}{#6}{-1} }%
                }{\DTMordinal{#3}{}{}\numdash{}\DTMdisplaydate{#4}{#5}{#6}{-1}}
            }
            }{\DTMordinal{#3}~\DTMmonthname{#2}%
            {}\numdash{}\DTMdisplaydate{#4}{#5}{#6}{-1}}
        }
        }{\DTMdisplaydate{#1}{#2}{#3}{-1}{}\numdash{}\DTMdisplaydate{#4}{#5}{#6}{-1}}
    }
\ExplSyntaxOff

它以简洁的方式显示从一个日期到下一个日期的持续时间。参见下图。

在此处输入图片描述

但是,我需要通过将结束日期增加几天来操纵它。类似的东西\dateRange{2016}{12}{31}{2016}{12}{31 + 1}不起作用。我发现以下代码

%https://tex.stackexchange.com/questions/318006/add-n-days-to-variable-date
\DTMsavedate{DeadLineDate}{2016-05-20}
\newcommand{\DeadLineDateExtend}{1}

\newcount\daycount
\newcommand{\dueDate}[1]{%
    \DTMsaveddateoffsettojulianday{DeadLineDate}{#1}\daycount
    \DTMsavejulianday{newDeadLineDate}{\number\daycount}
    \DTMusedate{newDeadLineDate}
 }

它可以向 a 添加天数DTMdate。我的问题是让这两个函数一起工作。

  1. 重写dateRange以便输入两个DTMdates而不是简单的数字。
  2. 提取日期并将newDeadLineDate其重新插入dateRange

因此我需要的帮助是首先有两个日期,增加其中一个日期并使用\dateRange函数显示日期范围。如能对上述列表中的 1. 或 2. 提供帮助,我将不胜感激。

\documentclass{article}

\usepackage[english]{babel}
\usepackage[en-GB,calc]{datetime2}

\usepackage{xparse}

% https://tex.stackexchange.com/questions/390693/datetime-ranges-using-datetime2/390738
\newcommand*{\numdash}{\,--\,}

\ExplSyntaxOn
\NewDocumentCommand{\dateRange}{mmmmmm}
    {
        \str_case:nnF { #1 }
        {
        {#4}  { 
            \str_case:nnF { #2 }
            {
            {#5}  { 
                \str_case:nnF { #3 }
                {
                {#6}  { \DTMdisplaydate{#4}{#5}{#6}{-1} }%
                }{\DTMordinal{#3}{}{}\numdash{}\DTMdisplaydate{#4}{#5}{#6}{-1}}
            }
            }{\DTMordinal{#3}~\DTMmonthname{#2}%
            {}\numdash{}\DTMdisplaydate{#4}{#5}{#6}{-1}}
        }
        }{\DTMdisplaydate{#1}{#2}{#3}{-1}{}\numdash{}\DTMdisplaydate{#4}{#5}{#6}{-1}}
    }
\ExplSyntaxOff

%https://tex.stackexchange.com/questions/318006/add-n-days-to-variable-date
\DTMsavedate{DeadLineDate}{2016-05-20}
\newcommand{\DeadLineDateExtend}{1}

\newcount\daycount
\newcommand{\dueDate}[1]{%
    \DTMsaveddateoffsettojulianday{DeadLineDate}{#1}\daycount
    \DTMsavejulianday{newDeadLineDate}{\number\daycount}
    \DTMusedate{newDeadLineDate}
 }

\begin{document}

\dateRange{2016}{12}{31}{2016}{12}{31}

\dateRange{2016}{12}{30}{2016}{12}{31}

\dateRange{2016}{11}{31}{2016}{12}{31}

\dateRange{2015}{12}{31}{2016}{12}{31}

\end{document}

答案1

datetime2从指定日期中提取年、月、日

您可能注意到,在代码示例中使用了命令\DTMsavedate和,该包可以将日期保存在由 〈name〉 标识的特殊存储中。引用部分\DTMsavejuliandaydatetime2存储和使用日期和时间手册内容datetime2

在下面的命令中,〈name〉(没有活动字符)是唯一标识信息的名称。

当您在这样的存储中有一个日期时(如执行 后的情况)\DTMsavejulianday{〈name〉}{〈number〉},您可以使用命令\DTMfetchyear\DTMfetchmonth和提取相应的年份、月份和日期\DTMfetchday。这些命令中的每一个都采用 〈name〉 参数并扩展为相应的数字。换句话说,\DTMfetchyear{〈name〉}扩展到年份、\DTMfetchmonth{〈name〉}月份和\DTMfetchday{〈name〉}日期。其余的基本上是管道工作。 :-)

连接不同部分

我建议一个\dateRange与您的命令行为类似的命令,不同之处在于:

  • 它接受一个可选参数(默认为 0),该参数指定在显示结果范围之前要在结束日期中添加的天数;

  • 它在日期序数和月份名称之间使用不间断空格(在制度~下是正常的空格\ExplSyntaxOn,但我相信你想要一个不间断空格);

  • 它使用整数比较,因此对于所有日、月和年参数01,被认为与 相同102与 相同2,等等(如果您不想要这样,请使用\str_if_eq:nnTF该答案的第一个修订版中的 ,但我看不出这样做有什么好的理由)。

我重新缩进该函数并使用\int_compare:nNnTF\str_case:nnF使代码更易于阅读并解决上面的第三点。

我还定义了一个代码级函数\nebuch_display_date_range:nnnnnn来包含这个重新编写的代码,因为这样在不同情况下重用起来更容易。这使我们能够生成一个变体\nebuch_display_date_range:nnnxxx,在将最后三个参数传递给基函数之前,先将其完全展开\nebuch_display_date_range:nnnnnn(完全展开由 完成\edef)。这只需要一行简单的代码:

\cs_generate_variant:Nn \nebuch_display_date_range:nnnnnn { nnnxxx }

使用变体,很容易将临时日期计算的结果(添加了偏移量)传递给基函数\nebuch_display_date_range:nnnnnn,因为\DTMfetchday\DTMfetchmonth\DTMfetchyear都是可扩展函数(参见的文档datetime2)。

偏移日期的计算也是在代码级函数中实现的,即\nebuch_compute_offset_date:nnnnn,以便其他代码可以轻松地重用它(并且它在我的实现中使用\dateRange)。

\documentclass{article}
\usepackage[english]{babel}
\usepackage[en-GB,calc]{datetime2}
\usepackage{xparse}

\newcommand*{\numdash}{\,--\,}

\ExplSyntaxOn

% Similar to your \dateRange, but we use integer comparisons here and the
% code-level API allows the creation of variants with \cs_generate_variant:Nn.
\cs_new_protected:Npn \nebuch_display_date_range:nnnnnn #1#2#3#4#5#6
  {
    \int_compare:nNnTF {#1} = {#4}
      {
        \int_compare:nNnTF {#2} = {#5}
          {
            \int_compare:nNnTF {#3} = {#6}
              { \DTMdisplaydate {#4} {#5} {#6} {-1} }
              {
                \DTMordinal {#3} {} {} \numdash
                \DTMdisplaydate {#4} {#5} {#6} {-1}
              }
          }
          {
            % I replaced ~ with \nobreakspace here because of \ExplSyntaxOn
            \DTMordinal {#3} \nobreakspace \DTMmonthname {#2} \numdash
            \DTMdisplaydate {#4} {#5} {#6} {-1}
          }
      }
      {
        \DTMdisplaydate {#1} {#2} {#3} {-1} \numdash
        \DTMdisplaydate {#4} {#5} {#6} {-1}
      }
  }

\cs_generate_variant:Nn \nebuch_display_date_range:nnnnnn { nnnxxx }

\newcount \nebuch_tmp_count

% #1, #2, #3: year, month, day
% #4: number of days (offset)
% #5: <name> (in the sense of datetime2) used to store the resulting date
\cs_new_protected:Npn \nebuch_compute_offset_date:nnnnn #1#2#3#4#5
  {
    \DTMsavedate { nebuch_compute_offset_date_tmp_date } { #1-#2-#3 }
    \DTMsaveddateoffsettojulianday
      { nebuch_compute_offset_date_tmp_date } {#4} { \nebuch_tmp_count }
    \DTMsavejulianday {#5} { \number \nebuch_tmp_count }
  }

\NewDocumentCommand { \dateRange } { O{0} m m m m m m }
  {
    \nebuch_compute_offset_date:nnnnn {#5} {#6} {#7} {#1}
                                      { nebuch_dateRange_tmp_date }
    \nebuch_display_date_range:nnnxxx {#2} {#3} {#4}
      { \DTMfetchyear { nebuch_dateRange_tmp_date } }
      { \DTMfetchmonth { nebuch_dateRange_tmp_date } }
      { \DTMfetchday { nebuch_dateRange_tmp_date } }
  }

\ExplSyntaxOff

\begin{document}

\dateRange{2016}{12}{31}{2016}{12}{31}\par
\dateRange{2016}{12}{30}{2016}{12}{31}\par
\dateRange{2016}{11}{31}{2016}{12}{31}\par
\dateRange{2015}{12}{31}{2016}{12}{31}

\bigskip
\dateRange[3]{2016}{12}{31}{2016}{12}{31}\par
\dateRange[3]{2016}{12}{31}{2016}{12}{28}\par
\dateRange[3]{2016}{12}{30}{2016}{12}{31}\par
\dateRange[3]{2016}{12}{30}{2016}{12}{28}\par
\dateRange[31]{2016}{11}{31}{2016}{12}{31}\par
\dateRange[31]{2016}{11}{31}{2016}{11}{30}\par
\dateRange[365]{2015}{12}{31}{2016}{12}{31}\par
\dateRange[365]{2015}{12}{31}{2016}{01}{01}

\bigskip
\dateRange{2016}{02}{7}{2016}{2}{07}

\end{document}

截屏

相关内容