www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Replacement for/alternative to std.date?

reply Stewart Gordon <smjg_1998 yahoo.com> writes:
Just looking at std.date, and noticing that
- it isn't object-oriented
- it isn't exactly complete
- its way of dealing with time zones leaves something to be desired

I reckon one of us ought to come up with a good date/time type for D. 
Has anyone written one already?

Things I feel such a type should support:

- construction by components (obviously)

- properties to set/get component values (obviously) (dealing with 
out-of-range values is a matter for debate)

- date/time arithmetic

- time zone information in the date object itself, and conversions 
between time zones

- time zone offset specifiable in minutes, allowing for the half-hour 
and even quarter-hour time zones that exist (and possibly more exotic, 
finer offsets)

- conversion to/from human-readable date/time strings, in a standard 
format and in the display date/time format specified in the OS configuration

- a struct representation that can be read/written from/to a file 
(either as date only, time only or both)

- possibly conversion to/from d_time, for the purposes it may continue 
to serve

- the option of specifying only a date, or only a time, if that's what's 
desired

....

Stewart.

-- 
My e-mail is valid but not my primary mailbox, aside from its being the 
unfortunate victim of intensive mail-bombing at the moment.  Please keep 
replies on the 'group where everyone may benefit.
Jul 05 2004
next sibling parent reply Benji Smith <dlanguage xxagg.com> writes:
On Mon, 05 Jul 2004 12:10:31 +0100, Stewart Gordon
<smjg_1998 yahoo.com> wrote:
Things I feel such a type should support:
...let me add to that: * Recognition of various system epochs (I'd love to be able to get a date value, as an offset from the UNIX epoch, even when I'm on a Windows system). * Ability to toggle on/off daylight savings time adjustments for any given date object, based on its locale.
Jul 05 2004
parent reply Stewart Gordon <smjg_1998 yahoo.com> writes:
Benji Smith wrote:
<snip>
 * Recognition of various system epochs (I'd love to be able to get a 
 date value, as an offset from the UNIX epoch, even when I'm on a 
 Windows system).
Yes, there are various date numbering systems. Unix epochs, at least two systems of Excel dates, Julian dates, the list goes on. But yes, supporting them would be a step forward.
 * Ability to toggle on/off daylight savings time adjustments for any 
 given date object, based on its locale.
Yes, we could start to list every time locale (combination of standard time offset and DST formula) on the planet, and use it for this. Stewart. -- My e-mail is valid but not my primary mailbox, aside from its being the unfortunate victim of intensive mail-bombing at the moment. Please keep replies on the 'group where everyone may benefit.
Jul 06 2004
parent reply Charles Hixson <charleshixsn earthlink.net> writes:
Stewart Gordon wrote:
 Benji Smith wrote:
 <snip>
 
 ...
Yes, we could start to list every time locale (combination of standard time offset and DST formula) on the planet, and use it for this. Stewart.
How about using a 64 bit (128bit?) integer and listing milliseconds (microseconds), +/- since 2004/01/01? Nice, straightforwards, easy to work with, reasonably compact...the only problem is converting it to a date that anyone else could understand. And then there's the leap second problem...yes, conversion to standard time might be difficult, if you wanted accuracy closer than a minute. (Over a period of a few centuries.) Now SETTING it to the implied accuracy...THAT might be a challenge.
Jul 08 2004
parent reply Stewart Gordon <smjg_1998 yahoo.com> writes:
Charles Hixson wrote:

<snip>
 How about using a 64 bit (128bit?) integer and listing milliseconds 
 (microseconds), +/- since 2004/01/01?  Nice, straightforwards, easy to 
 work with, reasonably compact...the only problem is converting it to a 
 date that anyone else could understand.  And then there's the leap 
 second problem...yes, conversion to standard time might be difficult, if 
 you wanted accuracy closer than a minute. (Over a period of a few 
 centuries.)
 
 Now SETTING it to the implied accuracy...THAT might be a challenge.
Internal date representations come in two basic kinds: numerical and structured. One of my ideas is to have 10 bytes: 4 for date (structured), 4 for time (milliseconds) and 2 for time zone. That would allow for straightforward date manipulations, and a compact format for the time component (which is much simpler to deal with than dates, so I suppose we can get away with it). Stewart. -- My e-mail is valid but not my primary mailbox, aside from its being the unfortunate victim of intensive mail-bombing at the moment. Please keep replies on the 'group where everyone may benefit.
Jul 09 2004
parent reply Arcane Jill <Arcane_member pathlink.com> writes:
In article <cclpt4$1sv6$1 digitaldaemon.com>, Stewart Gordon says...
Internal date representations come in two basic kinds: numerical and 
structured.

One of my ideas is to have 10 bytes: 4 for date (structured), 4 for time 
(milliseconds) and 2 for time zone.  That would allow for 
straightforward date manipulations, and a compact format for the time 
component (which is much simpler to deal with than dates, so I suppose 
we can get away with it).
I would imagine it would simplify things enormously if you dispensed with the time zone field and simply decreed that all dates were to be stored internally in UTC. You would then need to worry about timezones only on creation and extraction - not during date comparisons or manipulations. This would also mean that you also wouldn't have to worry about daylight saving times, except during creation and extraction. (I didn't see any mention of DST in your above description, by the way. I assume this was an oversight). In addition, Charles Hixon mentioned the problem of leap seconds. He is correct. You /will/ need to worry about this - if you want to be accurate. Unless of course, you want to store your time information in TAI (International Atomic Time) instead of UTC (Coordinated Universal Time). TAI does not have leap seconds, but can differ from UTC by an integral number of seconds. You might find you need to structure your time field as well as your date field, for reasons such as this! Of course, no other computer language gets this right, so there's plenty of precedent for pretending that a tropical year is an integral number of seconds for computational convenience. (As if!) But that doesn't make it correct. Arcane Jill
Jul 09 2004
parent reply Stewart Gordon <smjg_1998 yahoo.com> writes:
Arcane Jill wrote:

<snip>
 I would imagine it would simplify things enormously if you dispensed with the
 time zone field and simply decreed that all dates were to be stored internally
 in UTC. You would then need to worry about timezones only on creation and
 extraction - not during date comparisons or manipulations.
Manipulations frequently include manipulation of local times, including DST adjustments. E.g. in calendar applications.
 This would also mean that you also wouldn't have to worry about daylight saving
 times, except during creation and extraction. (I didn't see any mention of DST
 in your above description, by the way. I assume this was an oversight).
 
 In addition, Charles Hixon mentioned the problem of leap seconds. He is
correct.
 You /will/ need to worry about this - if you want to be accurate. Unless of
 course, you want to store your time information in TAI (International Atomic
 Time) instead of UTC (Coordinated Universal Time). TAI does not have leap
 seconds, but can differ from UTC by an integral number of seconds. You might
 find you need to structure your time field as well as your date field, for
 reasons such as this!
<snip> Leap seconds are irregular, so they'd need to be either specified by the individual programmer or we'd need to frequently update the module. A typical desktop computer has even less idea when they occur (except possibly under certain network time servers) so trying to adjust to timing across it would seem fruitless anyway. For that matter, are there many practical applications rely on that leap second? As you say, just carrying the time in UTC would simplify things. Stewart. -- My e-mail is valid but not my primary mailbox, aside from its being the unfortunate victim of intensive mail-bombing at the moment. Please keep replies on the 'group where everyone may benefit.
Jul 09 2004
parent Arcane Jill <Arcane_member pathlink.com> writes:
In article <ccltm8$22i4$1 digitaldaemon.com>, Stewart Gordon says...

Manipulations frequently include manipulation of local times, including 
DST adjustments.  E.g. in calendar applications.
Obviously, but by storing dates internally in timezone-independent form would simplify things greatly. UTC is timezone-independent.
Leap seconds are irregular,
So is DST, but I don't hear anyone suggesting we ignore that. (See my next paragraph).
so they'd need to be either specified by the 
individual programmer or we'd need to frequently update the module.
Not that frequently. You could pull leap second information off the internet easily enough (the US Navy maintain pretty good tables), and once a year should be sufficient. A table of historic leap seconds and the NTP time when each occurred is available via FTP from any NIST NTP server. You're going to have to do that ANYWAY to get daylight saving time information. For example, DST in the UK is defined by an act of parliament. Current legislation defines DST here only up to the year 2007. Beyond that, we have to wait for the next act of parliament. I don't know the situation in other parts of the world, but I imagine the rules are similar.
A typical desktop computer has even less idea when they occur
Isn't that just because of limitations of existing date functions?
For that matter, are 
there many practical applications rely on that leap second?
Astronomy? Counting down to a New Year party? Seriously - the Unix world is cottoning on to this. ISO C 200X proposes a new <time.h> which addresses the leap second question - see http://www.cl.cam.ac.uk/~mgk25/time/c/. Maybe once upon a time clocks weren't accurate enough to worry about it, but they are now, and a language of the future would be seriously dumb to ignore it. And - (this is completely obvious if you think about it) - those seconds ACCUMULATE. It may only be one or two seconds a year, but over time, they will add up.
As you say, 
just carrying the time in UTC would simplify things.
I think you must have misread me. UTC /DOES/ have leap seconds. Carrying the time in UTC would mean that you /DO/ have to worry about them. It's TAI that doesn't. Calculations would be simpler in TAI, of course, but civil time is based on UTC, not on TAI. Getting dates right is hard work - but that, of course, is why it would be good to have a library class that gets it right. Otherwise we'd all be rolling our own, over and over again. Jill
Jul 09 2004
prev sibling next sibling parent reply Arcane Jill <Arcane_member pathlink.com> writes:
In article <ccbcv8$1lpt$1 digitaldaemon.com>, Stewart Gordon says...
Just looking at std.date, and noticing that
- it isn't object-oriented
- it isn't exactly complete
- its way of dealing with time zones leaves something to be desired
Going back to this original post... I realise that some of later replies may have focused to heavily on how hard it is to get this right, and that that was perhaps not the best thing for me to have said, because it could be seen as discouragement. I suppose, in my mind, I want D to reach for the stars, to lead the field, not to trail behind other rivals. But I should instead have been more encouraging. Yes, there is room for improvement in std.date. If someone were to write something better, I don't think anyone would complain. As D advances, I think we are going to see /many/ of our "old favorites" in std.whatever get superceded by superior alternatives. And these in turn may be superceded yet again. At this early stage in D's development, I do believe we should encourage such progress.
I reckon one of us ought to come up with a good date/time type for D. 
Has anyone written one already?
Not in D, but in C++ many, many times. And each time differently - and I only ever wrote in the functionality that I, personally, needed, and no more. I suspect lots of other people have done the same. Why? Because existing date functionality on many platforms is not that good. And of course, it was DST that I found hardest of all. Where do you get all that information for every locale in the world and for every year, past, present and future? But anyway - here are my thoughts, if someone should care to code them up. This is a general idea, which may be improved upon over time without having to go back and rewrite everything. Stuff like DST and leap-seconds can be added later, without breaking the API. I envisage at least TWO classes/structs. One - (probably called Date) - represents a single instant in time. It doesn't matter what that instant is /called/, it only matters that two Dates compare equal if and only if they represent the same instant in time. Dates should also be comparable with each other using opCmp. Two - a class/struct (probably called either DateDiff or Interval) - which represent the difference between two dates. Like Date itself, the internal format is irrelevant, only the API matters. Operator overloads should do the expected thing. A Date plus a DateDiff gives another Date. Subtracting a Date from a Date gives a DateDiff. Both Date and DateDiff have functions to do various conversions. I hope someone takes this up, as it would be a really good thing to have.
Things I feel such a type should support:

- construction by components (obviously)

- properties to set/get component values (obviously) (dealing with 
out-of-range values is a matter for debate)

- date/time arithmetic
Yes.
- time zone information in the date object itself, and conversions 
between time zones
This is the part with which I disagree. If a Date represents a specific instant in time then it HAS no time-zone. It is just a moment in time. For example, in Jill's scheme, if a user in France and a user in America both constructed a Date object to represent the instant in time when Neil Armstrong first set foot on the moon, those two objects would compare equal. Timezone is not relevant. If either or both of these passed such an object to a user in Japan, they would be able to extract from it the Japanese local time which represents that instant. Timezone is a conversion problem. You need to know it when you CONSTRUCT a Date, and you need to know the timezone for which you require information when you EXTRACT infomation from a Date, but you don't need to store timezone information IN a Date.
- time zone offset specifiable in minutes, allowing for the half-hour 
and even quarter-hour time zones that exist (and possibly more exotic, 
finer offsets)
A TimeZone class/struct wouldn't be a bad idea then, but again, there is no need to store a timezone inside a Date. That's confusing two concepts.
- conversion to/from human-readable date/time strings, in a standard 
format and in the display date/time format specified in the OS configuration

- a struct representation that can be read/written from/to a file 
(either as date only, time only or both)

- possibly conversion to/from d_time, for the purposes it may continue 
to serve

- the option of specifying only a date, or only a time, if that's what's 
desired
I hope someone takes this up. With the concept I've suggested, and the feature list that Stewart has suggested, this would be a marvellous thing. Extra goodies like proper DST/leap second support could then always be added later, without breaking anything. Jill
Jul 10 2004
parent reply Stewart Gordon <smjg_1998 yahoo.com> writes:
Arcane Jill wrote:

<snip>
 This is the part with which I disagree. If a Date represents a specific instant
 in time then it HAS no time-zone. It is just a moment in time. For example, in
 Jill's scheme, if a user in France and a user in America both constructed a
Date
 object to represent the instant in time when Neil Armstrong first set foot on
 the moon, those two objects would compare equal. Timezone is not relevant. If
 either or both of these passed such an object to a user in Japan, they would be
 able to extract from it the Japanese local time which represents that instant.
Comparing equal and being identical internally aren't the same thing. But yes, you have a point.
 Timezone is a conversion problem. You need to know it when you CONSTRUCT a
Date,
 and you need to know the timezone for which you require information when you
 EXTRACT infomation from a Date, but you don't need to store timezone
information
 IN a Date.
<snip> Yes, I suppose you have a good idea there. Of course we should have a means of selecting the time zone in which these functions are carried out, which would obviously default to the user's local time zone. Stewart. -- My e-mail is valid but not my primary mailbox, aside from its being the unfortunate victim of intensive mail-bombing at the moment. Please keep replies on the 'group where everyone may benefit.
Jul 12 2004
parent reply Arcane Jill <Arcane_member pathlink.com> writes:
In article <ccu396$1q3o$1 digitaldaemon.com>, Stewart Gordon says...
Arcane Jill wrote:

Yes, I suppose you have a good idea there.  Of course we should have a 
means of selecting the time zone in which these functions are carried 
out, which would obviously default to the user's local time zone.
I think you're right too. I mean, we're both right. I think you're talking about expressing partial information about a date. You mentioned being able to express a date without a time, or a time without a date. Or - other examples spring to mind immediately - a day, month and year, but with calendar (Gregorian or Julian) unspecified. So I think we need your idea too. Let's call this concept a PartialDate (well, feel free to come up with a better idea). This stores structured information about a date, such a human might use, but doesn't actually refer to an instant in time. To turn a PartialDate into a Date, you'd need to either supply the missing parts, or pass to a function that used some magic defaults. I think a "best of both worlds" approach would be pretty cool, actually, Jill
Jul 12 2004
parent Jonathan Leffler <jleffler earthlink.net> writes:
Arcane Jill wrote:
 In article <ccu396$1q3o$1 digitaldaemon.com>, Stewart Gordon says...
Arcane Jill wrote:
Yes, I suppose you have a good idea there.  Of course we should have a 
means of selecting the time zone in which these functions are carried 
out, which would obviously default to the user's local time zone.
I think you're right too. I mean, we're both right. I think you're talking about expressing partial information about a date. You mentioned being able to express a date without a time, or a time without a date. Or - other examples spring to mind immediately - a day, month and year, but with calendar (Gregorian or Julian) unspecified. So I think we need your idea too. Let's call this concept a PartialDate (well, feel free to come up with a better idea). This stores structured information about a date, such a human might use, but doesn't actually refer to an instant in time. To turn a PartialDate into a Date, you'd need to either supply the missing parts, or pass to a function that used some magic defaults. I think a "best of both worlds" approach would be pretty cool, actually,
There have been rather extensive discussions on how to improve on the standard C libraries for date and time handing in the comp.std.c news group, over a period of years in total. Two links at Google, via Tiny URL, are: More recent - June-July 2004 http://tinyurl.com/6cy94 Less recent - February-April 2002 http://tinyurl.com/5peb9 -- main thread http://tinyurl.com/6eagz -- first side thread http://tinyurl.com/4wtr4 -- second side thread http://david.tribble.com/text/c0xcalendar_1.html http://david.tribble.com/text/c0xcalendar.html http://david.tribble.com/text/c0xtimet.htm http://david.tribble.com/text/c0xlongtime.html http://www.calendarists.com/ I have a bunch of URLs for other more or less relevant web sites discussing many of the issues. At the very least, people designing a system for D should be aware of the issues facing other languages - and be grateful for the lack of legacy code to hamper getting your changes accepted. -- Jonathan Leffler #include <disclaimer.h> Email: jleffler earthlink.net, jleffler us.ibm.com Guardian of DBD::Informix v2003.04 -- http://dbi.perl.org/
Jul 12 2004
prev sibling next sibling parent reply Stewart Gordon <smjg_1998 yahoo.com> writes:
I've now got an idea I think I'm going to try and code up.  (That is, if 
I don't end up discarding this one for another one as I have been doing 
for the last however long.)

Two structs, DateValue and TimeValue, will each wrap a 32-bit integer 
representing a date and a UTC time respectively, and provide operations 
on them.

A third struct, DateTime, would combine these values and provide 
operations that rely on the combination (as local time manipulation 
nearly always does).

Operations that get/set components would work in local time, which would 
default to the user's time zone but be globally settable.

Further types could represent intervals of time on a similar basis.

This system would, I believe, make it fairly straightforward to add 
improvements such as DST adjustment and leap seconds at some later date.

As an extra, we could have a struct of the date/time components (of 
which some may be 'blank'), and conversions between this and the 
aforementioned types.

What does everyone think?

Stewart.

-- 
My e-mail is valid but not my primary mailbox, aside from its being the 
unfortunate victim of intensive mail-bombing at the moment.  Please keep 
replies on the 'group where everyone may benefit.
Jul 14 2004
next sibling parent reply pragma <EricAnderton at yahoo dot com> <pragma_member pathlink.com> writes:
In article <cd3mj8$2cai$1 digitaldaemon.com>, Stewart Gordon says...
I've now got an idea I think I'm going to try and code up.  (That is, if 
I don't end up discarding this one for another one as I have been doing 
for the last however long.)

Two structs, DateValue and TimeValue, will each wrap a 32-bit integer 
representing a date and a UTC time respectively, and provide operations 
on them.

A third struct, DateTime, would combine these values and provide 
operations that rely on the combination (as local time manipulation 
nearly always does).

Operations that get/set components would work in local time, which would 
default to the user's time zone but be globally settable.

Further types could represent intervals of time on a similar basis.

This system would, I believe, make it fairly straightforward to add 
improvements such as DST adjustment and leap seconds at some later date.

As an extra, we could have a struct of the date/time components (of 
which some may be 'blank'), and conversions between this and the 
aforementioned types.

What does everyone think?
I love this idea Stewart. :) Are you going to include a 'free-format' function as well as explicit methods? // future example? DateValue dv = new DateValue(someTimeUint); writefln("The date is: %s",dv.format("MM/DD/YYYY")); TimeValue tv = new TimeValue(someTimeUint); writefln("The time is: %d:%d:%d",dt.hours(),dt.minutes(),dt.seconds()); - Pragma
Jul 14 2004
parent reply Stewart Gordon <smjg_1998 yahoo.com> writes:
pragma <EricAnderton at yahoo dot com> wrote:

<snip>
 Are you going to include a 'free-format' function as well as explicit methods?
 
 // future example?
 DateValue dv = new DateValue(someTimeUint);
 writefln("The date is: %s",dv.format("MM/DD/YYYY"));
Good question. I guess it's a matter of how useful it would be over the OS format and what can be done with writef.
 TimeValue tv = new TimeValue(someTimeUint);
 writefln("The time is: %d:%d:%d",dt.hours(),dt.minutes(),dt.seconds());
dt? Stewart. -- My e-mail is valid but not my primary mailbox, aside from its being the unfortunate victim of intensive mail-bombing at the moment. Please keep replies on the 'group where everyone may benefit.
Jul 14 2004
parent reply pragma <EricAnderton at yahoo dot com> <pragma_member pathlink.com> writes:
In article <cd3s07$2l0c$1 digitaldaemon.com>, Stewart Gordon says...
pragma <EricAnderton at yahoo dot com> wrote:

<snip>
 Are you going to include a 'free-format' function as well as explicit methods?
 
 // future example?
 DateValue dv = new DateValue(someTimeUint);
 writefln("The date is: %s",dv.format("MM/DD/YYYY"));
Good question. I guess it's a matter of how useful it would be over the OS format and what can be done with writef.
(Stewart, I hope you don't mind me expanding on your concept BTW, as I have a few more ideas regarding dates in D myself.) The only reason why I bring up string-based formatting of dates is because, sooner or later, you're going to want to generate a string representation of a date without wrangling a huge lump of code. This is just like how printf/writef is more useful (if not clearer) than streams in some cases. IMO, Anything that follows the same formatting conventions as PHP's date() function would be *extremely* useful: http://us2.php.net/date BTW, that URL is *packed* with useful functions waiting to be added to D. As a side note, I'd even advocate having a '%t' format specifier for d_time added to std.format if nothing else. Right now, d_time is dumped as a ulong.
 //get the time
 d_time dt = getUTCtime();

 // just dump the time in much the same way toDateString() does.
 writefln("timestamp: %t",dt);


 writefln("Today is: %#t","MM/DD/YYYY",dt);
If you're not adverse to the d_time type, then perhaps the same formaters could also be used to getwhatever bits we want:
  // these could be added to std.date...?
  uint getDatePart(d_time dt,char[] dateFormat);
  char[] getDatePartString(d_time dt,char[] dateFormat);
I think both your class(es) and such a format extension could live quite happily side-by-side. :)
 TimeValue tv = new TimeValue(someTimeUint);
 writefln("The time is: %d:%d:%d",dt.hours(),dt.minutes(),dt.seconds());
dt?
erg.. 'tv' for TimeValue rather. I'm used to 'dt' for 'd_time'. - Pragma
Jul 14 2004
parent reply Stewart Gordon <smjg_1998 yahoo.com> writes:
pragma <EricAnderton at yahoo dot com> wrote:
<snip>
 The only reason why I bring up string-based formatting of dates is because,
 sooner or later, you're going to want to generate a string representation of a
 date without wrangling a huge lump of code.  This is just like how
printf/writef
 is more useful (if not clearer) than streams in some cases.
The only trouble with streams is that writef hasn't been put into them. I've written the code to do this and posted it here the other day ... hopefully they'll actually be put in.
 IMO, Anything that follows the same formatting conventions as PHP's date()
 function  would be *extremely* useful:
 
 http://us2.php.net/date
Had a look. The assignment of letters to formats looks rather inconsistent, but at least it would be easy to parse. I've noticed that that system doesn't seem to have: - case control over day and month names - any mention of BC/AD, presumably because BC is beyond the PHP date range...
 BTW, that URL is *packed* with useful functions waiting to be added to D.
 
 As a side note, I'd even advocate having a '%t' format specifier for d_time
 added to std.format if nothing else.  Right now, d_time is dumped as a ulong.
<snip>

 writefln("Today is: %#t","MM/DD/YYYY",dt);
We'd have to decide on a system for format strings. I had been thinking about a system like this: dd MMM yyyy 15 JUL 2004 Wwww 'the' ddt 'of' Mmmm Thursday the 15th of July h:ii:ss pp 4:25:10 pm HH:ii:ss 16:25:10 yyyy-mm-dd HH:ii:ss.lll 2004-07-15 16:25:10.254 ....
 If you're not adverse to the d_time type, then perhaps the same formaters could
 also be used to getwhatever bits we want:
I suppose my date types and d_time could continue to be developed in parallel for a while.
 // these could be added to std.date...?
 uint getDatePart(d_time dt,char[] dateFormat);
 char[] getDatePartString(d_time dt,char[] dateFormat);
What would those functions return exactly, for different dateFormat strings?
 I think both your class(es) and such a format extension could live quite
happily
 side-by-side. :)
<snip> Yes. Once we've all settled for a suitable format format, it could be integrated into both d_time and my types. Stewart. -- My e-mail is valid but not my primary mailbox, aside from its being the unfortunate victim of intensive mail-bombing at the moment. Please keep replies on the 'group where everyone may benefit.
Jul 15 2004
next sibling parent reply pragma <EricAnderton at yahoo dot com> <pragma_member pathlink.com> writes:
In article <cd68nd$271p$1 digitaldaemon.com>, Stewart Gordon says...
The only trouble with streams is that writef hasn't been put into them. 
  I've written the code to do this and posted it here the other day ... 
hopefully they'll actually be put in.
Amen to that. A streams extension to writef would be dead-simple to write too.
 IMO, Anything that follows the same formatting conventions as PHP's date()
 function  would be *extremely* useful:
 
 http://us2.php.net/date
Had a look. The assignment of letters to formats looks rather inconsistent, but at least it would be easy to parse.
Agreed. Its a starting point though. Oracle has it's own way of doing this as well: http://www-db.stanford.edu/~ullman/fcdb/oracle/or-time.html. This is also a pretty deficent way of accomplishing things. The ISO spec for date/time formatters is a good reference too, but doesn't have as many bells and whistles: http://www.cl.cam.ac.uk/~mgk25/iso-time.html. The page does include a link to an algorithm database for timezones and daylight savings time algorithms that might pique your interest: http://www.twinsun.com/tz/tz-link.htm.
I've noticed that [the php date] system doesn't seem to have:

- case control over day and month names
- any mention of BC/AD, presumably because BC is beyond the PHP date 
range...
I never thought of this, but you're right. Php falls completely flat in this department. I was thinking you could use "ad" for "bc/ad" notation and "ce" for "ce/bce" notation, but this creates trouble by conflicting with other notations in the spec. To include these features, something new might be needed.
 BTW, that URL is *packed* with useful functions waiting to be added to D.
 
 As a side note, I'd even advocate having a '%t' format specifier for d_time
 added to std.format if nothing else.  Right now, d_time is dumped as a ulong.
<snip>

 writefln("Today is: %#t","MM/DD/YYYY",dt);
We'd have to decide on a system for format strings. I had been thinking about a system like this: dd MMM yyyy 15 JUL 2004 Wwww 'the' ddt 'of' Mmmm Thursday the 15th of July h:ii:ss pp 4:25:10 pm HH:ii:ss 16:25:10 yyyy-mm-dd HH:ii:ss.lll 2004-07-15 16:25:10.254
Sounds like a soild start. I may throw some suggestions for this back into the NG later, if you like? :)
 // these could be added to std.date...?
 uint getDatePart(d_time dt,char[] dateFormat);
 char[] getDatePartString(d_time dt,char[] dateFormat);
What would those functions return exactly, for different dateFormat strings?
Well it may not be that useful, but something like:
 int day = getDatePart(dt,"dd"); // returns the day
 char month = getDatePartString(dt,"Mmmm"); // returns month like 'July'.
.. but that's probably not as useful as I would have first thought. - Pragma
Jul 15 2004
parent "Carlos Santander B." <carlos8294 msn.com> writes:
"pragma" <EricAnderton at yahoo dot compragma_member pathlink.com> escribió
en el
mensaje news:cd6i9v$2as9$1 digitaldaemon.com
| In article <cd68nd$271p$1 digitaldaemon.com>, Stewart Gordon says...
|| We'd have to decide on a system for format strings.
||
|| I had been thinking about a system like this:
||
|| dd MMM yyyy 15 JUL 2004
|| Wwww 'the' ddt 'of' Mmmm Thursday the 15th of July
|| h:ii:ss pp 4:25:10 pm
|| HH:ii:ss 16:25:10
|| yyyy-mm-dd HH:ii:ss.lll 2004-07-15 16:25:10.254
|
| Sounds like a soild start.  I may throw some suggestions for this back
into the
| NG later, if you like? :)
|

I already wrote a toString function, taking a d_time and a char [] (to
specify the format). It's available in the Wiki in the Phobos additions
section, and I also mentioned it once in dsource in the Deimos forum.

-----------------------
Carlos Santander Bernal
Jul 15 2004
prev sibling parent reply "Carlos Santander B." <carlos8294 msn.com> writes:
"Stewart Gordon" <smjg_1998 yahoo.com> escribió en el mensaje
news:cd68nd$271p$1 digitaldaemon.com
| The only trouble with streams is that writef hasn't been put into them.
|   I've written the code to do this and posted it here the other day ...
| hopefully they'll actually be put in.

... which I can't get to work: they cause AV.

-----------------------
Carlos Santander Bernal
Jul 15 2004
parent reply Stewart Gordon <smjg_1998 yahoo.com> writes:
Carlos Santander B. wrote:

 "Stewart Gordon" <smjg_1998 yahoo.com> escribió en el mensaje
 news:cd68nd$271p$1 digitaldaemon.com
 The only trouble with streams is that writef hasn't been put into them.  
 I've written the code to do this and posted it here the other day ... 
 hopefully they'll actually be put in.
... which I can't get to work: they cause AV.
At least I thought I'd tested it. Would you care to supply a code sample? Stewart. -- My e-mail is valid but not my primary mailbox, aside from its being the unfortunate victim of intensive mail-bombing at the moment. Please keep replies on the 'group where everyone may benefit.
Jul 16 2004
parent reply "Carlos Santander B." <carlos8294 msn.com> writes:
"Stewart Gordon" <smjg_1998 yahoo.com> escribió en el mensaje
news:cd89l8$383$2 digitaldaemon.com
| Carlos Santander B. wrote:
|
|| "Stewart Gordon" <smjg_1998 yahoo.com> escribió en el mensaje
|| news:cd68nd$271p$1 digitaldaemon.com
||| The only trouble with streams is that writef hasn't been put into them.
||| I've written the code to do this and posted it here the other day ...
||| hopefully they'll actually be put in.
||
|| ... which I can't get to work: they cause AV.
|
| At least I thought I'd tested it.  Would you care to supply a code sample?
|
| Stewart.
|
| --
| My e-mail is valid but not my primary mailbox, aside from its being the
| unfortunate victim of intensive mail-bombing at the moment.  Please keep
| replies on the 'group where everyone may benefit.

Here's the code I tested (dmd 0.95, win xp pro and win 95):

//////////////////////
import std.stream;

void main ()
{
    stdout.writefln("hello world");  // <- AV
    stdout.writef("hello world\n");  // <- unable to move file pointer

    File f = new File("output",FileMode.Out);
    f.writefln("hello world");  // <- AV
    f.writef("hello world\n");  // <- AV
    f.close();
}

//////////////////////

-----------------------
Carlos Santander Bernal
Jul 16 2004
next sibling parent Stewart Gordon <smjg_1998 yahoo.com> writes:
Carlos Santander B. wrote:
 "Stewart Gordon" <smjg_1998 yahoo.com> escribió en el mensaje 
 news:cd89l8$383$2 digitaldaemon.com
 Carlos Santander B.  wrote:
 
 "Stewart Gordon" <smjg_1998 yahoo.com> escribió en el mensaje 
 news:cd68nd$271p$1 digitaldaemon.com
 The only trouble with streams is that writef hasn't been put 
 into them.  I've written the code to do this and posted it here 
 the other day ...  hopefully they'll actually be put in.
... which I can't get to work: they cause AV.
At least I thought I'd tested it. Would you care to supply a code sample? Here's the code I tested (dmd 0.95, win xp pro and win 95):
<snip> Thanks - I don't know why it doesn't work, but I'll take a look. I'm guessing that there are problems (which I've a feeling have been seen before) with functions within functions within classes, or something. Stewart. -- My e-mail is valid but not my primary mailbox, aside from its being the unfortunate victim of intensive mail-bombing at the moment. Please keep replies on the 'group where everyone may benefit.
Jul 19 2004
prev sibling parent reply Stewart Gordon <smjg_1998 yahoo.com> writes:
Carlos Santander B. wrote:
<snip>
 Here's the code I tested (dmd 0.95, win xp pro and win 95):
<snip> I'm afraid something went wrong last night when I tried to take your code home to test. But below is the test code I was using, which works for me: ---------- import std.stream; void main() { File f = new File("stream_writef.out", FileMode.Out); f.writef("Today is %s %s %d", 11, "July", 2004); f.writefln(" and the time is %d:%s", 18, 30L); f.writefln("This is a new line."); delete f; f = new File("stream_writefW.out", FileMode.Out); f.writefW("Today is %s %s %d", 11, "July", 2004); f.writeflnW(" and the time is %d:%s", 18, 33L); f.writeflnW("This is a new line."); delete f; } ---------- All I can suggest is: Are you sure you remembered to rebuild Phobos after making the changes? Stewart. -- My e-mail is valid but not my primary mailbox, aside from its being the unfortunate victim of intensive mail-bombing at the moment. Please keep replies on the 'group where everyone may benefit.
Jul 20 2004
parent "Carlos Santander B." <carlos8294 msn.com> writes:
"Stewart Gordon" <smjg_1998 yahoo.com> escribió en el mensaje
news:cdinu2$1a88$1 digitaldaemon.com
| All I can suggest is: Are you sure you remembered to rebuild Phobos
| after making the changes?

I did rebuild it, but I forgot to copy it to dmd\lib. Sorry for the trouble.
It works just fine now.

-----------------------
Carlos Santander Bernal
Jul 20 2004
prev sibling parent reply Jonathan Leffler <jleffler earthlink.net> writes:
Stewart Gordon wrote:

 I've now got an idea I think I'm going to try and code up.  (That is, if 
 I don't end up discarding this one for another one as I have been doing 
 for the last however long.)
 
 Two structs, DateValue and TimeValue, will each wrap a 32-bit integer 
 representing a date and a UTC time respectively, and provide operations 
 on them.
 
 A third struct, DateTime, would combine these values and provide 
 operations that rely on the combination (as local time manipulation 
 nearly always does).
 
 Operations that get/set components would work in local time, which would 
 default to the user's time zone but be globally settable.
 
 Further types could represent intervals of time on a similar basis.
 
 This system would, I believe, make it fairly straightforward to add 
 improvements such as DST adjustment and leap seconds at some later date.
 
 As an extra, we could have a struct of the date/time components (of 
 which some may be 'blank'), and conversions between this and the 
 aforementioned types.
 
 What does everyone think?
Sub-second precision? Please? And the 'UTC time'; what range do you have in mind? Within a single day, or since 1970-01-01 00:00:00+00:00, or some other epoch? -- Jonathan Leffler #include <disclaimer.h> Email: jleffler earthlink.net, jleffler us.ibm.com Guardian of DBD::Informix v2003.04 -- http://dbi.perl.org/
Jul 14 2004
parent reply Stewart Gordon <smjg_1998 yahoo.com> writes:
Jonathan Leffler wrote:
<snip>
 Sub-second precision?  Please?
 
 And the 'UTC time'; what range do you have in mind?  Within a single 
 day, or since 1970-01-01 00:00:00+00:00, or some other epoch?
My thought is that TimeValue would represent a time within a single day, in milliseconds since midnight UTC. Stewart. -- My e-mail is valid but not my primary mailbox, aside from its being the unfortunate victim of intensive mail-bombing at the moment. Please keep replies on the 'group where everyone may benefit.
Jul 15 2004
parent reply Jonathan Leffler <jleffler earthlink.net> writes:
Stewart Gordon wrote:

 Jonathan Leffler wrote:
 <snip>
 
 Sub-second precision?  Please?

 And the 'UTC time'; what range do you have in mind?  Within a single 
 day, or since 1970-01-01 00:00:00+00:00, or some other epoch?
My thought is that TimeValue would represent a time within a single day, in milliseconds since midnight UTC.
Well, milliseconds is better than integral seconds; going all the way to nanoseconds might be overkill - though POSIX/SUS does that. Given that you're probably planning on using 32-bit unsigned quantities and that there are 86,400 seconds in a day, you could nominally work in 0.1 millisecond units (but not in 0.01 millisecond units), and it isn't worth doing that. So, you have some large integral number of days (16 bits are not adequate as a signed quantity only allows about +/-90 years from your chosen epoch, so you need 32 bits for the days), plus 32 bits for the time of day in milliseconds since midnight, and presumably a 16 bit signed offset for the time zone - in minutes. That won't represent all historical time zones (you'd need milliseconds offsets for some of those), but it will manage all modern current civil time zones (which are actually multiples of 15 minutes offset from UTC -- Newfoundland and India are on half hour time zones, and Nepal is on a quarter hour time zone, primarily to emphasize that is isn't India). -- Jonathan Leffler #include <disclaimer.h> Email: jleffler earthlink.net, jleffler us.ibm.com Guardian of DBD::Informix v2003.04 -- http://dbi.perl.org/
Jul 15 2004
parent reply Stewart Gordon <smjg_1998 yahoo.com> writes:
Jonathan Leffler wrote:

<snip>
 Well, milliseconds is better than integral seconds; going all the way 
 to nanoseconds might be overkill - though POSIX/SUS does that.  Given 
 that you're probably planning on using 32-bit unsigned quantities and 
 that there are 86,400 seconds in a day, you could nominally work in 
 0.1 millisecond units (but not in 0.01 millisecond units), and it 
 isn't worth doing that.  So, you have some large integral number of 
 days (16 bits are not adequate as a signed quantity only allows about 
 +/-90 years from your chosen epoch, so you need 32 bits for the 
 days), plus 32 bits for the time of day in milliseconds since 
 midnight,
Yes, that's exactly what I said.
 and presumably a 16 bit signed offset for the time zone - in minutes.
If you've been following the thread, you'll have noticed that there's been a debate on whether each time should have a zone attached. The current plan is to just have it as a global setting. Keeping it with every time object would bloat memory usage a bit for most purposes. But yes, offsets in minutes are one of the basic design ideas.
 That won't represent all historical time zones (you'd need 
 milliseconds offsets for some of those),
Did they actually have discrete time zones in those days? Or a continuum?
 but it will manage all modern current civil time zones (which are 
 actually multiples of 15 minutes offset from UTC -- Newfoundland and 
 India are on half hour time zones, and Nepal is on a quarter hour 
 time zone, primarily to emphasize that is isn't India).
So I'd gathered. But I hadn't gathered where the quarter-hour zones are. If the settings of my mobile phone are anything to go by, then there are 25 whole-hour offsets (-12:00 to +12:00), 10 half-hour offsets (-09:30, -08:30, -03:30, +03:30, +04:30, +05:30, +06:30, +09:30, +10:30, +11:30) and two quarter-hour offsets (+05:45, +12:45). That's before you count DST.... Stewart. -- My e-mail is valid but not my primary mailbox, aside from its being the unfortunate victim of intensive mail-bombing at the moment. Please keep replies on the 'group where everyone may benefit.
Jul 16 2004
parent Jonathan Leffler <jleffler earthlink.net> writes:
Stewart Gordon wrote:

 Jonathan Leffler wrote:
 <snip>
 Well, milliseconds is better [...]
Yes, that's exactly what I said.
Yes, and I repeated it with justifications as I went - sorry. There was an echo in the room, or something.
 and presumably a 16 bit signed offset for the time zone - in minutes.
If you've been following the thread, you'll have noticed that there's been a debate on whether each time should have a zone attached. The current plan is to just have it as a global setting. Keeping it with every time object would bloat memory usage a bit for most purposes. But yes, offsets in minutes are one of the basic design ideas.
Different people will have different views on that. The SQL standard, FWIW, provides both TIME and TIME WITH TIMEZONE (and TIMESTAMP and TIMESTAMP WITH TIMEZONE - time stamps include date as well as time). When you know from the context what the time zone is, and that it applies to every time, the global is fine. However, if you need to deal with orders from around the world (a web site), you might be interested to know what the local time was at the customer's site as well as at the web site.
 That won't represent all historical time zones (you'd need 
 milliseconds offsets for some of those), 
Did they actually have discrete time zones in those days? Or a continuum?
I forget the exact values, but it wasn't a continuum - for example, the Netherlands used an offset from GMT (this pre-dates UTC by half a century or so) that was N minutes and M.XYZ seconds different. It represented rather accurately the difference between the Greenwich meridian and a suitable point in the Netherlands - perhaps an observatory near Amsterdam.
 but it will manage all modern current civil time zones (which are 
 actually multiples of 15 minutes offset from UTC -- Newfoundland and 
 India are on half hour time zones, and Nepal is on a quarter hour time 
 zone, primarily to emphasize that is isn't India).
So I'd gathered. But I hadn't gathered where the quarter-hour zones are. If the settings of my mobile phone are anything to go by, then there are 25 whole-hour offsets (-12:00 to +12:00), 10 half-hour offsets (-09:30, -08:30, -03:30, +03:30, +04:30, +05:30, +06:30, +09:30, +10:30, +11:30) and two quarter-hour offsets (+05:45, +12:45). That's before you count DST....
+05:45 would be Nepal; +12:45 would be somewhere in the Pacific. One of the more interesting problems is that ISO 8601 defines time zone offsets such that points east have positive time zones, but Unix and hence POSIX defines them such that points west have positive time zones. Isn't standardization wonderful - two choices, and both are standard! -- Jonathan Leffler #include <disclaimer.h> Email: jleffler earthlink.net, jleffler us.ibm.com Guardian of DBD::Informix v2003.04 -- http://dbi.perl.org/
Jul 16 2004
prev sibling parent reply "Kris" <someidiot earthlink.dot.dot.dot.net> writes:
Found this while wandering around:
http://www.cise.ufl.edu/~sbeck/DateManip.html

It has some ideas worth glancing at, including a "business mode" (think UPS
delivery!).

- Kris


"Stewart Gordon" <smjg_1998 yahoo.com> wrote in message
news:ccbcv8$1lpt$1 digitaldaemon.com...
 Just looking at std.date, and noticing that
 - it isn't object-oriented
 - it isn't exactly complete
 - its way of dealing with time zones leaves something to be desired

 I reckon one of us ought to come up with a good date/time type for D.
 Has anyone written one already?

 Things I feel such a type should support:

 - construction by components (obviously)

 - properties to set/get component values (obviously) (dealing with
 out-of-range values is a matter for debate)

 - date/time arithmetic

 - time zone information in the date object itself, and conversions
 between time zones

 - time zone offset specifiable in minutes, allowing for the half-hour
 and even quarter-hour time zones that exist (and possibly more exotic,
 finer offsets)

 - conversion to/from human-readable date/time strings, in a standard
 format and in the display date/time format specified in the OS
configuration
 - a struct representation that can be read/written from/to a file
 (either as date only, time only or both)

 - possibly conversion to/from d_time, for the purposes it may continue
 to serve

 - the option of specifying only a date, or only a time, if that's what's
 desired

 ....

 Stewart.

 --
 My e-mail is valid but not my primary mailbox, aside from its being the
 unfortunate victim of intensive mail-bombing at the moment.  Please keep
 replies on the 'group where everyone may benefit.
Jul 17 2004
parent Jonathan Leffler <jleffler earthlink.net> writes:
Kris wrote:

 Found this while wandering around:
 http://www.cise.ufl.edu/~sbeck/DateManip.html
 
 It has some ideas worth glancing at, including a "business mode" (think UPS
 delivery!).
Also http://datetime.perl.org/ Lots and lots of ideas. -- Jonathan Leffler #include <disclaimer.h> Email: jleffler earthlink.net, jleffler us.ibm.com Guardian of DBD::Informix v2003.04 -- http://dbi.perl.org/
Jul 17 2004