Date methods can be slow, so be careful not to repeatedly recalculate
anything that can be remembered.

Using UTC

I find that the JavaScript UTC methods can be somewhat faster
than the corresponding non-UTC ones. In hindsight, that should be
expected. Unless actual date/times are needed, for
repetitive work such as calendar display it should be noticeably
better to use the UTC methods.

This shows generation of a Date Object set by UTC literals and
generation of a Date Object representing UTC YMDhms from a Date
Object value representing the same civil YMDhms :-

Using Day Counts

Creating a Date Object

Normally, a Date Object will always be created with a particular
value required : "now", or given by parameters.

Otherwise, for N being numeric, new Date(N) should
be faster than new Date() since, while both create an Object,
the former only needs to load it with N while the latter must
consult the system clock and maybe the locality settings. Moreover, with
the former, the value is reproducible. So, unless the current date/time
is needed, the former is better.

Remember to allow for possible Summer Time
and Time Zone changes, except when
using GMT/UTC. Much code presented elsewhere ignores these, and is
therefore in error part of the time. If UTC functions can be used, the
overheads and errors can be avoided.

Otherwise, if Days are specified, then work directly with Days,
rather than with milliseconds from 1970, as civil days are not always 24
hours long, but can be 23 or 25 hours. Likewise, both Months and Years
have varying numbers of Days. Always test over a Summer Time change.

Anything containing 1000*60*60*24 or 86400000 or 864e5 is suspect,
unless it is used in conjunction with UTC functions or there is
appropriate rounding or offset adjustment. Note that in general it will
be the user's settings that matter; on the Web, Summer Time remains
significant even for Polar and Equatorial authors.

Where that number is used, it is better written as 864e5
since that form is less prone to error.

Clock Change Demonstration

The addition of 24 hours of actual time has advanced the EU civil
time by only 23 hours; the inverse occurs in Spring.

JavaScript and UNIX Day 0 was GMT 1970-01-01 Thu; MJD 0
was GMT 1858-11-17 Wed; the difference is 40587 days. Day 0 for
Delphi 2+ and compatible spreadsheets, etc., was Civil
1899-12-30, 25569 days before UNIX Day
0. See
Date Miscellany I and
Date and Time Scales.

Remember that a browser's local time is likely not to be GMT/UTC;
so getTimezoneOffset may be
needed.

True UNIX day number to Date Object of Start

Civil UNIX day number to Date Object

CMJD to Y M D without using a Date Object

Again, remember Summer Time and Time Zone; days are not all the same
length. Do not attempt date shifting in time units, or month/year
shifting in days; direct functions are provided.

Any attempt to deal with civil days by using milliseconds is pure
folly - though JavaScript GMT/UTC days should be constant in length
(being specified (ECMA-262 3rd Edn Sec 15.9.1.1) as having no Leap Seconds).

Note : The clock change, Spring and Autumn, can
occur on the 31st of the month; so, for example, 86400 seconds before
April 1st can be late in March 30th (e.g. EU, one year in 7)
instead of being the last day of March.

Set as many components as possible in a single method call
(the optional parameters were introduced in JavaScript 1.3)

which always give the present civil time tomorrow (strictly,
there is one hour in Spring during which this is not possible, for
places with Summer Time); as usual, month and year will be changed if
necessary.

Note that incrementing/decrementing in Months can, in the first
instance, get to the 29th, 30th or 31st of a month that does not have
that date; in that case, the Object enters the following month, which
may or may not be appropriate (see also 0: Date Object
Information).

Starting with January 31st of successive years, that correctly gives
for leap years Feb 29th, else Feb 28th. Similarly for altering the Year
and avoiding a non-existent Feb 29th.

To step continuously along month-ends, step the beginnings of each
following month, and go back one day each time.

One must decide whether the difference is to use days each
of 24 hours, or is to use days of local time.

Mere comparison is easy (apart from the autumnal ambiguous hour);
compare the fields in order of diminishing significance, and return at
the first difference; or use Date objects and compare their values.

To determine whether one date is within a given number of days of
another, it may be easier or safer to increment/decrement one of the
dates and then compare the result with the other date than it is to work
by subtraction.

If Date Objects are provided, one must consider possible effects
of their time components on comparisons.

General

If avoidable (it may be needed for formal administrative purposes),
do not attempt to subtract date/time in Y-M-D h:m:s; all that borrowing
is tiresome and error-prone. Think about the exact requirements; check
management expectations and needs. For people's ages, however, it seems
often necessary to work in Y-M-D, with care.

Since there are always 12 months in a year, one can for simplicity
work with M' = 12×Y+M; and for subtraction one can ignore month
numbers being 1..12 rather than 0..11. Similarly, hh:mm:ss can be
converted to seconds, if Summer Time transitions are ignored.

Frequently, either the initial or the final date will be fixed, and
the other will be the current date.

Difficulties

A sequence of differences is obtained by keeping one date fixed
and stepping the other date by one day at a time.

A sequence of differences should always look
plausible. Requirements include :-

when Y, M, D match, the result must be 0, 0, 0

when M, D match, the result must be dY, 0, 0

when D matches, the result must be dY, dM, 0

when either date shifts by one day, the days part of the result
usually changes by one, or jumps between 0 and 27/28/29/30.

I doubt whether all of those can be achieved at once!

Consider
Apr 4 to May 6 must be one month and two days; also May 4 to Jun 6.
Step the start daily to May 4; 30 steps, as Apr has 30 days.
Step the close daily to Jun 6; 31 steps, as May has 31 days.
Thus there cannot be a 1:1 correspondence between the two sets of
intermediate differences; there must be an omission or a repeat.

Consider
Apr 4 to Jun 3; 1 month gets to May 4, then -4+31+3 = 30 days.
Jun 3 back to Apr 4; 1 month gets to May 3, then +3+30-4 = 29 days.
In the first case the "borrow" is of May, in the second it is of April.

Detail

Convert the years and months to just months, and subtract. Subtract
the dates; if negative, first "borrow" the length in days of an
appropriate month, with allowance for its year if it is February.
Convert months back to years and months.

One can subtract seconds; if negative, borrow a minute; then subtract
minutes, etc.

If days, hours, minutes, seconds are needed, then set the
start and finish date/times into a date object (new Date()
creates an object for the current date/time), and take
valueOf() for each, and subtract these to get the difference in
milliseconds. If only times are given, use a dummy date, e.g.T = "12:34:56" ; D = new Date("1/1/70 "+T) ,
possibly appending UTC.

Or, for start and finish, multiply days by 24, add hours, multiply
by 60, add minutes, multiply by 60, add seconds; and subtract.