All the Perl that's Practical to Extract and Report

Navigation

The Fine Print: The following comments are owned by whoever posted them. We are not responsible for them in any way.
Without JavaScript enabled, you might want to
use the classic discussion system instead. If you login, you can remember this preference.

Please Log In to Continue

Suppose that DateTime were the other way round, and defaulted to the local timezone. Then somebody could've made an equivalent blog post to yours but comparing DateTime->now with gmtime and complaining that they are different!

There are 2 different possible behaviours. Obviously the module can only do 1 of them by default.

I've been inconvenienced the other way round, when I discovered that our MySQL database was storing timestamps in local time rather than UTC and not storing the timezone.

You're striking at the heart of the matter by bringing up MySQL. That's our DB and it's probably the first place I ever saw a "NOW()" function. As you mention NOW() in MySQL is just like "now" in real life - it's local time. So when I see DateTime->now(), well, I expect the same. And if I called you up right now and said "hey, what time is it now?" you'd probably meet my expectations too!

Sure, that doesn't mean that everyone should expect that or that the developers of DateTime are morons. They ju

As you mention NOW() in MySQL is just like "now" in real life - it's local time.

Except that it isn't — it's more like floating time, because it doesn't also note the timezone. That's just wrong, because it means that MySQL's timestamps don't map to a particular moment in time, but to several possible moments. And even if you know the physical location, because of daylight-saving time that isn't good enough.

I don't mind at all which timezone MySQL uses to display its times. And I certainly don't care how it stores them internally. But I do care that if I tell it to note an event as having just occurred that it records sufficient information about when 'now' is such that when I later ask it for when that event happened it can give me an answer which unambiguously refers to just 1 moment in time.

So in practice that means you have to know the timezone of stored times. That can either be explicit (by storing a timezone with every time) or by being documented that all times are in UTC (or some other ‘standard’).

So when I see DateTime->now(), well, I expect the same.

But it is doing the same! Calling DateTime->now is constructing an object which unambiguously refers to the current moment in time. There are lots of ways of displaying that. By default it happens to display in UTC, but that's to do with how the data is displayed, not which moment is being represented. (And it doesn't seem fair to blame a constructor for the output!) You could also note that it displays the date by default in ISO8601 format, which has the fields in an order that most humans don't use in their day-to-day lives. Perhaps it should display the date in a more familiar format? But even so that wouldn't affect which date is being displayed.

Note how the time initially stored is in UTC, but is (internally) labelled as such — because when you tell it which timezone you wish to view the time in you are not merely applying a timezone label to an existing floating time (which would result in the time staying the same in the subsequent print statement), but telling it which view of the already-stored moment you are interested in.

This isn't unusual behaviour. If you do my $num = 0x10 then Perl stores the actual integer to which you're referring (sixteen), not the digits one and zero. If you try to print it you'll get 16 by default. If you want that integer displayed in a different base then there are ways of specifying that. But 0x10 and 16 are undoubtedly the same integer. And now is undoubtedly now, regardless of the number of ways of writing it.

And if I called you up right now and said "hey, what time is it now?" you'd probably meet my expectations too!

Do you know where in the world I am? If not you might find it confusing if I just gave you a time in my local timezone (which is different from yours) without telling you what that was.

And while most of the time if somebody asked me the time I wouldn't give them the timezone (because I'd presume they know which timezone I'm in), if somebody happened to ask me the time on the day that the clocks change for daylight saving then I'd probably clarify my answer by stating explicitly which time I was referring to.

I'd be satisfied if MySQL only stored timezone information with times that are potentially ambiguous (that hour when the clocks go back every autumn); that's the minimum required. But surely it's better to be consistent, and simpler for everybody involved, if it always included it?

Sure, that doesn't mean that everyone should expect that or that the developers of DateTime are morons. They just have different expections, I suppose.

Exactly — whichever you pick, somebody's going to prefer t'other. So DateTime can be seen as having arbitrarily chosen one of several ways which would be correct; it's straightforward to get any behaviour you want.

Whereas MySQL has chosen a way which is definitely wrong, because if it isn't doing what you want it forgets vital information and there's no way of getting back out of it the information you put in. Which, when you think about it, is a pretty fundamental requirement for a database.