A bit more about Time::Moment

In my previous blog post I mentioned the bottlenecks of DateTime and why I had to develop Time::Moment and it's underlying c library, c-dt.

In this blog post I'll talk a bit of the design decisions I made for Time::Moment.

Time::Moment supports a finite set of timestamps, the range is 0001-01-01T00:00:00Z to 9999-12-31T23:59:59Z with nanosecond precision regardless of architecture (32/64 bit) as long as the compiler provides support for 64 bit integers (I'm not aware of a architecture where it would be feasible to run Perl that doesn't provide a compiler which doesn't support 64 bit integers, cpan testers agree). Externally (the documented API) Time::Moment is constrained by 32 bit or the mantissa of NV (doubles) 53 bit. Time::Moment doesn't trust Storable and thus takes care of marshalling and unmarshalling the state when serializing/unserializing using Storable. Time::Moment guarantees a marshalled object on a Perl compiled 64 bit platform is unmarshalled correctly on a Perl compiled 32 bit platform and vice versa.

I'm a firm believer of standards and when it comes to timestamps, there is only one standard that is without legacy, it's ISO 8601. Time::Moment implements a subset of the ISO 8601:2004(E) standard. In my experience, when you mention ISO 8601, most developers think of RFC 3339, which is a superset of ISO 8601 and only accept one of the three calendar representations defined by ISO 8601.

Time::Moment supports three different calendars in two different formats, as specified by ISO 8601:2004(E). If you haven't read the wikipedia article covering ISO 8601, I suggest you do it know=)

Time::Moment->from_string is capable of parsing the following compliant timestamps (ISO 8601:2004 4.3 Date and time of day)

Combinations of calendar date and time of day:

Basic format:
20140808T003146+0200
20140808T003146.705971+0200
20140808T0031+0200

Extended format:
2014-08-08T00:31:46+02:00
2014-08-08T00:31:46.705971+02:00
2014-08-08T00:31+02:00

Combinations of ordinal date and time of day:

Basic format:
2014220T003146+0200
2014220T003146.705971+0200
2014220T0031+0200

Extended format:
2014-220T00:31:46+02:00
2014-220T00:31:46.705971+02:00
2014-220T00:31+02:00

Combinations of week date and time of day:

Basic format:
2014W325T003146+0200
2014W325T003146.705971+0200
2014W325T0031+0200

Extended format:
2014-W32-5T00:31:46+02:00
2014-W32-5T00:31:46.705971+02:00
2014-W32-5T00:31+02:00

For comparability reasons, Time::Moment stringifies to a Calendar date and time of day in extended format.

Because we (the common developers that need to deal with shitty implementations of ISO 8601 and RFC 3339) have to deal with real world implementations that purport to be in either ISO 8601 or RFC 3339 but in reality is neither, I had to implement a lenient mode in Time::Moment->from_string().

3 Comments

Why no overloading operators other than stringification and comparison? It would be easier to just add two scalars containing a references to a Time::Moment class than use plus_hours or one of those other methods.

Leave a comment

About Christian Hansen

user-pic I blog about Perl.