Dates along with companion durations (Days or elapsed Time) obviously fit
the point-extent pattern that we described nearly twenty years ago.
We have nothing to add to that now, except to note that any Date class that fails to meet
the requirements described there can hardly be a candidate for incorporation into any
serious commercial or scientific application. Let's look at some of them:
Spreadsheets share the blame
The mainstream spreadsheet processors got some things right and others wrong. The internal date
representation is the integer number of days since an origin (good) but that origin is December 31,
1899 (bad), and in Excel negative values aren't supported. It's impossible, then, to store
or at least to display a date before that origin.
Suppose d1 and d2 are
objects. In addition to just displaying dates or using them
as parts of a time stamp (trivial), a C++, C#, or Java program might reasonably need:
- To compare them for simple ordering1 and possibly
- To add to or subtract from d1 a number of
Days (a companion class or just an integer)
giving another Date.
- To subtract
d2, giving a duration (number of days).
- To multiply or divide a number of days by a pure number, giving a number of days.
- To divide a number of days by another number of days, giving a pure number.
Note that those requirements are for a pure
class (and optionally also
Days), not one mixed up with
Time2 of day.
What should be the earliest and latest legal
Software, even mainstream products, has gotten this wrong repeatedly, for no good reason:
The exclamation marks are deliberate. Each of those gaffes was utterly inexcusable.
- Excel and other spreadsheet products have failed to support dates before 1900!
- UNIX used a 32-bit number of seconds since January 1, 1970 (first release date),
overflowing in the year 2038, already within the range of retirements and bond
- Many naïve applications as well as some mainstream operating systems stored dates
with 2-digit (or single byte binary) years, causing the costly (and
unnecesary) "Y2K crisis" or similar restrictions!
With an accuracy of 1 day, a 32-bit word can specify four billion distinct Date values.
That's about twelve million years, surely an adequate span for any business application. If we extend
the representation to 64 bits, we can represent a span of time that easily accommodates the age of
So, there is no excuse, no economy of storage, that justifies any of the weird Date
representations that have plagued computer programs and files for decades.
The foregoing discussion was, of course, about internal data representation. A robust
Date facility must support the Calendar(s) in
common use by application users.
Needless to say, the internal representation (i.e. the member data) should have nothing
whatever to do with such cultural complications. A simple integer number of days since an
origin is an efficient and flexible internal representation. But we need to support those
messy external representations, with leap years and, in some cases, discontinuities for
the Gregorian adoptions in different nations.
For most business and scientific applications in the developed world, we just need:
- Constructors for the common external representations, e.g. 8 characters or 3 short
- Conversion functions to produce the external formats expected by the user societies,
e.g. "September 10, 2016" or "2016-09-10".
- Accessor functions to retrieve the month, the day of the month, the day of the week, the
week number of the year, and
the English (or other language) names of the months and weekdays.
That's not so hard or at all mysterious, is it?
Standard library functions and classes
As of today, unfortunately, none of the three languages, C++, C#, and Java, supports a simple and robust
Date class or a companion elapsed time
Days class. Some third-party libraries may offer
acceptable solutions, or you may want to develop your own. This web site offers a reasonable
Java version, and C++ and C# versions are available on
If you have any good solutions, let's hear about them.
1—The usual ordering relations should be supported
except in Java, which can't handle overloaded operators. But Java should use the
usual (but clumsy) Comparable interface, rather than special before and
should be kept separate or tied together is a separate somewhat messy topic that depends upon the
application, and we needn't discuss it here.
Return to IDI home page
Last modified 10 September 2016