25

Is there a standard body or a specific normative way how time-related things should be implemented in practice (like ICU for Unicode-related tasks) or is this currently a "best-effort", depending on how much effort, time and money language and library implementers want to spend?

Is there a specific and complete implementation which could serve as a example for how time-related things should be handled?

Which existing library would you consider as a bad, a decent or a good example?

soc
  • 27,983
  • 20
  • 111
  • 215
  • In my experience, the best way to implement date/time operations is however Java DOESN'T implement them... – Mark Sep 14 '10 at 14:39
  • Do you mean util.Date/util.Calendar, JodaTime or JSR310? :-) – soc Sep 14 '10 at 14:53
  • I haven't worked with JSR310, but it has been my displeasure to work with util.Date and util.Calendar. – Mark Sep 14 '10 at 15:08
  • 1
    I found this W3C document to offer an excellent overview of the how and whys: http://www.w3.org/TR/timezone/ – Stephen Kennedy Nov 11 '11 at 14:55

6 Answers6

17

I'll try to give an answer to the second and third question using the Java library which might become part of Java 7.

javax.time.* (JSR 310)

These classes are a complete rewrite of JodaTime trying to fix the design flaws of util.Date/util.Time as well as JodaTime.

JSR 310 tries to provide a comprehensive model for date and time, which is type-safe and self-documenting. It is interoperable with existing classes, but also considers XML- and DBMS-based use-cases. The classes are final, immutable, thread-safe and cannot be modified after construction. Instances are created via a rich set of Factory methods which can cache things in the background.

LocalDate dateToday     = LocalDate.of(2010, 9, 14);
LocalDate oneMonthLater = dateToday.with(OCTOBER);
LocalDate oneYearLater  = dateToday.withYear(2011);

The API has some "machine-oriented" classes and some "human-oriented" classes:

Machine-oriented

Instant

For a point of time comparable to an Unix or Java timestamp. Actually there are Instant, TAIInstant and UTCInstant which enable people to exactly choose which definition of time they need i. e. "day-based", "linear, without leap seconds" etc.

Duration

A time range not necessarily associated with a specific Date or Calendar.

Human-oriented

There is a rich collection of classes handling different use-cases like Date-only, Time-only, Time and Date, with and without Timezones, with and without DST.

DateProvider

OffsetDate, LocalDate (, java.sql.Date compatibility)

TimeProvider

OffsetTime, LocalTime (, java.sql.Time compatibility)

DateTimeProvider

ZonedDateTime, OffsetDateTime, LocalDateTime (, java.util.GregorianCalendar compatibility)

InstantProvider

Instant, ZonedDateTime, OffsetDateTime (, java.util.Date compatibility)

Period

Periods represent a time span like "5 days" that can be added and subtracted from a date/time.

Matcher

Matchers enable queries like "is this date in the year 2006?" or "is this day the last day of this year".

Adjuster

Adjusters come to the rescue if you have want to make more complex changes, like "Give me the last day of the month!" or "The second Tuesday after Christmas, please!".

Resolver

Resolvers allow users to define what should happen if a certain date is not valid, like February 31st 2010:

DateResolver previous = DateResolvers.previousValid();
LocalDate date = date(2010, 2, 30, previous);
// date = 2010-02-28

Working with Timezone and DST data

It is possible to serialize these classes and deserialize them using either the current timezone data or the timezone data when they were serialized. Additionally, rules from different timezones can be compared: It is possible to find out if DST rules have changed, e. g. between version 2010e and 2010f for Dates in London or Moscow and decide what should be done if a Time is in a gap or overlap.

Calendar systems

Although everything is based on ISO-8601, simple calendars for Hebrew, Hijrah, Japanese, ThaiBuddist, etc. time systems are provided.

Formatting and Parsing

toString() returns ISO8601 and patterns like those in SimpleDateFormat and more advanced are supported.

Integration

  • Databases
  • JodaTime
  • Legacy JDK classes (java.util.*)
  • XML

References:

soc
  • 27,983
  • 20
  • 111
  • 215
  • 1
    Is it just me or does the `Resolver` object seem like a really, really dumb idea.. I thought good user interfaces didn't surprise the user. I'd much rather it throw an error you can catch and notify the user that the date is wrong. – Blindy Sep 23 '10 at 07:55
  • @Blindy, I agree. I haven't used JSR310 at all, but I just don't see how this could work. – John L Sep 23 '10 at 14:04
  • Correction: There is no Hebrew calendar in JSR-310. Furthermore: Oracle has rejected it, see [JDK-issue](https://bugs.openjdk.java.net/browse/JDK-6256425). And I would not really call such calendars being simple otherwise nobody had problems to implement it by own fortues. – Meno Hochschild Nov 27 '17 at 11:34
11

I don't think there's a single standard to such things at the moment, however there are multiple standards which such things may conform to: ISO 8601 for example.

ICU's own date/time handling is a cross-language (C/C++ and Java) and multi-platform library.

It handles dates and times internally, typically, using for a single time a UDate (C/C++) or a java.util.Date/long (Java), as number of milliseconds since 1-1-1970, or a Calendar object which is specific to the type of calendar (Gregorian vs Hijri, etc). Durations are available for formatting. Leap years are calculated as part of calendar systems, and leap seconds are assumed to be handled by the underlying operating system. DST/Timezone data is kept up to date with 'the tz database' sometimes referred to by its author's surname, Olson.

Hope this has answered your question some as regards ICU.

Steven R. Loomis
  • 4,228
  • 28
  • 39
  • Cool, I didn't know that ICU had a Date/Time library! I thought of ICU as a "de facto" implementation standard for everything Unicode-related, but it seems to have quite a lot of additional use cases, too. – soc Sep 15 '10 at 07:09
  • @soc Interesting about the bounty- do you have any more specifics about what you're looking for? I didn't notice that you had answered your own Q. – Steven R. Loomis Sep 16 '10 at 21:53
  • Yes, I hope that someone experienced in more languages than me can give me an overview like "the standard library in language X is quite bad because [...]. Therefore most people use library Z to solve the problem with [...], which is comparable in design to library W in language V. [...]" And so on and so on. I only have some limited experience with the Java libraries and would be happy if someone else has some judgment about them or can explain why they were designed the way they are and how the situation is in Python, Perl, C#, the Lisp-family, etc. – soc Sep 16 '10 at 22:31
  • It seems to be really hard to get time-related things right and java.util.Date/Calendar are a perfect example of a failed attempt. I wonder if other languages put more thought into it before they shipped time-related classes with their standard library and got it right the first time or if they had comparable trouble they had to solve by fixing/deprecating/removing etc. the classes? – soc Sep 16 '10 at 22:41
  • I'm not sure that I would call java.util.Calendar a failed attempt. It was released Feb 19, 1997 with Java 1.1 and provided Java with localized date and time functionality after much thought and effort was put into it. Of course, looking back, there are always things that can be improved. So your question is a good one, in the sense of 'what has been done, how can it be done better'? – Steven R. Loomis Sep 17 '10 at 17:45
11

There are time(s) and there are dates (calendars)
The first problem is that dates are not linked to time but to astronomical position of Earh, Moon, etc. + regularity/periodicity of human activity. The time is also subjective and relative or even relativistic and measured either astronomically or or atomically.

The time bodies and the date/calendar bodies
The International Standartization Organization (ISO) [4] has issued

  • "ISO 8601 Data elements and interchange formats — Information interchange — Representation of dates and times" [4a]

which, like other international standards, is recommendation and is based on already established practices.
It is (subjectively) based only on Gregorian Calendar [5] and on proleptic one (projected backwards to well before it was actually invented so is of limited use in dealing with historic dates) [5a].

The World Calendar Association [1d] initiated the introduction of new World Calendar since 2012 [1b-1d] which would make useless already existing date libraries. Again, the same main problem, see on it further on.

The most covering, I ever saw, date-time-related comparison in IT systems is [2] between BIG8 DBMS (IBM DB2, Informix, Ingres, InterBase, Microsoft SQL Server, MySQL, Oracle, and Sybase).
This and all other surveys show that the processing of the same, for ex., Gregorian calendar time/dates are different between all systems as well as inside the same platforms (between different products and versions of the same product), see for ex., [3].

THE MAIN PROBLEM with all date/time libraries in all-all systems, frameworks is that their date/time datatypes do not permit to include geographical and calendar information in date/time datatypes.
Without which they are mainly half- useless - what is the sense of milliseconds in SQL Server datetime2 values in 7th century? At that time there was even no clocks measuring time with accuracy of minutes (Galileo Galilei used, for ex., his heart beats to measure intervals of time in his experiments) as well as Gregorian Calendar was not even invented.

So, plenty of datetime type space is misused failing to give the most important flexibility of working with dates by linking and including with them to geography and/or calendar info.

Just fast illustrations:

  • Modern Russia uses Gregorian calendar and the Russian Orthodox Church uses Julian calendar by which many state holidays in Russia are determined (for example, Christmas in Russia is on 7th of January and Old New Year is on 14th of January by Gregorian Calendar while the dates of other religious holidays are floating relatively to Gregorian Calendar).
  • In pre-1917 Russia, Poland as its part, used Gregorian Calendar while all the rest Russia used Julian Calendar (with floating difference of 13-18 days at the "same" time zone) [5b];
  • Double-click on clock in MS Windows (or open Control Panel --> Date and Time) --> Time Zone tab --> view time zones in combobox. You will see that there are 25 hours from GMT-12:00 to GMT+13:00 over a hundred of time zones with fractions of hour like GMT+5:00, GMT+5:30, GMT+5:45, etc.

==== Cited:
[1] New World Calendar
[1a]Update: Sorry, do not read [1a], author confused calendars and wrote wrong info in this news brief
World Calendar 2012: 35 days in a month
http://www.panorama.am/en/society/2010/01/29/newcalendar

[1b] http://en.wikipedia.org/wiki/World_Calendar
[1c] http://www.theworldcalendarin2012.org/Index2.htm
[1d] http://www.theworldcalendar.org/TWCA.htm

[2] Peter Gulutzan,Trudy Pelzer. SQL Performance Tuning: Dates in SQL
http://www.informit.com/articles/printerfriendly.aspx?p=30939

[3] SqlDateTime.MinValue != C# DateTime.MinValue, why?
SqlDateTime.MinValue != DateTime.MinValue, why?

[4]
International Organization for Standardization
http://en.wikipedia.org/wiki/International_Organization_for_Standardization
[4a] ISO 8601 Data elements and interchange formats — Information interchange — Representation of dates and times
http://en.wikipedia.org/wiki/ISO_8601

[5]
Gregorian Calendar
http://en.wikipedia.org/wiki/Gregorian_calendar
[5a] Proleptic Gregorian calendar
http://en.wikipedia.org/wiki/Proleptic_Gregorian_calendar
[5b] Gregorian Calendar Adoption
http://en.wikipedia.org/wiki/Gregorian_calendar#Adoption
[6]
http://en.wikipedia.org/wiki/Galileo_Galilei

Community
  • 1
  • 1
  • 2
    Great explanation! As soon as I can start another bounty, I award you the points. Thanks! – soc Oct 10 '10 at 14:25
7

I haven't used it in a while, but from past experience I'd say that Boost.Date_Time is a pretty good example.

While probably not the first choice for many fast paced projects today, the expressive power of C++ still seems to be a very good match for a complex problem domain like date/time, so combined with the high quality peer review process to pass for becoming an official Boost C++ library I'd hope that the library at hand could serve as a example for how time-related things should be handled, albeit not as a complete implementation, see below.

Boost Date Time

The library is documented very well, so I could probably assemble the entire answer from quotes, but I'll try to extract some fragments according to the template suggested by soc's answer instead - nonetheless I'm going to start with an entire quote:

Motivation

The motivation for this library comes from working with and helping build several date-time libraries on several projects. [...]

Programming with dates and times should be almost as simple and natural as programming with strings and integers. Applications with lots of temporal logic can be radically simplified by having a robust set of operators and calculation capabilities. Classes should provide the ability to compare dates and times, add lengths or time durations, retrieve dates and times from clocks, and work naturally with date and time intervals.

Domain Concepts

The library supports 3 basic temporal types:

  • Time Point - Specifier for a location in the time continuum.
  • Time Duration - A length of time unattached to any point on the time continuum.
  • Time Interval - A duration of time attached to a specific point in the time continuum. Also known as a time period.

Calculations

You can get a pretty intuitive overview on how the domain concepts relate to each other in section Details - Calculations.

Constraints

An important part of my original decision to evaluate the library has been the available documentation of design goals and necessary tradeoffs in light of the complex problem domain, which seems to outline the real world expertise that has been put into the library - you can read more about it in the following two sections:

Working with Timezone and DST data

There is full support for all kind of calculations and conversions one could think of, as far as I'm concerned - see the headings in section Examples for an initial impression.

Calendar/Time systems

This is definitely the weak spot concerning your specification, despite the library being specifically designed with extensibility in mind:

A large part of the genesis of this library has been the observation that few date-time libraries are built in a fashion that allows customization and extension. A typical example, the calendar logic is built directly into the date class. Or the clock retrieval functions are built directly into the time class. These design decisions usually make it impossible to extend or change the library behavior. At a more fundamental level, there are usually assumptions about the resolution of time representation or the gregorian calendar.

However, I'm not aware of any implementations of other calendar/time systems than the ones included, see Library Reference for the current implementations of:

  • Date Time
  • Gregorian
  • Posix Time
  • Local Time

Formatting and Parsing

This is fully supported and one of the strong points of the library due to the respective power of the underlying C++ I/O system, see Date Time Input/Output - the stream oriented C++ I/O has both merit and issues depending on your needs and expectations, but this topic is discussed elsewhere on this site.

Integration

This is provided as well via compatibility with Boost Serialization, which is archive oriented though, usually meaning a file of binary data, text data, XML or so; i.e. databases are not explicitly supported as in your JSR 310 example.

Community
  • 1
  • 1
Steffen Opel
  • 63,899
  • 11
  • 192
  • 211
  • @soc - Your [own answer](http://stackoverflow.com/q/3709870/3710304#3710304) provided a great template and respective motivation to recall and revisit my evaluation of Boost Date Time; your bounty made this more worthwhile even, thanks much :) – Steffen Opel Oct 10 '10 at 15:08
4

To answer your "Good Example" question, take a look at Noda Time - Jon Skeet's port of the Joda-Time libraries for Java to .Net

Community
  • 1
  • 1
Wolfwyrd
  • 15,716
  • 5
  • 47
  • 67
  • Why was it ported? Is the .NET API as bad as the one from Java? – soc Oct 05 '10 at 20:49
  • 3
    Strange.. I figured he would have just rewritten the universe's implementation of time to native .NET. – intuited Oct 06 '10 at 05:23
  • It's more than just a port. It started out that way, but it's evolved significantly. Joda Time, Noda Time, and JSR-310 are all influenced by similar design concepts and by each other. It is an *excellent* library IMHO, and puts .NET's built-in types to shame. – Matt Johnson-Pint Sep 06 '13 at 02:26
4

You mention Python in an earlier comment.

Python's builtin datetime support (docs) is pretty practical, but you have to use a third-party timezone database such as pytz (docs) to make it close to complete. And, as the pytz docs mention, you may still have problems with adding deltas to times right around DST transitions if you aren't careful.

It was once the case that eGenix's mx.DateTime was the way to go if datetime didn't do it for your application, particularly for string to timestamp conversions, but dateutil seems to be popular these days (I haven't used it though).

Bill Gribble
  • 1,797
  • 12
  • 15