Jump to page: 1 210  
Page
Thread overview
[phobos] datetime review
Oct 08, 2010
Jonathan M Davis
Oct 08, 2010
Sean Kelly
Oct 08, 2010
Yao G.
Oct 08, 2010
Walter Bright
Oct 08, 2010
Jonathan M Davis
Oct 09, 2010
Jonathan M Davis
Oct 09, 2010
Walter Bright
Oct 09, 2010
Jonathan M Davis
Oct 09, 2010
Walter Bright
Oct 09, 2010
Johannes Pfau
Oct 09, 2010
Jacob Carlborg
Oct 09, 2010
Denis
Oct 09, 2010
Jacob Carlborg
Oct 09, 2010
Jonathan M Davis
Oct 09, 2010
Denis
Oct 10, 2010
Jonathan M Davis
Oct 10, 2010
Denis
Oct 10, 2010
Yao G.
Oct 11, 2010
Yao G.
Oct 11, 2010
Yao G.
Oct 10, 2010
Philippe Sigaud
Oct 10, 2010
Walter Bright
Oct 10, 2010
David Simcha
Oct 10, 2010
Jonathan M Davis
Oct 09, 2010
Walter Bright
Oct 09, 2010
Walter Bright
Oct 09, 2010
Jonathan M Davis
Oct 09, 2010
Walter Bright
Oct 09, 2010
Michel Fortin
Oct 09, 2010
Jonathan M Davis
Oct 09, 2010
Sean Kelly
Oct 09, 2010
Sean Kelly
Oct 09, 2010
Walter Bright
[phobos] datetime review (new attempt at URL)
Oct 08, 2010
Jonathan M Davis
Oct 08, 2010
Sean Kelly
Oct 14, 2010
Denis
Oct 14, 2010
Michel Fortin
Oct 14, 2010
Jonathan M Davis
Oct 15, 2010
Jonathan M Davis
Oct 18, 2010
Jonathan M Davis
Oct 09, 2010
Simen Kjaeraas
Oct 09, 2010
Denis
Oct 09, 2010
Simen Kjaeraas
Oct 09, 2010
Simen Kjaeraas
Oct 10, 2010
Jonathan M Davis
Oct 10, 2010
Jonathan M Davis
Oct 10, 2010
Jonathan M Davis
Oct 10, 2010
Jonathan M Davis
Oct 10, 2010
Jonathan M Davis
Oct 10, 2010
Michel Fortin
Oct 11, 2010
Jonathan M Davis
Oct 12, 2010
Michel Fortin
Oct 12, 2010
Jonathan M Davis
Oct 12, 2010
Michel Fortin
Oct 12, 2010
Jonathan M Davis
Oct 14, 2010
Jonathan M Davis
Oct 14, 2010
Jonathan M Davis
Oct 15, 2010
Jonathan M Davis
Oct 12, 2010
Michel Fortin
Oct 12, 2010
Yao G.
Oct 12, 2010
Michel Fortin
Oct 12, 2010
Jonathan M Davis
Oct 13, 2010
Michel Fortin
Oct 13, 2010
Jonathan M Davis
Oct 12, 2010
Jonathan M Davis
Oct 12, 2010
Michel Fortin
Oct 11, 2010
Jonathan M Davis
Oct 10, 2010
Jonathan M Davis
Oct 10, 2010
Jonathan M Davis
Oct 11, 2010
Brad Roberts
[phobos] datetime review (Question about SysTime and immutability)
Oct 15, 2010
Jonathan M Davis
October 08, 2010
Okay. Here is my current datetime code for review. It's not 100% done, but I think that it's ready to be reviewed. The one part that is not yet complete is the PosixTimeZone and WindowsTimeZone classes which allow you to get TimeZone objects for arbitrary time zones by name on Posix and Windows systems respectively. It's functionality that I definitely think should be in std.datetime, but it's not necessary for most programs, and this project has already taken me far longer than I ever anticipated, so it seems prudent to present my code with PosixTimeZone and WindowsTimeZone stubbed out (but everything else being complete) and finish them later. If the review process takes long enough, I may have them done before it's over anyway.

There are several TODO comments in the code which mark functionality which probably should be added at some point, but it's not core functionality, and I never intended to implement any of it before submitting my code for review (for instance, it would be useful to implement date recurrence patterns and be able to create ranges out of them - useful, but hardly core functionality and potentially very time-consuming to implement).

My code is based on Boost's API, but it isn't exactly the same and expands on it a fair bit, and none of the implementation is from Boost. It's also been properly D-ified, with it being highly generic and having ranges and the like. Since the module was pushing 40,000 lines, I split it into separate modules in a single package:

* datetime.all: Has a description for the package as a whole and publicly imports all of the other modules in datetime. Ideally, you'd just import datetime.all rather than trying to selectively import the other modules.

* datetime.core: Contains types and functions which are used by most of the other modules in datetime (e.g. the enum TUnit which hold the various units of time: year, hour, second, etc.).

* datetime.duration: Contains the various duration types.

* datetime.interval: Contains the various interval and range types.

* datetime.other: Contains stuff that doesn't fit in in any of the other modules.

* datetime.timepoint: Contains the various time point types. It also contains Clock, which will give you the current time.

* datetime.timezone: Contains the various time zone classes which SysTime uses.


Rather than Boost's date, ptime, and localtime, I have Date, TimeOfDay, DateTime, and SysTime.

* Date holds a Gregorian date as year, month, and day and is optimized for calendar operations. It has a range of approximately 32,000 BC to 32,000 AD.

* TimeOfDay holds hour, minute, and second.

* DateTime holds a Date and a TimeOfDay to have a date with the time. It's optimized for calendar operations and has no concept of time zone.

* SysTime is intended to be the time type to deal with time from the OS. It is more or less a combination of Boost's ptime and localtime. It holds the date/time in hecto-nanoseconds (100 ns) from midnight January 1st, 1 AD UTC and has a TimeZone object as part of it so that its getters can convert the time to that time zone. However, its internal time is always in UTC, thereby avoiding conversion errors due to DST. Its constructors default to using the LocalTime TimeZone object, so if you don't want to worry about time zones, you don't have to. The Clock object allows you to get a SysTime with the current time in local time, UTC, or any other time zone that you give it. SysTime has a range of approximately 29,000 BC to 29,000 AD.


One of the major changes from Boost is that I dropped special time points - that is positive infinity, negative infinity, and invalid (e.g. not-a-date). They complicated the code considerably and their only benefit, as far as I can tell, is to aid in defining infinite intervals and ranges. And since infinite ranges in D need to be known as infinite at compile time, it's not possible to define infinite ranges based on their end points (which are known at runtime). So, I just defined interval and range types which were infinite (in addition to the finite ones) and dropped the special time points.

Another major change is that all duration, interval, and range types (rather than iterator types) are generic and are intended to work with pretty much any time point instead of being specific to particular time point type (though there are some restrictions due to the fact that you can't convert between months/years and smaller time units due to the variable number of days in a month and year). Also, ranges are defined based on delegates, so they are extremely flexible.

I have already integrated SHOO's code from the nascent std.datetime with minimal alterations. Ticks became TickDuration and was put in datetime.duration. systime and apptime became Clock.currSystemTicks and Clock.currAppTicks respectively and were put in datetime.timepoint. The rest is in datetime.other (which is painfully small, but what's there doesn't really fit in in any of the other modules; however, it may grow when additional functionality is added, and it seems to me that the fact that the intended use is to just import datetime.all makes the small module less of an issue).

I didn't make much of an attempt to make my code use @safe, @trusted, or @system, since making that work is definitely a pain at the moment. std.array, std.algorithm, std.range, and std.conv (at minimum) really should be made to use them first. I did try and use const, nothrow, and pure liberally, though with the current purity rules, a lot of functions which should be pure can't be (though the svn version of dmd should do better), and bug http://d.puremagic.com/issues/show_bug.cgi?id=4974 doesn't help either.


I have included my src files as well as the ddoc html files generated from them. In addition to datetime, I have included a unittests module which I use heavily in my unit tests (and makes them much more pleasant). I'd love it if some version of that got into Phobos as well. My code has extensive unit tests and should be fully documented, so bugs should be few and far between (though I'm not about to claim that my code is bug-free).

The code: https://docs.google.com/leaf?id=0B- f1J0HiG2ovYmMzYWVkODMtODRiYi00NTg4LWI4MDctOTQ0MjE4YTI5Y2U1&sort=name&layout=list&num=50

(the hyphen after the B is part of the link; I wish that I could get my client to wrap the normal lines but not the link...)

- Jonathan M Davis


P.S. If anyone can figure out how  to make SysTime work as immutable, I'd really appreciate it. It holds a long value and an immutable TimeOfDay object in a Rebindable struct, so it should be able to be immutable, but I can't seem to get it to work, and I had to comment out all of my unit tests that verify that immutable SysTimes work.

Also, if anyone could tell me what the default directories for the time zone files on FreeBSD and OSX are, that would be very useful. It's /usr/shar/zoneinfo on Linux, but I have no idea where they are on FreeBSD or OSX.
October 08, 2010
On Oct 8, 2010, at 2:04 PM, Jonathan M Davis wrote:
> 
> The code: https://docs.google.com/leaf?id=0B- f1J0HiG2ovYmMzYWVkODMtODRiYi00NTg4LWI4MDctOTQ0MjE4YTI5Y2U1&sort=name&layout=list&num=50

"Sorry, the page (or document) you have requested is not available."

> (the hyphen after the B is part of the link; I wish that I could get my client to wrap the normal lines but not the link...)

This will only work if you send a formatted message.  The mail protocol requires lines to be wrapped at ~75 characters.
October 08, 2010
On Fri, 08 Oct 2010 16:04:58 -0500, Jonathan M Davis <jmdavisProg at gmx.com> wrote:


> The code: https://docs.google.com/leaf?id=0B- f1J0HiG2ovYmMzYWVkODMtODRiYi00NTg4LWI4MDctOTQ0MjE4YTI5Y2U1&sort=name&layout=list&num=50
>
> (the hyphen after the B is part of the link; I wish that I could get my
> client
> to wrap the normal lines but not the link...)
>
> - Jonathan M Davis

Use a URL shortener:

- http://bit.ly
- http://is.gd/
- http://goo.gl/

etc...

-- 
Yao G.
October 08, 2010
I know you've worked hard on this, and I apologize for coming off sounding a bit grumpy about things.

Jonathan M Davis wrote:
>
> * datetime.core: Contains types and functions which are used by most of the other modules in datetime (e.g. the enum TUnit which hold the various units of time: year, hour, second, etc.).
>
> * datetime.duration: Contains the various duration types.
>
> * datetime.interval: Contains the various interval and range types.
>
> 
[...]
> * datetime.timepoint: Contains the various time point types. It also contains Clock, which will give you the current time.
>
> * datetime.timezone: Contains the various time zone classes which SysTime uses.
>
> 

It bothers me that there are so many types, i.e. "various duration types", "various interval types", etc.

Now that I read that again, why is there both a "duration" and an "interval"?

Why are there multiple "various time zone classes" instead of "a" time zone class?

Does handling time really merit seven modules?

> The code: https://docs.google.com/leaf?id=0B-f1J0HiG2ovYmMzYWVkODMtODRiYi00NTg4LWI4MDctOTQ0MjE4YTI5Y2U1&sort=name&layout=list&num=50

Argh, I have to create Yet Another Account just to look at the code. I apologize if my comments are answered in the code source.



October 08, 2010
Okay. Hopefully this URL works:

http://is.gd/fS35q
October 08, 2010
Yup.

On Oct 8, 2010, at 2:59 PM, Jonathan M Davis wrote:

> Okay. Hopefully this URL works:
> 
> http://is.gd/fS35q
> _______________________________________________
> phobos mailing list
> phobos at puremagic.com
> http://lists.puremagic.com/mailman/listinfo/phobos

October 08, 2010
On Friday, October 08, 2010 14:58:35 Walter Bright wrote:
> I know you've worked hard on this, and I apologize for coming off sounding a bit grumpy about things.
> 
> Jonathan M Davis wrote:
> > * datetime.core: Contains types and functions which are used by most of the other modules in datetime (e.g. the enum TUnit which hold the various units of time: year, hour, second, etc.).
> > 
> > * datetime.duration: Contains the various duration types.
> > 
> > * datetime.interval: Contains the various interval and range types.
> 
> [...]
> 
> > * datetime.timepoint: Contains the various time point types. It also contains Clock, which will give you the current time.
> > 
> > * datetime.timezone: Contains the various time zone classes which SysTime uses.
> 
> It bothers me that there are so many types, i.e. "various duration types", "various interval types", etc.
> 
> Now that I read that again, why is there both a "duration" and an "interval"?

A duration is a length of time with units while an interval is two time points (or a time point and a duration) which therefore designate a duration which is fixed in time. So, they are distinct (the concepts are from Boost). There are multiple duration types primarily because you can't convert between months and small units without a specific date, so you can't convert something like 5 months to days without knowing which months you're dealing with. However, I have definite worked on making it so that you don't have to worry about the multiple duration types in most cases. You'd do something like Dur.years(5) + Dur.days(2) to create a duration of 5 years and 2 days, and you don't have to know or care what the duration types are.

There are multiple interval types only to deal with infinity. You have Interval, with a definite begin and end, PosInfInterval which goes from a specific time point to infinity, and NegInfInterval which goes from negative infinity to a specific time point. The infinite intervals are primarily of interest in creating infinite ranges. A lot of user code could simpler ignore them.

> 
> Why are there multiple "various time zone classes" instead of "a" time zone class?

There are multiple time zone classes because it uses polymorphism to deal with the rules for a given time zone. The really basic LocalTime and UTC deal with most cases, but for anyone who really needs to deal with multiple time zones, PosixTimeZone and WindowsTimeZone will be invaluable (I'd love to only have one of those, but Windows just doesn't deal with time zones like the Posix world does).

> Does handling time really merit seven modules?

It was one until just the other day, but it was just too many lines of code for a single module. Ideally, you'd just import datetime.all and you wouldn't have to deal with importing individual modules (though unfortunately, there isn't presently any way to combine the documentation in that manner).

Overall, I don't think that it's all that complicated, but it's a lot of code, and it's definitely the case that some of it will not be needed in the average application, but having it would be extremely useful. The generic nature of much of the code reduces how much you really have to worry about too.

However, the proper dealing of dates and times can get pretty complicated (the C API can't even dream of coming close to covering what a real date/time library should cover), so any serious date/time library is not going to be a small, simple module. I have done my best to make what I've done both simple and flexible, but there is a lot of it.

The real question is whether I've managed to make something which is both easily useable for the average application which doesn't care about much beyond getting the current time and yet still gives applications which really care about manipulating dates and times the features and capabilities that they need.

> 
> > The code: https://docs.google.com/leaf?id=0B-f1J0HiG2ovYmMzYWVkODMtODRiYi00NTg4LWI 4MDctOTQ0MjE4YTI5Y2U1&sort=name&layout=list&num=50
> 
> Argh, I have to create Yet Another Account just to look at the code. I apologize if my comments are answered in the code source.

You shouldn't need to create an account. It should be accessible without any type of account. If you need an account, I screwed up. The short URL is http://is.gd/fS35q . I originally just attached the code to the e-mail, but Brad asked me to just post a link to it. Google docs was the best that I could come up with.

- Jonathan M Davis
October 08, 2010
I should probably add that the seven modules aren't exactly equal in size. In particular datetime.all only has its module documentation and public imports for all of the other modules, and datetime.other is quite small. I didn't necessarily split the code into modules in the best manner. I split it more on concepts than the amount of code in them (so datetime.timepoint probably has close to half of the code in it). I'm open to suggestions if someone has a better way to split the code up. Ideally, it would all be in one module, but it was too much for one.

Also, as much as there is, a large portion of it is unit tests and documentation. There's definitely more unit tests than normal code, and there might be more documentation than normal code.

One point that may need to be improved is the module documentation so that it's more obvious exactly what you need to just get the time and print it out or whatever the insanely simple operations are that would be typical in your average program that does little with the time. I am afraid that it is a bit like std.algorithm in that it's quite easy to use but a bit overwhelming to look at so that you _think_ that it's hard to use, even though it really isn't. I do have quite a few examples it the code though, and I hope that the documentation is generally clear enough. I tried to make it so that it was, but it really needs to have people who aren't familiar with it judge it at this point.

- Jonathan M Davis
October 08, 2010

Jonathan M Davis wrote:
>
> You shouldn't need to create an account. It should be accessible without any type of account. If you need an account, I screwed up. The short URL is http://is.gd/fS35q . I originally just attached the code to the e-mail, but Brad asked me to just post a link to it. Google docs was the best that I could come up with.
>
> 

I agree that Brad has the right idea with that. Thanks for doing this.
October 08, 2010

Jonathan M Davis wrote:
> I should probably add that the seven modules aren't exactly equal in size. In
> particular datetime.all only has its module documentation and public imports for
> all of the other modules, and datetime.other is quite small. I didn't
> necessarily split the code into modules in the best manner. I split it more on
> concepts than the amount of code in them (so datetime.timepoint probably has
> close to half of the code in it). I'm open to suggestions if someone has a
> better way to split the code up. Ideally, it would all be in one module, but it
> was too much for one.
> 

I agree that modules should be organized by concept rather than size. But also, I don't know of a rule that says a module is "too large", unless that module contains concepts that are independent of each other and that users will rarely require both at the same time.

Remember, if a module's implementation code is large, it can be split into a .di/implementation pair, rather than into multiple modules.

> Also, as much as there is, a large portion of it is unit tests and documentation. There's definitely more unit tests than normal code, and there might be more documentation than normal code.
>
> One point that may need to be improved is the module documentation so that it's more obvious exactly what you need to just get the time and print it out or whatever the insanely simple operations are that would be typical in your average program that does little with the time. I am afraid that it is a bit like std.algorithm in that it's quite easy to use but a bit overwhelming to look at so that you _think_ that it's hard to use, even though it really isn't. I do have quite a few examples it the code though, and I hope that the documentation is generally clear enough. I tried to make it so that it was, but it really needs to have people who aren't familiar with it judge it at this point.
>
> - Jonathan M Davis
> _______________________________________________
> phobos mailing list
> phobos at puremagic.com
> http://lists.puremagic.com/mailman/listinfo/phobos
>
>
> 
« First   ‹ Prev
1 2 3 4 5 6 7 8 9 10