Picking up the ball

[ CC'd to the Mpls Perl Monger list, Matt Sergeant, and David Wheeler, all
of whom have expressed some interest in the topic. I'd suggest that
further discussion be solely on the datetime@perl.org list, however. ]
Ok, the state of Perl's date and time modules continues to suck. They all
have different APIs, they all overlap each other, but very few cooperate
in any real way.
This is so freaking lame! Why can't I get something back from Date::Manip
that works with Date::Calc, or that has an API like Date::ICal or
Time::Piece? Why? Why? Why?
I don't know why, but it's time to change it.
First, let me summarize some of the past discussion along these lines.
Shane tests this list. It works. A promising beginning -
http://archive.develooper.com/datetime@perl.org/msg00001.html
Rich Bowen's "Grand Unified Theory of Date/Time modules -
http://archive.develooper.com/datetime@perl.org/msg00009.html
Also read Rich's edited version of his original proposal:
http://dates.rcbowen.com/unified_edited.txt
Lots of discussion on this thread. I think Rich's basic points all still
stand, and his ideas are all good. The only thing I think left out in
Rich's proposal is that a base DateTime object should support fractions of
a second. This could probably be optional, since most people won't need
it.
As a side note, there's a Perl interface to libtai64 called Time::TAI64
(marked as beta and not updated in about 5 months). TAI64 is apparently
the current standard, but I'm not sure that really means we have to use it
;)
Later, Rich posted a message about namespaces wherein he proposed a set of
top 2-level datetime-related namespaces. Also some discussion of Date::
vs. Time:: in this thread. A good start but needs more stuff (I'll come
back to this) -
http://archive.develooper.com/datetime@perl.org/msg00095.html
Skud asks all the datetime module authors to identify themselves -
http://archive.develooper.com/datetime@perl.org/msg00111.html
Rich outlines some proposed namespace changes based on his earlier
proposal - http://archive.develooper.com/datetime@perl.org/msg00145.html
Skud made a list opf everyone on the list, which provides a handy, though
a bit outdated, list of date & time modules -
http://infotrope.net/opensource/software/perl6/modules/author-groups/datetime/
Even more discussion on namespaces -
http://archive.develooper.com/datetime@perl.org/msg00208.html
After this, it all sort of dies down until someone pops back up in
February, 2002 and asks "why does this all still suck?" -
http://archive.develooper.com/datetime@perl.org/msg00317.html
Rich says he gave up trying to herd the cats -
http://archive.develooper.com/datetime@perl.org/msg00320.html
And last but not least, my recent rant in my use.perl journal about how
this _still_ sucks, which prompted some discussion in the comments -
http://use.perl.org/comments.pl?sid=10459
As part of the discussion I posted a quick proposal for fixing the mess,
and I'll restate a refined version of that in a second.
In a response to that proposal Jesse Vincent pointed out that there was
code for timezones in the reefknot CVS as Date::ICal::TimeZone. Thanks
Jesse!
Ok, so here's my proposal.
1. Stop herding cats. If existing module authors don't want to play,
then screw them. I don't want to spend lots of time arguing about
namespaces and whether modules should move to a new namespace or any
such crap. I want to have a suite of modules that actually work
together, instead of a big mess of random crap!
2. Use the DateTime:: namespace. The modules@perl.org cabal doesn't
like it? That's nice. Their buy-in is nice, but lack thereof does
not prevent success. And in my experience, when presented with
working code that's being used by a bunch of people, they may accept a
namespace previously deemed unacceptable.
Why a new top-level namespace? Well, what's the difference between
Date:: and Time::? Not much, in most cases. It seems like the
authors of these modules mostly picked one at random. There are a few
exceptions, like Time::HiRes, but other than that, it's ridiculous.
Moreover, the DateTime:: space is empty except for one module, and so
it won't be cluttered by a million overlapping older modules. So it
provides a nice psychological benefit of dropping the baggage.
3. Start with set of base data objects around which functionality can be
built.
NOTE: I am not particularly wedded to any of these namespaces, I'm just
trying to outline the basic functionality I think is needed for a good
suite of datetime modules. OTOH, I don't want to spend lots of time
arguing about the damn namespaces!
- DateTime::Object - Yeah, I know Rich hates class names that describe
the implementation, so maybe DateTime::Base. I don't care too much. The
namespace should make it should be obvious that this is the basic building
block for all datetime functionality in the suite. A good candidate for
this is the existing Date::ICal code, with a bunch of the Time::Piece
convenience methods thrown in for good measure. The only thing Date::Ical
needs is to add support for fractional seconds.
There's also Class::Date and Date::Handler. But I really want to recruit
Rich for this, so I lean towards using a tweaked Date::ICal for the base
object.
-- Simple OO interface for getting pieces of the date, formatting for
display, etc. Date::ICal and Time::Piece have a good API for this
already. I think Time::Piece may have _too many_ methods, but Date::ICal
doesn't have quite enough.
-- It must work outside of epoch times. Date::ICal - check!
-- It should handle fractional seconds. Based on a brief perusal of
Date::ICal, I think this can be added without too much difficulty.
-- Provides simple date parsing ala Time::Piece->strptime. Maybe throw in
the functionality provided by Date::Parse? Maybe make this a separate
module. Doesn't matter too much.
-- Complex date parsing to be provided by a separate module (refactored
Date::Manip, I hope).
-- Real timezone support (Olsen database), something totally lacking in
Perl right now. We need to finish up the Date::ICal::Timezone stuff Jesse
pointed me at.
-- Date calculations ala Date::Calc. Some of what Date::Calc provides
doesn't really return _dates_ per se, and that can go in a separate
module.
- DateTime::Delta - Date::ICal::Duration. Also look at some of the
convenience constants provided by Time::Seconds (which comes with
Time::Piece).
-- Should handle business versus normal days.
-- Should be possible to plug in holiday calendars for business day
calculation. See Date::Calendar in Date::Calc.
- DateTime::Set - See Date::Set
-- Needs to handle both finite and infinite sets. Should allow set to be
created as explicit set of DateTime::Object objects, _or_ via recurring
specifier.
-- Should function as an iterator
my $datetime = $dt_set->next;
my $datetime = $dt_set->next( after => $datetime );
my $datetime = $dt_set->next( before => $datetime );
my $datetime = $dt_set->prev( before => $datetime );
You get the picture.
-- Provide complex recurring specifier parsing, again this should probably
come from a recfactored Date::Manip.
- DateTime::Span
my $span = DateTime::Span->( begin => $datetime, end => $datetime );
my $span = DateTime::Span->( datetime => $datetime, delta => $delta );
if ( $span->contains( $some_datetime ) ) { ... }
my $delta = DateTime::Span->delta;
- DateTime::Span::Set
-- Whee! Sets of datetime spans! Again, finite and infinite.
my $span = $dt_span_set->next( begins_before => $datetime );
-- Complex parsing? "Every Tuesday in March from 3:30PM - 5:30PM" That'd
be cool, but not crucial.
- DateTime::Algorithm - aka Rich's proposed Date::Algorithm. Includes
things like:
-- DateTime::Algorithm::Leapyear
-- DateTime::Algorithm::Passover
- DateTime::Calendar - other calendars
-- Must be interoperable with base datetime object! This means that we
can convert back and forth between the two on demand.
-- DateTime::Calendar::Chinese
-- DateTime::Calendar::Discordian
- DateTime::Event - Rich proposed DateTime::Holiday but Abigail pointed
out that there are plenty of events that aren't holidays, per se.
-- DateTime::Event::Christmas
-- DateTime::Event::Christmas::EasternOrthodox
-- DateTime::Event::FourthofJuly - for _very_ dumb people ;)
As noted in this proposal, much of this already exists. Here's the
modules I propose stealing heavily from:
- Date::ICal & Time::Piece
- Date::Calc and the stuff it comes from
- Date::Set
- Date::Parse (good simple parsing routine)
- Date::Manip (the code is ugly but it does very cool things)
- Date::ICal::Timezone - in reefknot CVS
Modules from which there are no doubt good bits of code to steal, plus
inspiration for various features
- Class::Date
- Date::Handler
- Date::Convert
- others, no doubt
And here's a set of goals:
1. Produce the above-mentioned modules, starting with DateTime::Object,
the base class. The most important thing here is to come up with an API,
and a functional first implementation. Where possible, use existing code
in new modules. Where that's impractical (Date::Calc), simply use the
other module under the hood, and provide an API to it that fits into the
rest of the scheme.
Especially steal test suites from as many modules as possible!
2. Integrate everything into our datetime module suite codebase. This
means that where things are being used under the hood, we re-implement as
needed.
3. Now we have stuff that works. Good. At this point we focus on several
separate goals. Optimizing the base pieces. For example, I'm sure a lot
of the base date object and date math can be implemented in C. Same for
date calculations (see Date::Calc).
Work on complex bits like fancy date parsing (Date::Manip), datetime span
sets.
4. ...
5. Profit!
Ok, forget 4 & 5. But I think the rest are good ideas.
So, who's ready to chew ass and kick some bubble-gum?!
-dave
/*=======================
House Absolute Consulting
www.houseabsolute.com
=======================*/