Astronomers and others need calendar conventions in which the date and the day number are independent of location; for this, GMT/UTC and Julian Day Number & Modified Julian Date are appropriate.
GMT here refers to British legal GMT, in which the pre-1925 Astronomical 12-h shift is disregarded. The GMT date changes at London mean solar midnight.
More often, though, one needs a convention in which the local civil date and the day number change simultaneously; for this, Chronological Julian Date & Chronological Modified Julian Date are appropriate. Chronological Julian Day Number & Chronological Modified Julian Day Number are alternative terms.
In computing, other origins are often somewhat arbitrarily chosen - see Date and Time Scales.
It is often easier, or more efficient, to work in terms of day numbers, converting to/from calendar dates for output/input, than to work with year, month, and day.
"Mapping Time" (OUP), by E.G.Richards (EGR), contains much related information.
References to Julian day number in code and links are quoted, and actually refer to Chronological Julian Date.
For financial work, consider Wikipedia Day count convention but be aware of varying local convention.
Addendum for converting from Y M D
To allow for dates before 0000-03-01, add a multiple of 400 (Gregorian), 28 (Julian), or 2800 (both) years to y and, unless wanting only Day-of-Week, adjust the constant term correspondingly.
The method may not be optimum; starting with Year = (Year + Bias) mod 400 (Bias not needed for A.D. years) might reduce subsequent arithmetic.
Or use Math.floor(X) instead of X|0 which should automatically widen the range.
Conversion between closely-related Calendars can be done with simple difference rules such as that in Date and Time Scales. Otherwise, the best policy is to implement, for each Calendar, conversions in each direction between Date and Day-Count.
The Day-Count should be a well-defined one with a standard origin, and should change at the same time as the Date. It should be explicitly based, either on legal GMT or on local time.
Julian Date (JD) changes at noon GMT, Modified Julian Date (MJD) at midnight GMT; so those are not suitable. Generally one should use their "Chronological" versions (CJD, CMJD), which refer to the local civil day.
For some non-Christian Calendars, see via other pages :-
For Calendars in which the Date changes other than at midnight, be very careful about the matching of Dates to Days. For example, it is not usually made clear, when the origin of the Islamic Calendar is given in Christian terms, whether MuHarram 1, 1 A.H. maps to the Julian Calendar Date on which it started or to the following Date with which it had a larger overlap.
To represent a date Y M D as an eight digit string, it may be convenient to use a pseudo-date number such as PD = (Y×100+M)×100+D first; that transformation is readily reversible either with div and mod or with string operations. That format is also convenient for sorting, as number or string.
Zeller's Congruence (or Algorithm) gives Day-of-Week from Calendar Date. Methods, often attributed to Zeller, which use the same principles help to convert Calendar Date to Day-Count.
Computer languages often have primitives or library routines which implement, or can be used in, conversions. Such may be employed in test routines here, but the conversion routines shown do not use them. Code tested here is JavaScript.
Various arithmetical methods exist for dealing with the Leap Year rules in converting between day number and year number; either manifestly embodying the rules, or condensed either for numerical efficiency or for simplicity. Some are included in my dateprox.pas. Many are given in books such as "Mapping Time".
For JavaScript, see also in my JavaScript Date and Time 1 : Date Arithmetic, which was mostly not directly developed from Zeller's papers.
Various methods are valid over various year-ranges. Before using any over a wide range, test carefully against a method which will have a wide range, such as one using a Date Object.
Here the conversions are illustrated and tested in JavaScript.
The expression a % b is the remainder operation, equivalent to a mod b in Pascal; the integer part from the implied division is disregarded.
The expression (a/b)|0 using the bitwise OR operator is integer division, equivalent to a div b in Pascal; the remainder is disregarded. And Math.floor(a/b) is a wider-range but slower version.
The expression (a>>2) is integer shift right 2, equivalent to integer division by 4.
And M += 12 is increment by 12, and y-- is decrement by 1, and // starts comment to end-of-line, and /* ... */ is comment. The rest should now be obvious enough.
The origin of JavaScript dating, 1970-01-01 GMT, is MJD 40587.
CMJD -678973 is the day before the month before A.D. 0, Gregorian; that is date 0000-00-00.
Ordinarily, in Gregorian, a year has 365 days, a span of 4 years has 1461 days, and 100 years have 36524 days; but 400 years always have 146097 days.
Some of what follows is derived from the algorithms Web page for "Mapping Time" (a), in which the following constants are used.
For the Julian Calendar, omit the lines which assign to g in EGR-derived functions; and omit the obviously inapplicable Leap Year terms or lines and adjust the zero (probably by 2) in others.
The following tester harmlessly includes out-of-month dates.
2007-04-03: Loop start d=0 changed to d=1 as Firefox 2.0.0.3
Date.UTC takes d<1 as d=1 (2.0.0.14 - unchanged;
3.0 - fixed).
N.B. window.status shows progress, if enabled.
Two versions, essentially the same :
This, for CMJD, was developed in The Calendrical Works of Rektor Chr. Zeller : The Day-of-Week and Easter Formulae, section moved to Material Related to Zeller's Congruence., q.v.; the fastest method that I know of, and I doubt whether it can be much improved upon. This is the clearest version of the code.
This, for CMJD, was developed from the Day-of-Week code in Wikipedia Zeller's congruence.
This version of the code is in include3.js.
Modified by me from Mike Keith's day-of-week algorithm F1 in my subsidiary Zeller page.
The Fortran algorithm is cited in Julian Day Numbers by Peter Meyer, Sec 9 :-
The latter illustrates the folly of using local dates where UTC can be used instead.
The reverse calculation can be done in various ways; I have sought a style-matching and efficient version.
These two functions each test a function below.
N.B. window.status shows progress, if enabled.
This has a straightforward way of determining the year :-
It is somewhat faster with the Julian and Gregorian Rules done by congruences, and Math.round replaced; this version of the code is in include3.js :-
Adapted from Henry Fliegel and Thomas van Flandern, ACM Vol 11, 1968 (by mail from HJW 20051228); also see Julian Day Numbers by Peter Meyer, Sec 9.
N.B. Much of the work will be repeated three times, once for each getUTC... function call.
See in my VBScript Date and Time 1.
These do not use an absolute Day-Count.
Where, as in JavaScript, Delphi, etc., the language provides relevant pre-coded Date methods, it is likely that those will perform better than these approaches.
For some tasks, it is desirable that a Day-of-Year slightly outside the year itself be handled acceptably.
Transferred from other published and unpublished pages.
Generally, these methods start with March, and may count January as Month 13.
February is merely as long as is needed to pass the time until March.
Probably from "Astronomical Algorithms" (2nd ed, Dec '98) by Jean Meeus, Willmann-Bell Publishers, ISBN 0-943396-61-1.
K = 2 - (Y%4==0) // 2 - Leap, 1901-2099 N = Math.floor(275*M/9) - K*(M>2) + D - 30
N is the day-of-year of Y M D; extension to full Gregorian is obvious enough.
So for month-length :-
ML = Math.floor(275*(M+1)/9) - Math.floor(275*M/9) - K*(M==2) // or ML = M==2 ? 30-K : Math.floor(275*(M+1)/9) - Math.floor(275*M/9)
Tony Finch has noted that if (Month+10)*367%12 > 4 then Month (1..12) has 31 days :-
Similar methods are used in parts of JavaScript Date and Time 1 : Date Arithmetic and JavaScript Date and Time 3 : Input and Lengths.
From Week-Day, one can deduce the following for the number of days, N, since the end of February, and for the number of days, D, in each Month except February :-
M := 1 + (Month+9) mod 12 ; N := 28*M + (13*M-1) div 5 - 30 + Day ; D := 30 + (3*M+2) div 5 - (3*M-1) div 5 ; // not for February
Other forms have been given which require floating-point arithmetic (beware rounding error; I would always prefer integer arithmetic) ; Michael Deckers has quoted the derived forms :-
D = 1 + floor( ((M - 3) mod 12) * 30.6 + 0.4 ) // Mar 1 = 1 ? M = 1 + floor( (D + 60.6)/30.6 ) mod 12 // Mar = 1 ?
Thence
M = 1 + floor( (D*5 + 303)/153 ) // mod 12
and so
I have found the following way of calculating the lengths of the months :-
January is here also Month 13.
I have chosen to use a single array, though some tasks can be done faster with arrays of accumulated month-lengths.