Stata The Stata listserver
[Date Prev][Date Next][Thread Prev][Thread Next][Date index][Thread index]

st: leap years


From   "Nick Cox" <[email protected]>
To   <[email protected]>
Subject   st: leap years
Date   Thu, 15 Jan 2004 18:30:32 -0000

2004 is a leap year. This raises a small Stata problem, 
how to determine if a year is a leap year using Stata
syntax. 

The criteria for a year to be a leap year are 

YES if       1. year divisible by 4 

(but NOT if  2. year divisible by 100 

(but YES if  3. year divisible by 400))

and NO otherwise. 

If a leap year is a first-order correction, 
then the third criterion is an example of a third-order
correction. Scientists and engineers often use such 
ideas, but they seem in shorter supply in the everyday 
world. (I owe this remark to some Stata friend, but 
I have forgotten who it was. If you recognise your 
remark, remind me privately.) 

Naturally everybody knows criterion 1. but criteria 
2. and 3. are occasionally forgotten. For example, 
Excel has 1900 as a leap year: allegedly this 
was to provide bug-for-bug compatibility with 
Lotus 1-2-3. This is documented openly by Microsoft. 

In Stata: suppose -year- is a variable. An indicator 
1 for leap year and 0 otherwise is then 
given by 

(mod(year,4) == 0 & mod(year,100) != 0) | mod(year,400) == 0 

as -mod(,)- provides the remainder left over from division. 

The nested -cond()- solution, to please David Kantor, is 

        cond(mod(year,400) == 0, 1, 
	  cond(mod(year,100) == 0, 0, 
	  cond(mod(year,4)   == 0, 1, 
	  0))) 

-- the layout of which may be important to you, if not 
to Stata. 

To make sure you have balanced parentheses, exploit the 
pertinent function in a decent text editor: in the 
Stata do-file editor it's "Balance", Ctrl-B; in Vim
it is the % key; etc. 

Given daily dates, a feature of a leap year is clearly 
that there is a February 29, so 

	mdy(2,29,2004) < . 

is true. More explicitly: -mdy(2,29,?)- is missing 
if ? is not a leap year, but non-missing otherwise; 
in the latter case, it is less than missing. You 
could also do that as 

	!mi(mdy(2,29,2004)) 

Similarly, there are 366 days in a leap year, so 

	doy(mdy(12,31,2004)) == 366 

is true. We could vectorise both of those calculations 
to say 

	mdy(2,29,year) < . 

or 

	doy(mdy(12,31,year)) == 366 

Any other amusing or neat solutions? Especially neater 
ones? 

Nick 
[email protected] 
*
*   For searches and help try:
*   http://www.stata.com/support/faqs/res/findit.html
*   http://www.stata.com/support/statalist/faq
*   http://www.ats.ucla.edu/stat/stata/



© Copyright 1996–2024 StataCorp LLC   |   Terms of use   |   Privacy   |   Contact us   |   What's new   |   Site index