August 17, 2010
On Sunday 15 August 2010 05:36:08 Andrei Alexandrescu wrote:
> Thanks for your work, Jonathan. Our decision after the issue with Tango's date and time was to use Boost's. I'd started std.gregorian as a seed of a port of Boost's date and time, in the hope that someone will continue it. Jeff Garland (Boost's date/time author) has been very supportive in the matter.
> 
> I very strongly suggest to stick with copying Boost's or C++0x's date and time facilities, unless we find some clearly superior ways facilitated by D's features. Developing our own date/time library from scratch risks of being at best just as capable as Boost/C++0x but guaranteed unfamiliar to everyone.

Okay. I've started looking at boost's date/time stuff, and they do appear to maintain time internally in UTC rather than converting it to local time, which was my biggest fear, since I've run into a lot of problems with that sort of thing in the past. So, overall, I'd say that it looks quite good (this _is_ boost after all). I do have a few concerns, however.

1. I'd argue that the boost date/time libraries are way too complex for normal usage. If you want to do detailed date/time stuff, they look incredibly flexible, but I'd be very worried that for the average case they're seriously overkill. I'd be worried that programmers looking for basic date/time functionality will quickly get lost in dealing with the full boost implementation and that they would do better to have a seriously simplified date/time facility without all of the bells and whistles. That's not to say that we shouldn't implement the boost stuff in Phobos, but I'd be concerned if it were the only date/time facility available.

2. We're looking at least 3 modules for this - gregorian, local_time, and posix_time. Ideally, they'd be something like std.time.gregorian, std.time.local_time, and std.time.posix_time, but thus far we've avoided multiple levels of modules in the std hierarchy. Depending on the implementation, having package level access between them may be desirable (not having ported it all, I can't say for sure), and I think that it's fair to say that we wouldn't want to give all of std package-level access to the 3 of them (though hopefully package-level access wouldn't be required). So, it needs to be decided whether we want the three modules to be at a deeper level than std in the package hierarchy (and those modules are likely to be _big_ even _without_ solid unit tests - they're split up quite a bit among source files in C++).

3. Do you care whether the internals are the same or if the API is absolutely identical (or at least as identical as reasonably possible when going from C++ to D)? Already, looking at Date, I question the choice of maintaining its state as the number of days rather than a separate year, month, and day. I've implemented a good chunk of it with year, month, day, and I think that the code is much cleaner that way. I also have to wonder why on earth they picked 1400-01-01 as the oldest date possible since that seems arbitrarily recent, and depending on why that is, it would seem desirable to me to make it more flexible than that. In any case, I would hope that as long as the API and functionality is correct that I wouldn't have to port over its internals exactly, and I would hope that there wouldn't be a problem in adding functionality if it seems obviously valuable. And of course, some of it may make sense if the were made closer to how idiomatic D does things (like possibly make time durations ranges).

So, looking over it, the Boost stuff does look quite good but also very complex. I'm perfectly willing to spend time porting it over, and I've already done a fair bit of work with it (though there's a _long_ way to go), but I do think that we need another, easy-to-use date/time facility for the average use case. A fixed up std.date might be good enough for that, but full-on boost is just too much for the average case and is going to scare off a lot of programmers who just want to be able to get the date and do minimal stuff with it.

- Jonathan M Davis
August 17, 2010
On Tue, 2010-08-17 at 02:42 -0700, Jonathan M Davis wrote:
> On Sunday 15 August 2010 05:36:08 Andrei Alexandrescu wrote:
> > I very strongly suggest to stick with copying Boost's or C++0x's date and time facilities, unless we find some clearly superior ways facilitated by D's features. Developing our own date/time library from scratch risks of being at best just as capable as Boost/C++0x but guaranteed unfamiliar to everyone.
> 
> Okay. I've started looking at boost's date/time stuff, and they do appear to maintain time internally in UTC rather than converting it to local time, which was my biggest fear, since I've run into a lot of problems with that sort of thing in the past. So, overall, I'd say that it looks quite good (this _is_ boost after all).

Cool!


> I do have a few concerns, however.
> 
> 1. I'd argue that the boost date/time libraries are way too complex for normal usage. If you want to do detailed date/time stuff, they look incredibly flexible, but I'd be very worried that for the average case they're seriously overkill. I'd be worried that programmers looking for basic date/time functionality will quickly get lost in dealing with the full boost implementation and that they would do better to have a seriously simplified date/time facility without all of the bells and whistles. That's not to say that we shouldn't implement the boost stuff in Phobos, but I'd be concerned if it were the only date/time facility available.

When I first suggested we look at boost::date_time, I didn't really mean to suggest a complete port.  Date_time is huge, and full of things the average user will never need.  It will mean a lot of work, and as you say, we will end up with a pretty scary-looking date/time module.

My opinion is that instead of duplicating the whole shebang, we should:

a) Embrace its basic concepts.  For instance, I find the TimePoint/TimeDuration/TimeInterval separation quite intuitive and elegant:

http://www.boost.org/doc/libs/1_42_0/doc/html/date_time.html#date_time.conceptual


b). Pick a sensible subset of the boost:date_time functionality, and look at its code to figure out how it is best implemented.


> [...]
> 
> 3. Do you care whether the internals are the same or if the API is absolutely identical (or at least as identical as reasonably possible when going from C++ to D)? [...]

Personally, I certainly don't think having an identical API is a goal in itself.  D's standard library should have an API that is tailored to D, not C++.

-Lars

August 17, 2010



----- Original Message ----
> From: Jonathan M Davis <jmdavisprog at gmail.com>
> To: phobos at puremagic.com
> Sent: Tue, August 17, 2010 5:42:25 AM
> Subject: Re: [phobos] Status of std.gregorian
> 
> On Sunday 15 August 2010 05:36:08 Andrei Alexandrescu wrote:
> > Thanks for  your work, Jonathan. Our decision after the issue with Tango's date and  time was to use Boost's. I'd started std.gregorian as a seed of a port  of Boost's date and time, in the hope that someone will continue it.  Jeff Garland (Boost's date/time author) has been very supportive in the  matter.
> > 
> > I very strongly suggest to stick with copying Boost's  or C++0x's date and time facilities, unless we find some clearly  superior ways facilitated by D's features. Developing our own date/time  library from scratch risks of being at best just as capable as  Boost/C++0x but guaranteed unfamiliar to everyone.
> 
> Okay. I've  started looking at boost's date/time stuff, and they do appear to maintain  time internally in UTC rather than converting it to local time, which
>
> was my  biggest fear, since I've run into a lot of problems with that sort of thing  in the past. So, overall, I'd say that it looks quite good (this _is_ boost  after all). I do have a few concerns, however.
> 
> 1. I'd argue that the  boost date/time libraries are way too complex for normal
>
> usage. If you want  to do detailed date/time stuff, they look incredibly
>flexible,
>
> but I'd be  very worried that for the average case they're seriously overkill.

> I'd be  worried that programmers looking for basic date/time functionality will
>
> quickly get lost in dealing with the full boost implementation and that they would do better to have a seriously simplified date/time facility without  all
>of
>
> the bells and whistles. That's not to say that we shouldn't implement  the
>boost
>
> stuff in Phobos, but I'd be concerned if it were the only  date/time facility available.

I used boost::date_time a long time ago in a project where I needed timing facilities.  I found it to be quite unnecessarily complex, but it did work.  I personally like the C# time model better (same as Tango's), but clearly there is the desire to avoid looking at *all* like Tango's API, even if the author hasn't looked at it (no idea why that is).

I suggest not copying all the facilities, only the ones needed for gregorian calendar and dealing with time calculations.  Getting the current time is rather mundane boilerplate code, so copy if you wish, or rewrite from scratch, it will end up looking pretty much the same.

I can give you any advice you want as the developer of Tango's time modules, I just can't write any code.  I feel like after it is written, however, I can fix/improve the code that is written, since it's not Tango's base.

I would not generate the individual types for each unit (i.e. seconds, minutes, etc).  I would suggest representing the time in 100ns ticks as a long.  This gives a range of roughly 10,000 B.C. to 10,000 A.D. (with 0 being 1/1/01 A.D), and is the standard tick size used by Windows (and Tango, but I don't think they can claim ownership of this!).  Storing your time as a long makes all the math operations extremely easy, and should allow the compiler to inline most functions to simple instructions.

> 
> 2. We're looking at least 3 modules for  this - gregorian, local_time, and posix_time. Ideally, they'd be something  like std.time.gregorian, std.time.local_time, and std.time.posix_time, but  thus far we've avoided multiple levels of modules in the std hierarchy.  Depending on the implementation, having package level access between them  may be desirable (not
>
> having ported it all, I can't say for sure), and I  think that it's fair to say
>
> that we wouldn't want to give all of std  package-level access to the 3 of them
>
> (though hopefully package-level access  wouldn't be required). So, it needs to
>be
>
> decided whether we want the three  modules to be at a deeper level than std in

> the package hierarchy (and those  modules are likely to be _big_ even _without_
>
> solid unit tests - they're  split up quite a bit among source files in C++).

I never dealt with local_time.  I think one time module is enough, possibly two (std.time and std.gregorian).  I personally think local_time can be represented with UTC time with an offset, so I don't think it adds enough to warrant its own module.

> 3. Do you care whether  the internals are the same or if the API is absolutely

> identical (or at  least as identical as reasonably possible when going from C++
>
> to D)?  Already, looking at Date, I question the choice of maintaining its
>state
>
> as  the number of days rather than a separate year, month, and day. I've implemented a good chunk of it with year, month, day, and I think that the
>code
>
> is much cleaner that way. I also have to wonder why on earth they  picked 1400-01-01 as the oldest date possible since that seems arbitrarily  recent,
>and
>
> depending on why that is, it would seem desirable to me to make  it more
>flexible
>
> than that. In any case, I would hope that as long as the  API and functionality
>
> is correct that I wouldn't have to port over its  internals exactly, and I
>would
>
> hope that there wouldn't be a problem in  adding functionality if it seems obviously valuable. And of course, some of  it may make sense if the were made

> closer to how idiomatic D does things  (like possibly make time durations ranges).

Regarding the date starting point, I think it's simply an arbitrary decision. It's probably more based on how far in the future it can represent than how far in the past.  It's probably represented with a single value to make math easier.  I'd suggest having both a "point in time" struct which represents an exact point in time (including date, down to the smallest interval possible), and then have a struct to represent the date and time with fields.  Then provide converters between the two types.  Using a single value is better when doing things like measuring how long between two dates, and converting to/from OS date/times.  For example, if I'm just storing a point in time to use as a reference (for maybe implementing a UI timer or something), I don't want the library spending time converting fields to some value it can subtract.  Using split values is better for specifying exact date/time in the way humans are used to, so it makes for a good UI tool.  It also is able to represent more dates.

Regarding a direct port, I don't feel that way, do not be concerned with porting/copying the API exactly.  Use D facilities wherever possible.  Use your own ideas when you feel they are better.  Bounce ideas off the group, I think we have a pretty intelligent group here, and at least two of us (SHOO and myself) have already implemented date/time libraries.

-Steve




1 2
Next ›   Last »