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