# Determine last day of given month

I want to determine how many days there are in a particular month.

Using the datenumber package, I thought I could simply set the date to the 1st of the next month and then back up one day would be the end of the month and extract the date. Well that sure seemed simple when I came up with it, but then got stuck at actually extracting the day of the month.

So, what do I need to replace

\xdef\LastDayOfMonth{\value{dateday}}


with the get the number of days in the month.

## Notes:

• I am not opposed to additional packages, so any package solution is fine.

## Code:

\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}

-
The number of days in each month is independent of the year except for February which depends on the year being a leap year or not. Wouldn't it be easier to just encode the leap year algorithm and use an if-cascade? if year is not divisible by 4 then common year else if year is not divisible by 100 then leap year else if year is divisible by 400 then leap year else common year – Christian Lindig May 1 '14 at 17:14
@ChristianLindig: Good suggestion, but I'd prefer not to code it if possible. Although the two solutions below that compute it makes it look a lot simpler than I had thought it would be. – Peter Grill May 1 '14 at 20:05

I'd say to use \arabic{dateday}, since \value{dateday} is not expandable (it expands to the registers name, not to the value). However it doesn't work, because dateday is not set.

Since you're not bound to datetime, here's a version with 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}


Note that \NumberOfDaysInMonth is fully expandable, so

\edef\MDCCFebruary{\NumberOfDaysInMonth{1700}{2}}


would define the macro to expand to 28.

The conditional command \grill_if_leap_year:nTF can also be used in other situations. It has the four forms: predicate, true, false and true/false.

-

An old-school way using \ifnum and mod calculations from 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}

-

You can use package pgfcalendar from the pgf bundle. The utility macros accept date input as <year>-<month>-last for the last day in <month> of <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}

-