Start sending dates the right way (aka The ISO8601 101)
tempus-js.com
tempus-js.com
That said, ISO 8601 tries to cover most cases for date/time representation. Implementing every bit of ISO 8601 is not desirable of course, but it is certainly worth looking at.
Does that represent the 142:nd day of the year? Isn't that ambiguous when you can specify a year and month in the same format?
'P6Y4M4DT3H45M15S'
To me, that is absolutely no less "ghastly" as just saying the period is 3600 seconds (or whatever...)Not to mention six years, four months, four days, three hours, forty five minutes and fifteen seconds, which is nothing short of 200072715 seconds (which my brain definitely wants to parse as two billions and something).
> The nice thing about ISO intervals is that they are human readable
That P6 monstrosity is not human-readable. Not by 99.999% of humans, anyway.
Trying to get them to multiple seconds (incl all the fun with leap seconds!) would be hard.
If two pieces of software are passing dates around, use a UNIX, UTC timestamp. If a human wants to read it they're probably a programmer and know how to parse a timestamp. If they're not a programmer, then you shouldn't be showing them unformatted date times anyway.
(2) you'll have much fun with leap seconds
(3) a Unix timestamp is just a number represented as floating point ... not much different from all other numbers. A standard date representation on the other hand has a unique format that's distinguishable from all other data types. This comes in handy not only for humans reading it, but also for parsers of weak formats such as CSV
Also data lives longer than both code or the documentation describing the data, this being the main argument for text-based protocols.
(4) programmers are people with feelings too and would rather read human readable dates (since they are so common), rather than lookup the boilerplate for converting a Unix timestamp to a human readable format. Here's the Python version, which I know by heart just because I had to deal with a lot of timestamps:
timestamp = time.time() # now
datetime(*time.gmtime(timestamp)[:6]).strftime("%c")
Oh wait, that gives me the date in UTC. Ok, that date is meant for me, the programmer that knows what he's doing, so here's how I can read it: datetime(*time.localtime(timestamp)[:6]).strftime("%c")
Great, now I should write a blog post about it. Or you know, just use standard date formats that are human readable, because there's a reason why our forefathers used the dates representations that we use today, instead of counting scratches on wood or something ;-)And many applications and scripts can break, like those that store and manipulate timestamps assuming a certain format (e.g. positive integers).
The Unix timestamp was created to deal with timestamps, not with date representations. Therefore this requirement (dates prior to 1970) was not an issue that had to be dealt with explicitly.
If you need to handle variable precision, time zones, ranges, etc. you can either invent your own format or use ISO-8601 which at least has the virtue of being more human readable and more likely for people to have previously encountered.
The only thing libraries often get wrong is that the timestamp should always be present and default to 'Z'. It's pretty rare to want timestamps in local time except during debugging, but that's often the default. It catches a lot of people out.
I'm always a bit nervous when people talk about ISO8601, given that very few people have probably read the spec, and are likely guessing as to its content.
http://www.w3.org/TR/NOTE-datetime
which avoids most of the awkward corners, and for which a parser is a bit easier to write.
If you're in control of the output format though, I would fully agree.
For my needs 90% of the time iso8601 is overkill and unnecessary.
But dates in what I do don't need to be complicated. Which is rare. Also I never said working with times and dates is easy, evaluate your needs for the situation. Going full tilt with timezones and full date parsing for some general server logs for example doesn't always make sense is all I'm saying. Tschuss!
Technically UTC = GMT and always has and for this "epoch time" conversation is completely identical.
However there's a people problem. Some people think "GMT = the time in London now" which it isn't, since the UK switches to BST for daylights saving. Saying "UTC" avoids the "time in London" interpretation problem.
A user may want to have some information shown as 8AM PST at the same time he wants another one shown as 8AM CET.
The technical definition is "Number of days since 1st Jan 1970 in GMT" × 86400 + "Number of seconds since midnight GMT"
Unix time clocks does funny things when there's a leap second which is about 1½ years. Some pause for a second, some go forward then backward etc.
[1] Yes, I know there's no such thing as absolute time; perhaps "machine time" expresses what I mean.
2012-05-04 12:20:34.000343 +01:00
Or, if spaces are not allowed for an unknown reason then: 2012.05.04-12:20:34.000343+01:00
Much better, still I prefer the simplicity of this: 20120504.122034
In UTC, almost as compact as an epoch, but human readable. Add as many digits as nano precision is needed.http://www.postgresql.org/docs/8.0/static/datatype-datetime....
Timestamps are human readable. You just need a machine to change them into a human readable format
Also, why are people passing around date times for specific timezones? Converting a UTC timestamp to local time is trivial in every language I've used. Converting a local time to another local time isn't.
It sounds to me like a problem that doesn't exist, and a solution that causes more problems. I'll be sticking with unix timestamps thank you very much.
Only argument I've ever heard is human readability... If you're reading these by hand so often then just write a script/tool/whatever to convert them to human readable. This is still easier since you don't have to find an acceptable ISO8601 implementation. And frankly, how often are you reading the dates manually but not as part of some log output of your program where it could convert it to human readable before logging?
This is sending dates the wrong way.
Date: Thu, 17 May 2012 08:36:04 -0700 (PDT)
as Date: 1337268964
because no one needs to look at mail headers and it should be the job of the user's mail reader to display it in a human readable form? I do not think it is so black and white. In the case of mail headers, the benefit of keeping the timestamps human readable outweighs the programmer cost for parsing them correctly.Exactly...
Who reads email headers? Maybe some server admin who's going through some backups of emails looking for something. He might even appreciate having a date format that's lexicographically ordered for his searching purposes.
Having a human readable date is like changing HTTP Content-Length to say "one million four hundred and fifty thousand and sixty four" so that when I'm reading through my raw server logs I can easily see the magnitude of the length of the responses.
>>> datetime.datetime.utcfromtimestamp(-2**31)
datetime.datetime(1901, 12, 13, 20, 45, 52)For example, with e-mail you want to know both the absolute time (so the mail client can indicate how long ago that was) and the sender's local time (important for human interaction).
Implementation wise, making the timezone explicit forces the implementer to think about it at least once and not make the mistake of writing a local time, which works while testing on systems that are on the same timezone and breaks down in the wild.
ISO8601 defines its parameters within the body. I know I am parsing seconds from an ISO stamp because it is appended with an 'S'. It can support variable specificity, so I don't have to be second-accurate if it isn't needed.
I wish there was something simpler than 3339/8601, it really is a daunting mess of incompatible implementations and optional elements, but time is hard.