Extrahieren von Jahr, Monat und Tag aus einem benannten datetime2Datum

Extrahieren von Jahr, Monat und Tag aus einem benannten datetime2Datum

Ich habe einen Befehl erstellt, der so aussieht:

\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

Es zeigt die Dauer von einem Datum zum nächsten in prägnanter Form an. Siehe das Bild unten.

Bildbeschreibung hier eingeben

Ich muss jedoch das Enddatum manipulieren, indem ich es um einige Tage erhöhe. So etwas \dateRange{2016}{12}{31}{2016}{12}{31 + 1}funktioniert nicht. Ich habe den folgenden Code gefunden

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

Das kann Tage zu einem hinzufügen DTMdate. Mein Problem besteht darin, diese beiden Funktionen zusammenarbeiten zu lassen.

  1. Schreiben Sie es dateRangeso um, dass zwei DTMdatesstatt der einfachen Zahlen eingegeben werden.
  2. Extrahieren Sie dieJahr,MonatUndDatumaus newDeadLineDateund stecken Sie es wieder indateRange

Ich brauche also Hilfe dabei, zunächst zwei Daten zu haben, eines davon zu erhöhen und den Datumsbereich mithilfe der \dateRangeFunktion anzuzeigen. Für jede Hilfe zu 1. oder 2. aus der obigen Liste bin ich sehr dankbar.

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

Antwort1

Extrahieren von Jahr, Monat und Tag aus einem benannten datetime2Datum

Wie Sie wahrscheinlich in Ihrem Codebeispiel bemerkt haben, in dem die Befehle \DTMsavedateund \DTMsavejuliandayverwendet werden, datetime2kann das Paket Daten in speziellen Speichern speichern, die durch einen 〈Namen〉 identifiziert werden. ZitatabschnittSpeichern und Verwenden von Datums- und Zeitangabendes datetime2Handbuchs:

In den folgenden Befehlen ist der 〈Name〉 (keine aktiven Zeichen) ein Name, der die Informationen eindeutig identifiziert.

Wenn Sie ein Datum in einem solchen Speicher haben, wie es nach der Ausführung der Fall ist \DTMsavejulianday{〈name〉}{〈number〉}, können Sie das entsprechende Jahr, den Monat und den Tag mit den Befehlen \DTMfetchyear, \DTMfetchmonthund extrahieren \DTMfetchday. Jeder dieser Befehle verwendet ein 〈name〉-Argument und wird zur entsprechenden Zahl erweitert. Mit anderen Worten, \DTMfetchyear{〈name〉}wird zum Jahr, \DTMfetchmonth{〈name〉}zum Monat und \DTMfetchday{〈name〉}zum Tag erweitert. Der Rest ist im Wesentlichen Klempnerarbeit. :-)

Verbinden der verschiedenen Teile

Ich schlage einen \dateRangeBefehl vor, der sich wie Ihrer verhält, außer dass:

  • Es akzeptiert ein optionales Argument (Standardwert: 0), das die Anzahl der Tage angibt, die Sie zum Enddatum hinzufügen möchten, bevor der resultierende Bereich angezeigt wird.

  • es wird ein geschütztes Leerzeichen zwischen der Tagesordnungszahl und dem Monatsnamen verwendet ( ~ist unter Regime ein normales Leerzeichen \ExplSyntaxOn, aber ich glaube, Sie wollten ein geschütztes Leerzeichen);

  • es verwendet ganzzahlige Vergleiche, sodass für alle Tages-, Monats- und Jahresargumente das Gleiche wie , das Gleiche wie usw. 01betrachtet wird (wenn Sie dies nicht möchten, verwenden Sie „as“ in der ersten Überarbeitung dieser Antwort, aber ich sehe keinen guten Grund dafür).1022\str_if_eq:nnTF

Ich habe die Funktion neu eingerückt und \int_compare:nNnTFanstelle von verwendet \str_case:nnF, um den Code leichter lesbar zu machen und den dritten Punkt oben zu berücksichtigen.

Ich habe auch eine Funktion auf Codeebene definiert, \nebuch_display_date_range:nnnnnndie diesen überarbeiteten Code enthält, da er auf diese Weise viel einfacher in verschiedenen Situationen wiederverwendet werden kann. Dadurch können wir eine Variante generieren, \nebuch_display_date_range:nnnxxxdie die drei letzten Argumente vollständig expandiert, bevor sie an die Basisfunktion übergeben werden \nebuch_display_date_range:nnnnnn(vollständige Expansion wie von durchgeführt \edef). Dazu ist nur eine einfache Codezeile erforderlich:

\cs_generate_variant:Nn \nebuch_display_date_range:nnnnnn { nnnxxx }

Mit der Variante ist es einfach, das Ergebnis der temporären Datumsberechnung (die den Offset hinzufügt) an die Basisfunktion zu übergeben \nebuch_display_date_range:nnnnnn, da \DTMfetchdayund \DTMfetchmonthalle \DTMfetchyearerweiterbare Funktionen sind (siehe die Dokumentation von datetime2).

Die Berechnung des Offset-Datums wird ebenfalls in einer Funktion auf Codeebene implementiert, nämlich \nebuch_compute_offset_date:nnnnn, um sie für anderen Code leicht wiederverwendbar zu machen (und sie wird in meiner Implementierung von verwendet\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}

Bildschirmfoto

verwandte Informationen