
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.
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.
- Schreiben Sie es
dateRange
so um, dass zweiDTMdates
statt der einfachen Zahlen eingegeben werden. - Extrahieren Sie dieJahr,MonatUndDatumaus
newDeadLineDate
und 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 \dateRange
Funktion 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 datetime2
Datum
Wie Sie wahrscheinlich in Ihrem Codebeispiel bemerkt haben, in dem die Befehle \DTMsavedate
und \DTMsavejulianday
verwendet werden, datetime2
kann das Paket Daten in speziellen Speichern speichern, die durch einen 〈Namen〉 identifiziert werden. ZitatabschnittSpeichern und Verwenden von Datums- und Zeitangabendes datetime2
Handbuchs:
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
, \DTMfetchmonth
und 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 \dateRange
Befehl 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.
01
betrachtet wird (wenn Sie dies nicht möchten, verwenden Sie „as“ in der ersten Überarbeitung dieser Antwort, aber ich sehe keinen guten Grund dafür).1
02
2
\str_if_eq:nnTF
Ich habe die Funktion neu eingerückt und \int_compare:nNnTF
anstelle 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:nnnnnn
die 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:nnnxxx
die 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 \DTMfetchday
und \DTMfetchmonth
alle \DTMfetchyear
erweiterbare 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}