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}
 }

這可以增加天數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\DTMsavejulianday的程式碼範例中註意到的那樣,該datetime2套件可以將日期保存在由 <name> 標識的特殊儲存中。報價部分儲存和使用日期和時間手冊的datetime2

在下面的命令中,<名稱>(無活動字元)是唯一識別資訊的名稱。

當您在這樣的儲存中擁有日期時,就像執行後的情況一樣\DTMsavejulianday{〈name〉}{〈number〉},您可以使用命令\DTMfetchyear\DTMfetchmonth和提取相應的年、月和日\DTMfetchday。這些命令中的每一個都接受一個 <name> 參數並擴展為相應的數字。換句話說,\DTMfetchyear{〈name〉}擴展到年、\DTMfetchmonth{〈name〉}月和\DTMfetchday{〈name〉}日。剩下的基本上就是管道工作。 :-)

連接不同部分

我提出了一個\dateRange與您的命令類似的命令,除了:

  • 它接受一個可選參數(預設為 0),指定在顯示結果範圍之前要新增到結束日期的天數;

  • 它在日序數和月份名稱之間使用不間斷空格(~這是製度下的正常空格\ExplSyntaxOn,但我相信您想要一個不間斷空格);

  • 它使用整數比較,因此對於所有日、月和年參數,這01被認為與102等相同2(如果您不希望這樣,請使用\str_if_eq:nnTF此答案的第一個修訂版中的 as ,但我不這樣做我看不出有什麼好的理由這樣做)。

我重新縮進了該函數並使用了\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}

螢幕截圖

相關內容