I say string based representations of temporal information for co-ordinating or time-stamping activities which require granularity no less than one second should be in this form: yyyy-MM-dd-HHmmss
If I have anything to do with it this particular format always implies UTC. (Guaranteed after 2004-11-01-143247 until further notice ;)
I don't believe the format is used commonly by other international standards. Less potential for ambiguity. Bonus.
It uses a heavily limited character set, including no alphabetical or white space characters. Compact. Compatible (with modern file systems and URIs without need for character escaping). Easy to identify, parse and validate. Bonus.
It is an atomic value. It does not try to include localized representations of a week part (i.e. 'day') or timezone information. Data integrity. Simplicity. Bonus.
It is universally relevant. Non ambiguous. Identifiable heuristics. MEANING == point in UTC time. Bonus.
It's good for another ~8000 years. Durable. Bonus.
It's more 'human readable', and less ambiguous than “yyyyMMddHHmmss“. Bonus.
It is fixed width and sorting on its alphabetical representation in all known (to me) character encodings will be equivalent to a value based sort. Similar to advantages inherent in the ISO 8601 standard. Handy. Bonus.
It's open to the possibility of extension, to forms such as “yyyy-MM-dd-HHmmss-nnn“, “yyyy-MM-dd-HHmmss-nnnnnn“, etc. Where any granularity of time could be expressed. Bonus.
It does not identify the timezone relevant to the generator of the value. I consider timezone information inconsequential for the stated purpose of this representation of time. The value can be reliably migrated to any timezone, and the timezone of the generator, or any other applicable timezone, can be expressed separately in a message or inferred from a 'business rule'.
I say it's THE ONE TRUE WAY to express a string based representation of a point in time with granularity of one second.
(As opposed to a point in time relative to a non-identifiable or non-UTC clock, time of day, or a time of month, or a time of year, or a range thereof, which are an entirely different kettle of fish, useful only to feeble human minds with the confused notion that the universe revolves around them.)
In short, I consider this representation to imply its TYPE as a “temporal value relative to a known forward-only clock: UTC” in addition to expressing its VALUE.
And now, just thinking out loud, I reckon the format “yyyy-MM-dd HHmmss” could be used to describe a temporal value relative to an unknown (or otherwise unspecified) and not necessarily forward-only clock. Hmm.. maybe.
I wish someone maintained a international standard for describing 'clocks' with an integral representation.. perhaps someone does?
In my view, timezone information should be left out of temporal representations altogether, and there should be two basic notions, one of time relative to UTC and one of time relative to 'something else'. If you've ever had a call centre operator request a time from someone in another timezone, then you know my pain...
Ah, there it is: Sources for Time Zone and Daylight Saving Time Data .
Besides philosophical values there are considerations for old COM world...
Sure. Clearly 'compatibility' with any known API isn't a goal of mine. I've gone out of my way to pick a representation that you will rarely find, and dictated my own semantics.
I'm sick of seeing times that include incorrect timezone information (i.e. a representation of a local time with a stated UTC timezone) and all the other associated bullshit.
I'm not trying to change the world, just trying to explain how I'm ignoring the world..
I'm basically talking about how I can *represent* temporal information in an artifact, not how I expect a user to work with it. Basically I'm talking about non-localized string representations for use in mementos.
Time is really complicated. I've tried a tonne of ways to deal with it, including 'not dealing with it'.
In the end I've decided that in my situation there are basically two important types of time. One is PointInTime which is uncategorically stored in UTC and can be translated to a user local time for read only UI presentation. The other is RelativeTime which is similar to .NET DateTime in that it is TZ agnostic. RelativeTime information is collected from a user and rendered in the UI without conversion, in this case it serves simply as a label not as a necessarily identifiable point in time. Any business logic conducted on a RelativeTime needs to understand that it is *not* a PointInTime. There can be business rules, which are documented on a case by case basis, for how to determine an appropriate TZ offset for conversion of a RelativeTime into a PointInTime.
I also acknowledge TimeOfDay and RelativeDate.
I'm building my own structs for working with this stuff. Along with my own conventions for XML, SQL, UI, text based and binary representations of those times.
If I need to inter-operate then at least I can begin with a firm understanding of what the temporal data that *I* have *means*.
I tried to allude to the problems inherent in the 'store in UTC and convert to local time in UI' strategy. The problem is that 'local time' is not necessarily going to be known on the thread of execution in the run time. It's not necessarily a user setting. For example, when I've got an easily confused operator talking to an easily confused employee who are both in different timezones talking about a recent historical event the employee witnessed that is going to be recorded in my database, then when the operator says to the employee "what time did the event happen?" and the employee answers "2pm Thursday" and the operator enters the value, then the operator has not entered a value according to the timezone associated with *their* locality but rather with the locality of the *employee* or more likely the locality of the *site* at which the event took place. Clearly I need a business rule along with a business process to dictate and control what happens here, and my business requirements are that the users need not think too hard about it. The timezone in this case may be calculable from the known locality of the site, or the employee. Also, when I have an easily confused business analyst come along and query for all the events that took place between "2pm and 4pm last Thursday" I need to be able to satisfy their request with an understanding of whether they mean 2pm Thursday to be a PointInTime or as "5 hours after the start of business for each site in the result set relative to their own trading hours" and so on..
So, RelativeTime is just a 'label', it's 'time part' can readily be compared with any other RelativeTime functioning as a 'time of day' without need for further translation. For comparison with a PointInTime the TZ applicable to the RelativeTime will need to be determinable and the RelativeTime will then need to be translated to a PointInTime for comparison.
To keep things easy for myself I record all authoritative PointInTime information at the database server, during a transaction. Users can view PointInTime information in a UI (i.e. console, window handle or HTML string) translated to their local time. All data 'on the wire' or in any other persisted artifact or DB will be a 'value' only (i.e. atomic, no TZ indication) perhaps as a string in suitable for the TYPE of temporal data with some indication in formatting or field naming of either RelativeTime or PointInTime. TimeOfDay is represented as seconds since midnight and is typically a 16 bit integer. RelativeTime and PointInTime are both recorded as DateTime in SQL Server and a naming convention determines their difference. RelativeDate can be stored in a SmallDateTime. A comment, or other documentation for all RelativeTime/RelativeDate database fields indicates how a timezone can be calculated for any given record, assuming that is even possible.
I'd go on, except I couldn't be bothered, and I'm not satisfied that I've been completely correct with my explanation yet anyway..
My point was simply that if you see a time in the format yyyy-MM-dd-HHmmss and you know that it's from *me* then you can also know that it's a PointInTime relative to UTC.
> Also, when I have an easily confused business analyst come along and query for all the events that took place between "2pm and 4pm last Thursday"... <
I was trying to explain that "2pm to 4pm Thursday" might mean:
2004-11-04-140000 to 2004-11-04-160000
or it might mean:
2004-11-04 14:00:00 to 2004-11-04 16:00:00 relative to their own timezone.
or it might mean:
2004-11-04 14:00:00 to 2004-11-04 16:00:00 in an arbitrary timezone they are not necessarily in (say 'head office'), or that is unknown or specifically specified (as say 10 hours ahead of UTC).
or it might mean:
Consider the date to represent the date according to the timezone relevant to the site at the time that the event took place and consider the time in the same regard, allowing use to compare times against a known standard of trading times as being from 9am to 5pm local time, thus implying that 2pm means "5 hours after the site started trading for each site" and 4pm means "7 hours after the site started trading for each site", and so on..
The point is that RelativeTime is 'useful' although it has no meaning if compared to a PointInTime.
There is *no point* in recording a PointInTime as anything other than UTC. It is regularly too hard to source a timezone applicable to a 'user entered' or otherwise RelativeTime, particularly it is difficult to do so at data entry time, owing to the increased effort and potential for misunderstanding.
Basically they are *not the same thing*. So they should not be considered in the same domain, and they are not of the same TYPE.
But since you need to represent the value independently of the type, it doesn't hurt to use a convention that indicates your PointInTime is, in fact, a PointInTime, and not some confused notion of a RelativeTime that, at best, you might be able to use to have a guess about the date and relative position of the sun at the time the value was supposedly relevant. You most definitely can not allow automatic timezone conversion of a RelativeTime based on any locale information on the client workstation or server, because the 'type' doesn't know how to source a timezone, only business rules do. Asking a user for a PointInTime is probably something that you want to stay clear of, but you can do this provided you have some understanding of the users expectation of the timezone the PointInTime is relevant to and at data entry time the value they provide can be converted from the users timezone to UTC.
Damn... why did I drag myself back into this? Oh well. Enough!