如何在 latex 中实现 \tomorrow

如何在 latex 中实现 \tomorrow

有人问我如何\tomorrow在 TeX/LaTeX 中实现宏。虽然我可以想出一个相当好的解决方案,适用于一个文档类,但我不知道如何以与文档类无关的方式实现它。

我发现日期但是,即使日期算术可能有用,它也会假定日期的特定格式(这对于我所居住的地区来说也是错误的)。

有人有合理的便携解决方案吗?这可能吗?

答案1

这是 LaTeX3 中的原型;有关明天的数据可在整数变量中找到

\l_tomorrow_day_int
\l_tomorrow_month_int
\l_tomorrow_year_int

代码如下;最后的宏仅仅是数据如何使用的一个例子,可能与有关datetime

\documentclass{article}

\ExplSyntaxOn
\prop_new:N \g_tomorrow_months_prop
\bool_new:N \l_tomorrow_leap_bool
\tl_new:N \l_tomorrow_daysinmonth_tl
\int_new:N \l_tomorrow_day_int
\int_new:N \l_tomorrow_month_int
\int_new:N \l_tomorrow_year_int

\prop_gput:Nnn \g_tomorrow_months_prop {  1 } { 31 }
\prop_gput:Nnn \g_tomorrow_months_prop {  2 } { \bool_if:NTF \l_tomorrow_leap_bool { 29 } { 28 } }
\prop_gput:Nnn \g_tomorrow_months_prop {  3 } { 31 }
\prop_gput:Nnn \g_tomorrow_months_prop {  4 } { 30 }
\prop_gput:Nnn \g_tomorrow_months_prop {  5 } { 31 }
\prop_gput:Nnn \g_tomorrow_months_prop {  6 } { 30 }
\prop_gput:Nnn \g_tomorrow_months_prop {  7 } { 31 }
\prop_gput:Nnn \g_tomorrow_months_prop {  8 } { 31 }
\prop_gput:Nnn \g_tomorrow_months_prop {  9 } { 30 }
\prop_gput:Nnn \g_tomorrow_months_prop { 10 } { 31 }
\prop_gput:Nnn \g_tomorrow_months_prop { 11 } { 30 }
\prop_gput:Nnn \g_tomorrow_months_prop { 12 } { 31 }

\cs_new_protected:Npn \tomorrow_check_leap:n #1
 {
  \int_compare:nTF { 0 = \int_mod:nn { #1 } { 4 } }
   {% possibly a leap year
    \int_compare:nTF { 0 = \int_mod:nn { #1 } { 100 } }
     {% possibly not a leap year
      \int_compare:nTF { 0 = \int_mod:nn { #1/100 } { 4 } }
       {% leap year
        \bool_set_true:N \l_tomorrow_leap_bool
       }
       {% not leap year
        \bool_set_false:N \l_tomorrow_leap_bool
       }
     }
     {% leap year
      \bool_set_true:N \l_tomorrow_leap_bool
     }
   }
   {% not leap year
    \bool_set_false:N \l_tomorrow_leap_bool
   }
 }

\cs_new_protected:Npn \tomorrow_set_tomorrow:nnn #1 #2 #3
 {
  \int_compare:nT { #2 = 2 } { \tomorrow_check_leap:n { #3 } }
  \int_set:Nn \l_tomorrow_day_int { #1 }
  \int_set:Nn \l_tomorrow_month_int { #2 }
  \int_set:Nn \l_tomorrow_year_int { #3 }
  \__tomorrow_incr_day:
 }
\cs_new_protected:Npn \__tomorrow_incr_day:
 {
  \int_incr:N \l_tomorrow_day_int
  \prop_get:NVN \g_tomorrow_months_prop \l_tomorrow_month_int \l_tomorrow_daysinmonth_tl
  \int_compare:nT
   { \l_tomorrow_day_int > \tl_use:N \l_tomorrow_daysinmonth_tl }
   {
    \int_set:Nn \l_tomorrow_day_int { 1 }
    \__tomorrow_incr_month:
   }
 }
\cs_new_protected:Npn \__tomorrow_incr_month:
 {
  \int_incr:N \l_tomorrow_month_int
  \int_compare:nT { \l_tomorrow_month_int > 12 }
   {
    \int_set:Nn \l_tomorrow_month_int { 1 }
    \int_incr:N \l_tomorrow_year_int
   }
 }
\cs_generate_variant:Nn \prop_get:Nn { NV,Ne }

\NewDocumentCommand{\printtomorrowof}{mmm}
 {
  \tomorrow_set_tomorrow:nnn { #1 } { #2 } { #3 }
  Today~it~is~
  \int_to_arabic:n { #3 }/
  \int_to_arabic:n { #2 }/
  \int_to_arabic:n { #1 },~
  tomorrow~it~is~
  \int_to_arabic:n { \l_tomorrow_year_int }/
  \int_to_arabic:n { \l_tomorrow_month_int }/
  \int_to_arabic:n { \l_tomorrow_day_int }
  \par
 }
\ExplSyntaxOff

\begin{document}

\printtomorrowof{\day}{\month}{\year}
\printtomorrowof{30}{10}{2012}
\printtomorrowof{31}{10}{2012}
\printtomorrowof{31}{12}{2012}
\printtomorrowof{28}{2}{2012}
\printtomorrowof{28}{2}{2013}
\printtomorrowof{28}{2}{1900}
\printtomorrowof{28}{2}{2000}

\end{document}

如您所见,闰年被正确识别。当然,仅限公历。

为了定义合适的\tomorrow命令,您可以添加(之前\ExplSyntaxOn)一个babel版本

\NewDocumentCommand{\tomorrow}{}
 {
  \tomorrow_set_tomorrow:nnn { \day } { \month } { \year }
  \group_begin:
  \day = \l_tomorrow_day_int
  \month = \l_tomorrow_month_int
  \year = \l_tomorrow_year_int
  \today
  \group_end:
 }

或者一个datetime版本(datetime当然需要包)

\NewDocumentCommand{\tomorrow}{}
 {
  \tomorrow_set_tomorrow:nnn { \day } { \month } { \year }
  \formatdate { \l_tomorrow_day_int }
              { \l_tomorrow_month_int }
              { \l_tomorrow_year_int }
 }

在此处输入图片描述


当然,如果只想要明天的日期,这样做就有点过了。宏实际上允许根据给定的日期计算任何日期,给定间隔(正或负)。也可以将儒略日期的“反转”扩展为“日/月/年”形式,但这样会非常慢的。

\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\DeclareExpandableDocumentCommand{\juliandate}{ m m m }
 {
  \juliandate_calc:nnnn { #1 } { #2 } { #3 } { \use:n }
 }
\NewDocumentCommand{\storejuliandate}{ s m m m m }
 {
  \IfBooleanTF{#1}
   {
    \juliandate_calc:nnnn { #3 } { #4 } { #5 } { \cs_set:Npx #2 }
   }
   {
    \juliandate_calc:nnnn { #3 } { #4 } { #5 } { \cs_new:Npx #2 }
   }
 }
\cs_new:Npn \juliandate_calc:nnnn #1 #2 #3 #4 % #1 = day, #2 = month, #3 = year, #4 = what to do
 {
  #4 
   {
    \int_eval:n
     {
      #1 +
      \int_div_truncate:nn { 153 * (#2 + 12 * \int_div_truncate:nn { 14 - #2 } { 12 } - 3) + 2 } { 5 } +
      365 * (#3 + 4800 - \int_div_truncate:nn { 14 - #2 } { 12 } ) +
      \int_div_truncate:nn { #3 + 4800 - \int_div_truncate:nn { 14 - #2 } { 12 } } { 4 } -
      \int_div_truncate:nn { #3 + 4800 - \int_div_truncate:nn { 14 - #2 } { 12 } } { 100 } + 
      \int_div_truncate:nn { #3 + 4800 - \int_div_truncate:nn { 14 - #2 } { 12 } } { 400 } -
      32045
     }
   }
 }

\tl_new:N \l__juliandate_g_tl
\tl_new:N \l__juliandate_dg_tl
\tl_new:N \l__juliandate_c_tl
\tl_new:N \l__juliandate_dc_tl
\tl_new:N \l__juliandate_b_tl
\tl_new:N \l__juliandate_db_tl
\tl_new:N \l__juliandate_a_tl
\tl_new:N \l__juliandate_da_tl
\tl_new:N \l__juliandate_y_tl
\tl_new:N \l__juliandate_m_tl
\tl_new:N \l__juliandate_d_tl
\int_new:N \l_juliandate_day_int
\int_new:N \l_juliandate_month_int
\int_new:N \l_juliandate_year_int

\cs_new:Npn \__juliandate_set:nn #1 #2
 {
  \tl_set:cx { l__juliandate_#1_tl } { \int_eval:n { #2 } }
 }
\cs_new:Npn \__juliandate_use:n #1
 {
  \tl_use:c { l__juliandate_#1_tl }
 }
\cs_new_protected:Npn \juliandate_reverse:n #1
 {
  \__juliandate_set:nn { g }
   { \int_div_truncate:nn { #1 + 32044 } { 146097 } }
  \__juliandate_set:nn { dg }
   { \int_mod:nn { #1 + 32044 } { 146097 } }
  \__juliandate_set:nn { c }
   { \int_div_truncate:nn { ( \int_div_truncate:nn { \__juliandate_use:n { dg } } { 36524 } + 1) * 3 } { 4 } }
  \__juliandate_set:nn { dc }
   { \__juliandate_use:n { dg } - \__juliandate_use:n { c } * 36524 }
  \__juliandate_set:nn { b }
   { \int_div_truncate:nn { \__juliandate_use:n { dc } } { 1461 } }
  \__juliandate_set:nn { db }
   { \int_mod:nn { \__juliandate_use:n { dc } } { 1461 } }
  \__juliandate_set:nn { a }
   { \int_div_truncate:nn { ( \int_div_truncate:nn { \__juliandate_use:n { db } } { 365 } + 1) * 3 } { 4 } }
  \__juliandate_set:nn { da }
   { \__juliandate_use:n { db } - \__juliandate_use:n { a } * 365 }
  \__juliandate_set:nn { y }
   {
     \__juliandate_use:n { g } * 400 + 
     \__juliandate_use:n { c } * 100 + 
     \__juliandate_use:n { b } * 4 + 
     \__juliandate_use:n { a }
    }
  \__juliandate_set:nn { m }
   { \int_div_truncate:nn { \__juliandate_use:n { da } * 5 + 308 } { 153 } - 2 }
  \__juliandate_set:nn { d }
   { \__juliandate_use:n { da } - \int_div_truncate:nn { (\__juliandate_use:n { m } + 4) * 153 } { 5 } + 122 }
  \int_set:Nn \l_juliandate_year_int
   { \__juliandate_use:n { y } - 4800 + \int_div_truncate:nn { \__juliandate_use:n { m } + 2 } { 12 } }
  \int_set:Nn \l_juliandate_month_int
   { \int_mod:nn { \__juliandate_use:n { m } + 2 } { 12 } + 1 }
  \int_set:Nn \l_juliandate_day_int
   { \__juliandate_use:n { d } + 1 }
 }
\cs_generate_variant:Nn \juliandate_reverse:n { x }

\NewDocumentCommand{\showday}{ m }
 {
  \juliandate_reverse:n { #1 }
  \int_to_arabic:n { \l_juliandate_day_int }-
  \int_to_arabic:n { \l_juliandate_month_int }-
  \int_to_arabic:n { \l_juliandate_year_int }
 }

\NewDocumentCommand{\tomorrow}{ }
 {
  \group_begin:
  \juliandate_reverse:x { \juliandate_calc:nnnn { \day + 1 } { \month } { \year } { \use:n } }
  \day = \l_juliandate_day_int
  \month = \l_juliandate_month_int
  \year = \l_juliandate_year_int
  \today
  \group_end:
 }
\NewDocumentCommand{\tomorrowof}{ m m m }
 {
  \group_begin:
  \juliandate_reverse:x { \juliandate_calc:nnnn { #1 + 1 } { #2 } { #3 } { \use:n } }
  \day = \l_juliandate_day_int
  \month = \l_juliandate_month_int
  \year = \l_juliandate_year_int
  \today
  \group_end:
 }
\ExplSyntaxOff
\begin{document}
\juliandate{18}{12}{2012}

\storejuliandate*{\x}{18}{12}{2012}\x

\storejuliandate*{\x}{1}{1}{1900}\x

\showday{2456280}

\showday{2415021}

\tomorrow

\tomorrowof{31}{12}{2012}

\tomorrowof{28}{2}{2012}

\tomorrowof{29}{2}{2012}

\tomorrowof{28}{2}{2013}

\tomorrowof{28}{2}{1900}

\end{document}

答案2

只需快速烹饪

\documentclass{article}
\usepackage{pgfkeys,pgfcalendar}

\newcount\pgfdatecount
\newcommand{\tomorrow}{%
\pgfcalendardatetojulian{\year-\month-\day+1}{\pgfdatecount}
\pgfcalendarjuliantodate{\the\pgfdatecount}{\myyear}{\mymonth}{\myday}
\pgfcalendarmonthname{\mymonth}\space\myday,\space\myyear%
}

\begin{document}

\today~ is the day before tomorrow.\par
\tomorrow~ is the day after today.

\end{document}

在此处输入图片描述

还可以添加星期名称等。您可以查看手册。据我所知,这与班级无关,但月份名称是固定的。如果您愿意,也可以引入它们,但 ISO 日期就是因为这个而变得混乱。

答案3

我建议使用datenumber包。

序言

\usepackage{datenumber}
\setdatetoday
\addtocounter{datenumber}{1}%
\setdatebynumber{\thedatenumber}%

在文档中

今天是\today
明天是\datedate

答案4

这个问题已经有一段时间了,但我还没有看到一个简单的 TeX 解决方案。希望它对某些人有用。

\let\mydatesep=-
\newcount\advancedday
\newcount\daysinthismonth
\newcount\tempyear
\newcount\ttempyear
\def\advancedatebydays#1{%
\advancedday=\number\day%
\advance\advancedday by #1%
\tempyear=\number\year%
\ttempyear=\tempyear%
\loop%
\loop%
\ifnum\ttempyear>4 %
  \advance\ttempyear by-4 %
\repeat%
\ifnum\month=2 %
  \ifnum\ttempyear=4 %
    \daysinthismonth=29 %
  \else%
    \daysinthismonth=28 %
  \fi%
\else%
  \ifodd\month%
    \ifnum\month<8 %
      \daysinthismonth=30 %
    \else%
      \daysinthismonth=31 %
    \fi%
  \else%
    \ifnum\number\month>7 %
      \daysinthismonth=31 %
    \else%
      \daysinthismonth=30 %
    \fi%
  \fi%
\fi%
\ifnum\advancedday>\daysinthismonth%
  \ifnum\month=12 %
    \advance \tempyear by 1 %
    \advance \ttempyear by 1 %
    \advance \advancedday by -\daysinthismonth%
    \advance \month by -11 %
  \else%
    \advance \advancedday by -\daysinthismonth%
    \advance \month by 1 %
  \fi%
\repeat%
\number\advancedday\mydatesep\number\month\mydatesep\number\tempyear%
}%

\advancedatebydays{302}
\bye

相关内容