我想确定某个月有多少天。
使用该datenumber
包,我想我可以简单地将日期设置为下一个月,然后向后推一天,即月末,然后提取日期。那当然似乎当我想到这个时很简单,但后来却无法真正提取月份的日期。
那么我需要更换什么
\xdef\LastDayOfMonth{\value{dateday}}
获取该月的天数。
笔记:
- 我并不反对额外的方案,所以任何方案解决方案都可以。
代码:
\documentclass{article}
\usepackage{datenumber}
\usepackage{pgffor}
\newcounter{GivenDateCounter}
\newcommand{\LastDayOfMonth}{XX}%
\newcommand{\NumberOfDaysInMonth}[2]{%
% #1 = YYYY
% #2 = MM
\ifnum#2<12\relax
% Since this is NOT Dec we can just go to the 1st of the next
% month and back up one day.
\setmydatenumber{GivenDateCounter}%
{#1}%
{\numexpr#2+1\relax}% Next month
{01}% First of the month
\else
% Since this IS Dec we can just go to Jan 1st of the next
% year and back up one day.
\setmydatenumber{GivenDateCounter}%
{\numexpr#1+1\relax}% Next Year
{01}% Next day is Jan next year since current month is 12
{01}% First of the month
\fi
\addtocounter{GivenDateCounter}{-1}% Now we are the end of the required month
\xdef\LastDayOfMonth{\value{dateday}}% <---- Stuck here.
\typeout{**** \string\LastDayOfMonth for #1-#2=\LastDayOfMonth}%
}%
\begin{document}
\foreach \YearNumber in {2013, 2014} {%
\foreach \MonthNumber in {01, 02, ..., 12} {%
\par
Number of Days in \YearNumber-\MonthNumber{} is
\NumberOfDaysInMonth{\YearNumber}{\MonthNumber}.%
}%
}%
\end{document}
答案1
我想说使用\arabic{dateday}
,因为\value{dateday}
不可扩展(它扩展到寄存器名称,而不是值)。但是它不起作用,因为dateday
没有设置。
由于您不受 的约束datetime
,这里有一个带有 的版本xparse
。
\documentclass{article}
\usepackage{xparse,pgffor,multicol}
\ExplSyntaxOn
\DeclareExpandableDocumentCommand\NumberOfDaysInMonth { m m }
{
\grill_numb_days_month:nn { #1 } { #2 }
}
\cs_new:Npn \grill_numb_days_month:nn #1 #2
{
\int_case:nn { #2 }
{
{1}{31}
{2}{ \grill_if_leap_year:nTF { #1 } { 29 } { 28 } }
{3}{31}
{4}{30}
{5}{31}
{6}{30}
{7}{31}
{8}{31}
{9}{30}
{10}{31}
{11}{30}
{12}{31}
}
}
\prg_new_conditional:Npnn \grill_if_leap_year:n #1 { p,T,F,TF }
{
\bool_if:nTF
{
\int_compare_p:n { \int_mod:nn { #1 } { 4 } != 0 }
||
(
\int_compare_p:n { \int_mod:nn { #1 } { 4 } == 0 }
&&
\int_compare_p:n { \int_mod:nn { \int_div_truncate:nn { #1 } { 100 } } { 4 } != 0 }
)
}
{ \prg_return_false: }
{ \prg_return_true: }
}
\ExplSyntaxOff
\begin{document}
\begin{multicols}{2}
\foreach \YearNumber in {1900, 2000, 2012, 2013} {%
\foreach \MonthNumber in {1, 2, ..., 12} {%
\par
Number of Days in \YearNumber-\MonthNumber{} is
\NumberOfDaysInMonth{\YearNumber}{\MonthNumber}.%
}
}
\end{multicols}
\end{document}
注意\NumberOfDaysInMonth
是完全可扩展的,因此
\edef\MDCCFebruary{\NumberOfDaysInMonth{1700}{2}}
将定义要扩展为的宏28
。
条件命令\grill_if_leap_year:nTF
还可以用于其他场合,有谓词、真、假、真/假四种形式。
答案2
您可以使用捆绑包pgfcalendar
中的包pgf
。实用程序宏接受日期输入,如的<year>-<month>-last
最后一天。<month>
<year>
\documentclass{article}
\usepackage{pgfkeys,pgfcalendar}
\begin{document}
\newcount\datecount
\newcommand\daysinmonth[2]{%
\pgfcalendardatetojulian{#1-#2-last}{\datecount}%
\pgfcalendarjuliantodate{\the\datecount}{\dyear}{\dmonth}{\dday}%
\dday
}%
\daysinmonth{2012}{2}\par
\daysinmonth{2014}{2}\par
\daysinmonth{2014}{5}
\end{document}
答案3
一种老式的方法,使用\ifnum
和 mod 计算intcalc
:
\documentclass{article}
\usepackage{multicol,pgffor,intcalc}
\newcommand{\NumberOfDaysInMonth}[2]{% \NumberOfDaysInMonth{<year>}{<month>}
\ifcase#2
\or 31% January
\or% February
\ifnum\intcalcMod{#1}{4}=0
\ifnum\intcalcMod{#1}{100}=0
\ifnum\intcalcMod{#1}{400}=0
29% Year divisible by 4 and 100 and 400
\else
28% Year divisible by 4 and 100 (not 400)
\fi
\else
29% Year divisible by 4 (not 100 nor 400)
\fi
\else
28% Year not divisible by 4
\fi
\or 31% March
\or 30% April
\or 31% May
\or 30% June
\or 31% July
\or 31% August
\or 30% September
\or 31% October
\or 30% November
\or 31% December
\else
999% Invalid month...
\fi
}
\begin{document}
\begin{multicols}{2}
\foreach \YearNumber in {1900, 2000, 2012, 2013} {%
\foreach \MonthNumber in {1, 2, ..., 12} {%
\par
Number of Days in \YearNumber-\MonthNumber{} is
\NumberOfDaysInMonth{\YearNumber}{\MonthNumber}.%
}
}
\end{multicols}
\end{document}