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。私の問題は、これら 2 つの関数を連携させることです。

  1. 単純な数字ではなくdateRange2 を入力するように書き直してください。DTMdates
  2. 抽出するそして日付から取り出してnewDeadLineDate、再び挿入するdateRange

私が助けを求めているのは、まず日付を 2 つ用意し、そのうちの 1 つを増分し、関数を使用して日付範囲を表示することです\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:

以下のコマンドでは、<name> (アクティブな文字なし) は情報を一意に識別する名前です。

を実行した後のように、そのようなストアに日付がある場合\DTMsavejulianday{〈name〉}{〈number〉}、コマンド\DTMfetchyear、および を使用して対応する年、月、日を抽出できます。これらの各コマンドは、<name> 引数を受け取り、対応する数値に展開します。言い換えると、 は年、月、日に\DTMfetchmonth展開されます。残りは基本的に配管作業です。 :-)\DTMfetchday\DTMfetchyear{〈name〉}\DTMfetchmonth{〈name〉}\DTMfetchday{〈name〉}

さまざまなパーツを接続する

私は\dateRange、次の点を除いて、あなたのコマンドと同じように動作するコマンドを提案します:

  • 結果の範囲を表示する前に終了日に追加する日数を指定するオプションの引数 (デフォルトは 0) を受け入れます。

  • 日付序数と月名の間には改行なしのスペースを使用します (これは体制~下では通常のスペースです\ExplSyntaxOnが、改行なしのスペースが欲しかったのだと思います)。

  • 整数比較を使用するため、すべての日、月、年の引数について01、 は と同じ102は と同じ2、などと見なされます (これを望まない場合は、\str_if_eq:nnTFこの回答の最初の修正のように を使用してください。ただし、そうする正当な理由は見当たりません)。

コードを読みやすくし、上記の 3 番目のポイントに対処するために、関数を再インデントし、\int_compare:nNnTFの代わりにを使用しました。\str_case:nnF

\nebuch_display_date_range:nnnnnnまた、この再加工されたコードを格納するコード レベルの関数も定義しました。この方法では、さまざまな状況で再利用するのがはるかに簡単だからです。これにより\nebuch_display_date_range:nnnxxx、最後の 3 つの引数を完全に展開してから基本関数に渡すバリアントを生成できます\nebuch_display_date_range:nnnnnn( によって行われる完全な展開\edef)。これには、次の簡単なコード行だけが必要です。

\cs_generate_variant:Nn \nebuch_display_date_range:nnnnnn { nnnxxx }

バリアントを使用すると、、、およびはすべて拡張可能な関数であるため (のドキュメントを参照)、一時的な日付計算 (オフセットを追加) の結果を基本関数 に渡すことが簡単に\nebuch_display_date_range:nnnnnnなります。\DTMfetchday\DTMfetchmonth\DTMfetchyeardatetime2

オフセット日付の計算もコードレベルの関数、つまり に実装されており\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}

スクリーンショット

関連情報