
Eu fiz um comando parecido com 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
Ele exibe a duração de uma data a outra de forma sucinta. Veja a imagem abaixo.
No entanto, preciso manipular a data de término aumentando-a em alguns dias. Algo como \dateRange{2016}{12}{31}{2016}{12}{31 + 1}
não funciona. Encontrei o seguinte 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}
}
O que pode adicionar dias a um arquivo DTMdate
. Meu problema é fazer essas duas funções funcionarem juntas.
- Reescreva
dateRange
para que ele insira doisDTMdates
em vez dos números simples. - Extraia oano,mêsedatade
newDeadLineDate
e insira-o novamente emdateRange
Então, preciso de ajuda é primeiro ter duas datas, incrementar uma delas e exibir o intervalo de datas usando \dateRange
a função. Qualquer ajuda com 1. ou 2. da lista acima será muito 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}
Responder1
Extraindo o ano, mês e dia de uma datetime2
data nomeada
Como você provavelmente notou em seu exemplo de código onde os comandos \DTMsavedate
e \DTMsavejulianday
são usados, o datetime2
pacote pode salvar datas em armazenamentos especiais identificados por um 〈nome〉. Seção de citaçõesArmazenando e usando datas e horasdo datetime2
manual:
Nos comandos abaixo, o 〈nome〉 (sem caracteres ativos) é um nome que identifica exclusivamente a informação.
Quando você tem uma data em tal armazenamento, como é o caso após a execução , \DTMsavejulianday{〈name〉}{〈number〉}
você pode extrair o ano, mês e dia correspondentes usando os comandos \DTMfetchyear
e . Cada um desses comandos recebe um argumento 〈nome〉 e se expande para o número correspondente. Ou seja, expande para o ano, para o mês e para o dia. O resto é essencialmente trabalho de encanamento. :-)\DTMfetchmonth
\DTMfetchday
\DTMfetchyear{〈name〉}
\DTMfetchmonth{〈name〉}
\DTMfetchday{〈name〉}
Conectando as diferentes partes
Proponho um \dateRange
comando que se comporte como o seu, exceto que:
aceita um argumento opcional (padrão 0) que especifica o número de dias que você deseja adicionar à data final antes de exibir o intervalo resultante;
utiliza um espaço no-break entre o ordinal do dia e o nome do mês (
~
é um espaço normal em\ExplSyntaxOn
regime, mas acredito que você queria um espaço no-break);ele usa comparações de números inteiros, de modo que
01
é considerado igual a1
,02
igual a2
, etc. para todos os argumentos de dia, mês e ano (se você não quiser isso, use\str_if_eq:nnTF
como na primeira revisão desta resposta, mas eu não ' não vejo nenhuma boa razão para fazê-lo).
Reindentei a função e usei \int_compare:nNnTF
em vez de \str_case:nnF
para facilitar a leitura do código e abordar o terceiro ponto acima.
Também defini uma função em nível de código \nebuch_display_date_range:nnnnnn
para conter esse código retrabalhado, pois dessa forma é muito mais fácil reutilizá-lo em diferentes situações. Isso nos permite gerar uma variante \nebuch_display_date_range:nnnxxx
que expande totalmente os três últimos argumentos antes de passá-los para a função base \nebuch_display_date_range:nnnnnn
(expansão completa como feita por \edef
). Isso requer apenas uma simples linha de código:
\cs_generate_variant:Nn \nebuch_display_date_range:nnnnnn { nnnxxx }
Usando a variante, é fácil passar o resultado do cálculo da data temporária (que adiciona o deslocamento) para a função base \nebuch_display_date_range:nnnnnn
, porque \DTMfetchday
, \DTMfetchmonth
e \DTMfetchyear
são todas funções expansíveis (veja a documentação de datetime2
).
O cálculo da data de deslocamento também é implementado em uma função em nível de código, ou seja \nebuch_compute_offset_date:nnnnn
, para torná-la facilmente reutilizável por outro código (e é usada na minha implementação 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}