
He creado un comando que se parece a este:
\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
Muestra la duración de una fecha a la siguiente de forma sucinta. Vea la imagen a continuación.
Sin embargo, necesito manipular la fecha de finalización incrementándola unos días. Algo como \dateRange{2016}{12}{31}{2016}{12}{31 + 1}
no funciona. encontré el siguiente código
%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}
}
Lo que puede agregar días a un DTMdate
. Mi problema es hacer que estas dos funciones funcionen juntas.
- Vuelva a escribir
dateRange
para que ingrese dosDTMdates
en lugar de los números simples. - Extraer elaño,mesyfechadesde
newDeadLineDate
e insértelo nuevamente endateRange
Entonces, necesito ayuda para tener primero dos fechas, incrementar una de ellas y mostrar el rango de fechas usando \dateRange
la función. Cualquier ayuda con 1. o 2. de la lista anterior será muy apreciada.
\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}
Respuesta1
Extraer el año, mes y día de una datetime2
fecha determinada
Como probablemente haya notado en su ejemplo de código donde se usan los comandos \DTMsavedate
y , el paquete puede guardar fechas en almacenes especiales identificados por un 〈nombre〉. sección de cotizaciones\DTMsavejulianday
datetime2
Almacenamiento y uso de fechas y horasdel datetime2
manual:
En los comandos siguientes, el 〈nombre〉 (sin caracteres activos) es un nombre que identifica de forma única la información.
Cuando tienes una fecha en dicha tienda, como es el caso después de ejecutar , \DTMsavejulianday{〈name〉}{〈number〉}
puedes extraer el año, mes y día correspondiente usando los comandos \DTMfetchyear
y . Cada uno de estos comandos toma un argumento 〈nombre〉 y se expande al número correspondiente. Es decir, se expande al año, al mes y al día. El resto es básicamente trabajo de fontanería. :-)\DTMfetchmonth
\DTMfetchday
\DTMfetchyear{〈name〉}
\DTMfetchmonth{〈name〉}
\DTMfetchday{〈name〉}
Conectando las diferentes partes
Propongo un \dateRange
comando que se comporta como el tuyo, excepto que:
acepta un argumento opcional (por defecto 0) que especifica el número de días que desea agregar a la fecha de finalización antes de mostrar el rango resultante;
utiliza un espacio sin interrupciones entre el ordinal del día y el nombre del mes (
~
es un espacio normal bajo\ExplSyntaxOn
régimen, pero creo que querías un espacio sin interrupciones);utiliza comparaciones de números enteros, por lo que
01
se considera igual que1
,02
igual que2
, etc. para todos los argumentos de día, mes y año (si no desea eso, use\str_if_eq:nnTF
as en la primera revisión de esta respuesta, pero yo no No veo ninguna buena razón para hacerlo).
Volví a sangrar la función y la usé \int_compare:nNnTF
en lugar de \str_case:nnF
para hacer que el código sea más fácil de leer y abordar el tercer punto anterior.
También definí una función a nivel de código \nebuch_display_date_range:nnnnnn
para contener este código reelaborado, porque de esta manera es mucho más fácil reutilizarlo en diferentes situaciones. Esto nos permite generar una variante \nebuch_display_date_range:nnnxxx
que expande completamente los tres últimos argumentos antes de pasarlos a la función base \nebuch_display_date_range:nnnnnn
(expansión completa como lo hace \edef
). Esto sólo requiere una simple línea de código:
\cs_generate_variant:Nn \nebuch_display_date_range:nnnnnn { nnnxxx }
Usando la variante, es fácil pasar el resultado del cálculo de la fecha temporal (que agrega el desplazamiento) a la función base \nebuch_display_date_range:nnnnnn
, porque \DTMfetchday
y \DTMfetchmonth
son \DTMfetchyear
todas funciones expandibles (consulte la documentación de datetime2
).
El cálculo de la fecha de compensación también se implementa en una función a nivel de código, es decir \nebuch_compute_offset_date:nnnnn
, para que otro código pueda reutilizarla fácilmente (y se usa en mi implementación de \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}