how to migrate to std.datetime
Jonathan M Davis
jmdavisProg at gmx.com
Sun May 8 18:45:33 PDT 2011
On 2011-05-08 17:46, Adam D. Ruppe wrote:
> I decided to update my compiler today, and regret it for a lot of
> reasons, but meh.
>
> One of the things is std.datetime. A lot of my code uses std.date. It
> works very, very well for me and I like it.
>
> But, the compile process is nagging me about it. I want it to shut up.
Well, std.date is going away. While it may work for what you've been doing,
it's highly buggy.
> However, I'm not even sure where to start with std.datetime...
Well, it is true that it doesn't function anything like std.date.
> Which one of it's functions does the same as std.date.getUTCtime()?
>
> It looks like sysTimeToDTime is almost sorta kinda related, but it's
> got that same ugly deprecation text.
>
> sysTimeToDTime(Clock.currTime(UTC())); // best we can do?
>
>
> Note that it's important to me that the numbers match up - I have
> some stored and comparisons need to work the same way.
std.date and the values that it uses (i.e. d_time) are going away entirely.
sysTimeToDTime is there entirely to ease the transition. Anything that
std.date it is going to have to be redesigned so that it doesn't, unless you
want to copy the code to your own project and continue using that.
> What about std.date.toUTCString()? There's a lot of toBlahString
> in there, but none seem to match up.
>
> Another thing it's bitching at me about is std.file.lastModifed. I
> just want to check the file's age. With the old function, this is
> simple subtraction. How can I ask the new system "is this file
> greater than 8 hours old?"
>
>
> Last question: my app handles timezones on it's own by means of
> addition and subtraction of offsets against the getUTCtime() result.
> (it's a web app that fetches the offset from javascript so the server
> knows what the user's local time is relative to it's internal
> representation).
>
> std.date was pretty timezone agnostic.
>
> It looks like the DateTime doesn't mess around with them, so as
> long as I always ask for things in UTC, shouldn't be a problem, right?
>
>
> There's some more, but I think I can make the rest work with
> DateTimes by multiplying the numbers before input.
Okay. Basic overiew.
Date: Represents a date of the year. It holds a year, month, and day
internally. It has no relation to time zones.
TimeOfDay: Represents a time of day. It holds an hour, minute, and second
internally. It has no relation to time zones.
DateTime: Represents a specific time of day on a specific day of the year. It
holds a Date and TimeOfDay internally. It has no relation to time zones.
SysTime: Represents a specific date and time like DateTime does, except it
holds it internally in hecto-nanoseconds (100ns) from midnight January 1st, 1
A.D. (rather than holding the pieces of the date and time separately), and it
_does_ care about time zone. It also has precision up to hecto-nanoseconds
whereas DateTime only goes to the second.
Date, TimeOfDay, and DateTime are meant to handle basic calendar-based
operations where you don't care about the time zone. SysTime is intended for
dealing with the system time, and it incorporates time zones. You can convert
between SysTime and the other types (SysTime will cast to the other types, and
it'll take the other types in its constructors), but you do risk problems with
DST when converting from the other types to SysTime due to the fact that one
hour of the year exists twice and another doesn't exist at all due to DST
changes. But unfortunately, that's unavoidable. The only way to avoid the
problem entirely is to keep times internally in UTC at all times (which
SysTime does), though if the Date, TimeOfDay, or DateTime that you're
constructing a SysTime from represents a time in UTC, and you give it UTC as
its time zone, then you don't have that problem, since UTC doesn't have DST.
What you want to use is almost certainly SysTime. Clock.currTime() returns a
SysTime with the current time in the local time zone. Clock.currTime(UTC())
returns a SysTime with the current time in UTC. If you give it another
TimeZone object, it gives the current time in whatever time zone that object
represents. SysTime always holds the time internally in UTC and converts to
its time zone when queried for values such as its year or day, or when you do
something like convert it to a string.
The way that I would write the time out would be to use SysTime and either
have it in UTC already or call toUTC on it to get one in UTC, and then call
its toISOExtString (it was toISOExtendedString until dmd 2.053) function to
convert it to a string to write it out. When reading it in again, I'd then use
SysTime's fromISOExtString. You could just write it and read it with its time
zone being in the local time, but then that loses the time zone.
If you have a time in UTC with its time zone as numbers representing its
offset from UTC and DST, you could use SimpleTimeZone. It just has the offset
from UTC though, since it has no way of knowing when DST applies, so you would
have to add/subtract its DST offset to it if DST was in effect.
I really don't know what the best way to handle time is for your particular
application, since I'm not familiar with it. But the way that std.datetime
would handle it best would be to use either ISO or ISO Extendend strings,
which are obviously standard, since they're ISO. It really is _not_ meant to
do things the C way and have a number that you're passing around. You _can_
get at a SysTime's internal representation (of hnsecs since midnight, January
1st 1 A.D.) by calling its stdTime function if you really want a number. The
unixTime function will also give you a number by giving you a time_t like
you'd have in C. sysTimeToDTime converts a SysTime to a d_time, so it'll give
you what you've been using, but since d_time is going away along with
std.date, sysTimeToDTime will be going away as well.
Really, you're either going to have to convert your program to deal with time
the way that std.datetime does, or you're going to have to worry about
converting a SysTime or DateTime or whatever you want to use in std.datetime
to whatever representation you want to use in your program.
As for the functions in std.file, new functions were required in order to
avoid breaking old code. So, it's now timeLastModified instead of
lastModified. lastModified still returns a d_time and will be around until
std.date is gone. timeLastModified returns a SysTime. SysTimes can be compared
by simply comparing them as you would any number. If you want to ask whether
one is at least 8 hours older than another, you would do that in one of two
ways.
auto diff = sysTime2 - sysTime1;
auto olderByAtLeast8Hours = diff >= dur!"hours"(8);
or
auto olderByAtLeast8Hours = sysTime2 > sysTime1 + dur!"hours"(8);
dur!"hours"(8) creates a core.time.Duration of 8 hours. Subtracting one
SysTime from another (or Date, TimeOfDay, or Datetime from another value of
the same type) results in a core.time.Duration. And you can add or subtract a
Duration from a Date, TimeOfDay, DateTime, or SysTime.
So, you'll probably want to use SysTime, but you can use DateTime if you want.
You can even add or subtract the appopriate minutes or hours for UTC and DST
offsets to/from a DateTime if you want to handle it that way. e.g.
auto utcOffset = dur!"hours"(8);
auto dstOffset = dur!"minutes(60);
auto adjusted = dt + utcOffset - dstOffset;
So, whatever the best way to handle dates and times in your program is going
to depend on what your program is doing and how you want to adjust it. But
d_time and std.date are going away. The values that they use will no longer be
used by Phobos or be present in Phobos at all. std.datetime is how dates and
times will be handled. So, you really should get used to dealing with
std.datetime unless you want to be dealing with the date and time stuff
yourself. I can understand if there may be some migration issues in programs
which use std.date, but std.date is definitely buggy (even if it works for
what you've been doing), and it's going away.
- Jonathan M Davis
More information about the Digitalmars-d-learn
mailing list