• (nodebb)

    JSON the evil spawn of the parent evil JS... nuff said.

  • Greg (unregistered)

    You could of course also store the value as a string with the second or millisecond unit included or use a different dictionary key for a second or millisecond timestamp.

  • Sole Purpose Of Visit (unregistered)

    It doesn't really help that 1000 != 2e10, does it?

    This code is gibberish.

  • Hrolf (unregistered)

    A JSON document is an ASCII document. Even a "numeric" type is stored as its ASCII character representation, just without quotes. So why is it so hard to just settle on ISO 8601, a reasonable, parseable, and unambiguous way to represent dates, timestamps, and durations?

    Usually folks on this site are excessively tetchy about storing non-numeric data in a numeric format. Why the sudden love for it here?

  • (nodebb)
    { 
        "appointmentTimeUnixMillis": 1666007047081, 
        "appointmentTimeUnixSeconds": 1666007047, 
        "appointmentTimeUTC": "2022-10-17T11:44:07+0000" 
    }
    

    There. The dates are unambiguous.

  • (nodebb)
    ...any sufficiently large timestamps must be in milliseconds.

    It's actually even more WTF than that. Any really sufficiently large timestamps must be in microseconds. Depending on the value of MAX_NUMBER, any really really sufficiently large timestamps must be in nanoseconds. And so on.

  • (nodebb)

    Honestly, believing that XML solves the issue here is just overly optimistic about how XML will be used in real-world business code.

    Our XML parsing treats "unexpected duplicate" the same as "missing element", because it does (pseudo code)

    if(node.numberof("the tag") == 1) {
        optionvalue = node.get("the tag")
    }
    
  • (nodebb)

    My problem with the widely accepted format of "2022-10-17T11:44:07+0000" is the timezone. Ditto for Date object in JS. Why did they include the timezone in the date/time value? I don't want or need to pass around the timezone. The context of the code knows what the date/time represents, be it UTC or local, because the meaning of local - again - is derived from the context of the data.

    Addendum 2022-10-17 08:48: PS. Basically, JS and JSON went with something like DateTimeOffset in .NET, whereas what it should have been is something like DateTime in .NET.

  • (nodebb) in reply to Sole Purpose Of Visit

    It doesn't really help that 1000 != 2e10, does it?

    That's relevant even less than not at all.

    2e10 in seconds in Unix-epoch time is, as noted in the code comment, some time in the 27th Century, while 2e10 milliseconds (20 million seconds) hasn't even managed to escape from 1970, so that boundary is entirely arbitrary and it guarantees that a particular unit-not-specified quantity of time is unambiguous within the expectable lifespan of the data. For sure, a date between late 1970 and the early 27th Century, there are two representations, one in milliseconds and one in seconds, but that's less problematic than having data where a particular value is incapable of being resolved back to a single time correctly.

  • Timing Woes (unregistered)
    Comment held for moderation.
  • Sou Eu (unregistered)

    The first WTF is why would this service accept both seconds and milliseconds. The second WTF is why would a scheduling system need millisecond precision.

    Time is hard. Not every minute is 60 seconds (leap seconds, anyone?). Not every day is 24 hours (daylight savings). Not every month is 30 days. February may have 28 or 29 days. Not every year is 365 days (leap years, but also the cutoff from Julian to Gregorian calendar). Leap seconds are generally announced 5-6 months beforehand, so we can't programmatically plan for future leap seconds. During my lifetime, the US switched dates for daylight saving time and there are debates to completely abolish our biannual clock adjustments. Different countries start and stop daylight saving on different dates. Time is hard.

  • (nodebb) in reply to Mr. TA

    Why did they include the timezone in the date/time value?

    The general format allows specifying other timezones for timestamps. It's just that it's usually more convenient to write the formatter to work with a single timezone, and +0000 is the easiest to do that with.

    You weren't going to show that value directly to a non-technical user, were you?

  • (nodebb) in reply to dkf

    I understand it allows to specify the timezone, but that's my point - it's an unnecessary complication. In fact, it's a degradation of development experience - now I have to keep in mind how the corresponding object works in the source/target code, such as DateTime in .NET or Date in JS, WRT timezone handling. It has nothing to do with showing this value to the user.

    And the requirement to pass a timezone is a niche use case - and in those use cases, the timezone is stored elsewhere anyway, for example, an event scheduled for a local date/time will have the timezone stored as another field of the event object. Meaning, it's an anti-pattern to have timezone information be part of the date/time value in general.

    Those niche use cases aside, most of the time, date/time values are stored as UTC in the database and only converted to the user's local timezone in the UI.

  • Rob (unregistered) in reply to Mr. TA

    https://parade.com/.image/t_share/MTkwNTgwOTUyNjU2Mzg5MjQ1/albert-einstein-quotes-jpg.jpg

    There is no such thing as a date time without a location. :-)

  • (nodebb) in reply to Mr. TA

    For starters, this:

    "2022-10-17T11:44:07+0000"

    is a textual representation of the date and time, which should include the timezone to disambiguate it.

    The DateTime type structure, on the other hand, is an internal (relative to the application) object which must have an associated timezone to be meaningful(1), but you are right that it doesn't need to be included in the DateTime itself, provided that either it is stored somewhere else nearby or it is implicitly UTC.

    (1) And above all for it to be comparable to other DateTime objects.

  • (nodebb) in reply to Sou Eu

    but also the cutoff from Julian to Gregorian calendar

    but also the many, many cutoffs from Julian to Gregorian calendar. Not only did different countries do this at different times, but not all countries made the change all at once. If I recall an article I read a few years ago, there's a country where it is not clearly documented -when- they made all their changes.

    Just when you grasp that time is hard, it's even harder than that. :-)

  • (nodebb) in reply to Steve_The_Cynic

    There is no difference between the textual representation of the d/t and the DateTime type. Whatever your value is in the code, DateTime in this case, should be serialized in a way which transmits 1) all the information about this value and 2) no extra information about this value. DateTime is the right value type to use in the code, therefore the correct textual representation is "2022-10-17T11:44:07", and not "2022-10-17T11:44:07+0000". (Perhaps ticks can be added depending on precision requirements, but that's irrelevant).

    Similarly, the timezone which is stored nearby, should also be serialized nearby to the d/t value (or not serialized at all, if it's implicitly UTC).

    To summarize, there is no reason to have 2 different rules for representing the value in the code, and for serializing it. In fact, it's the wrong approach, IMO. Also, JS's decision to not event have an object which mimics .NET DateTime behavior is one of the biggest mistakes made by JS designers. I end up having to write "extension" methods in JS which "massage" JS Date into behaving more like .NET DateTime. Terrible.

  • Randal L. Schwartz (google)

    YAML is underused. And it supports JSON as a complete subset (a JSON string is a YAML file), and it can include type information. Oh, and comments. Ignore the indent issue... just use the JSON mode instead.

  • a cow (not a robot) (unregistered) in reply to Sole Purpose Of Visit
    Comment held for moderation.
  • fred weigel (unregistered) in reply to Sole Purpose Of Visit
    Comment held for moderation.
  • (nodebb) in reply to Mr. TA

    DateTime is the right value type to use in the code, therefore the correct textual representation is "2022-10-17T11:44:07", and not "2022-10-17T11:44:07+0000". (Perhaps ticks can be added depending on precision requirements, but that's irrelevant).

    Won't specifying only something like {"datetime": "2022-10-17T11:44:07"}result in a lot of misunderstandings about the time zone? Even if the information is close by {"datetime": "2022-10-17T11:44:07+0300"} feels safer than {"datetime": "2022-10-17T11:44:07", "timezone": "+0300"}, given that the latter form doesn't completely uniquely specify how to interpret the date-time part. I wouldn't immediately be sure whether to interpret it as "2022-10-17T11:44:07+0000"but to be displayed with a three-hour offset, resulting in "2022-10-17T14:44:07+0300", or "2022-10-17T11:44:07+0300. The latter probably only makes more sense to me right now, because I am seeing that form in posts in front of me; If I had not worked with dates for a while, my mind could go either way without necessarily noticing the potential for error.

    Insofar, I'd consider requiring an explicit timezone more robust.

  • (nodebb) in reply to R3D3

    Not at all.

    First of all, as previously mentioned, specifying the timezone is a rare requirement - best practice is to always store and transmit d/t values in UTC, and only convert to local, as needed, for UI purposes. What timezone you are displaying the information for the user depends on the user's settings, not any JSON message. (Except if user's settings are stored in a JSON file, but that's a different JSON doc at that point.) This also saves you from making mistakes about the timezone expectation - one simple rule, UTC only, both in storage (such as DB) and transmission (such as REST API JSON messages). Done.

    Secondly, even to the extent that timezone is SOMETIMES pertinent, a separate property is better, because a) you are only "doing stuff that's needed" - why send timezone info if it's irrelevant? and b) that timezone field should not pertain to the d/t value directly, but rather, describe the object being serialized in general, such as the hypothetical scheduled event in my example; in other cases, you might have a location property of the event object, which itself is an object containing a timezone property, and you want to use that to convert the d/t as needed. There is almost never a need to intrinsically tie the d/t value and the timezone into one.

    Thirdly, the answer to your question about how to interpret the d/t is - you have to know that, because it's in the "contract" which describes the JSON message (be it API or file format or what not). The whole process as you are describing it - trying to deduce how to interpret a d/t value in a JSON doc by looking at the JSON - is the wrong way around; you want to be fully aware of what's going on, and treat JSON as just a data file, and not rely on JSON to understand what the d/t value means.

  • Rob (unregistered)

    JavaScript specifies how to store a Date in JSON, which is nice and includes a UTC time zone so it is clear what has been stored.

    https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toJSON

  • Not unambiguous (unregistered) in reply to Eric Ray
    Comment held for moderation.
  • Kent (unregistered) in reply to Mr. TA
    Comment held for moderation.
  • MaxiTB (unregistered)

    This whole code is stupid, the proper way to serialize a timestamp is as an ISO timestamp highly preferable in UTC. Everythink else is always a hack.

  • Nick (unregistered)

    Mr. TA is massively triggering me here.

    I’m working on a large system where the original developers took that same naive approach of “we’ll just use the date/time without worrying about TimeZone” - we’re using Java, with the Joda Time library, so this equates to a LocalDateTime object in most of the code.

    However, this is NOT the same as a Date/Time in UTC. As a result, when our new client wanted a server in London, with users in both San Francisco and Tokyo, they ended up in a situation where the “Last Modified” time stamp on an object was 9 hours earlier than the “Created” time stamp.

    Sure, this could have been avoided by converting all times to UTC - but if your time stamp is just “2022-09-01 14:00:00.000”, there’s no way to know if it’s already been converted to UTC or not.

    I’ve only found two contexts in which zone-less dates and times are useful.
    First, for “all day” calendar events, you typically want a zone-less date - think Birthdays, Anniversaries, holidays etc. If you’re on vacation the other side of the world, you still want to celebrate your anniversary on the 4th of April (or whatever) - you might stay up until 2am to celebrate the exact “moment”, but you’re probably more concerned about making a day of it, based on local meal times etc. Second, for “alarms” (not “appointments” though), you typically want a zone-less time. If you have an alarm set for 7am, when you travel to Japan, you don’t want to be oversleeping by 9 hours because it’s going off at 16:00 local (7am UTC). An appointment SHOULD have a timezone though - you don’t want to be 9 hours early for your zoom call with the guys in London either!

    You can “get away” with having zone-less times in a single-server application that’s only used in a single timezone, or in a tiny project where all the inputs can be converted to UTC as soon as they are received - but for the sake of a few extra bytes, even in that scenario, it’s worth specifying that this is a UTC time so that there is never any confusion.

  • can't think of any more stupid names (unregistered) in reply to Nick
    Comment held for moderation.
  • Tse (unregistered) in reply to Nick
    Comment held for moderation.
  • (nodebb) in reply to Mr. TA

    My problem with the widely accepted format of "2022-10-17T11:44:07+0000" is the timezone.

    Well, if by "accepted format" you mean ISO 8601, a date/time without a timezone is explicitly assumed to be local time in the standard. If you are going to use ISO 8601, you either have to explicitly specify the offset of 0 or append a Z i.e. in ISO 8601 2022-10-17T11:44:07Z You can also write 20221017T114407Z if space is important.

    The context of the code knows what the date/time represents, be it UTC or local

    Ha ha. That's funny. How long have you been reading The Daily WTF?

  • (nodebb) in reply to Nick

    "Sure, this could have been avoided by converting all times to UTC - but if your time stamp is just “2022-09-01 14:00:00.000”, there’s no way to know if it’s already been converted to UTC or not."

    Again, it sounds like you have a process problem, not a JSON problem. If a simple rule is followed that all d/t values are UTC in DBs and JSON, then you always know it's UTC. If it wasn't converted to UTC, it's a bug. Relying on the timezone to discover whether it's UTC or not is not a good solution, because it's trivial (for bad devs) to create a d/t value in UTC timezone but with local value, using one of the corresponding d/t ctors.

    "I’ve only found two contexts in which zone-less dates and times are useful."

    This is yet another super niche requirement, which is different from what I was talking about. I meant that most of the time, UTC is implied, and only in some cases a specific timezone is relevant. Your examples of alarms/etc. are when there is no timezone in principle; a different requirement (which is perfectly valid).

    "You can “get away” with having zone-less times in a single-server application that’s only used in a single timezone, or in a tiny project where all the inputs can be converted to UTC as soon as they are received - but for the sake of a few extra bytes, even in that scenario, it’s worth specifying that this is a UTC time so that there is never any confusion."

    Same thing can be said about massive multi-server applications - all inputs have to be converted to UTCs as soon as they are received - always. It's much easier to just follow that rule than to try dealing with timezones (anywhere other than UI). And it's not about saving a few bytes - it's about avoiding confusion: dropping the timezone altogether reinforces the message that all d/ts are UTC, period, and does not leave open the possibility that a non-UTC d/t is even possible.

  • (nodebb) in reply to Jeremy Pereira

    "Well, if by "accepted format" you mean ISO 8601, a date/time without a timezone is explicitly assumed to be local time in the standard. If you are going to use ISO 8601, you either have to explicitly specify the offset of 0 or append a Z i.e. in ISO 8601 2022-10-17T11:44:07Z You can also write 20221017T114407Z if space is important."

    Right, that's my point - I disagree with that standard. "I'm right and the world is wrong" :) Bold claim, but I stand by it.

    "Ha ha. That's funny. How long have you been reading The Daily WTF?"

    Ha ha. I know, right? But that proves my point - it sounds like the timezone is (bad) way to counteract the forces of the "bad developer collective". I think there is a better way - enforcing a better standard.

  • (nodebb)

    The whole point of standards, and of providing more information than is strictly necessary, is that people make mistakes, and don't follow processes, or have different processes. If a new person comes to the team and sees a timestamp without a timezone, they're going to have to find out what the expectation is on this team. If the +0000 is there, then it's self-documenting. Making things unambiguous and requiring less external knowledge reduces issues caused by incorrect assumptions.

    I don't think we're even talking about doing things differently, except for including those extra 5 characters so that developers don't have to Just Know that it's in UTC.

  • Local (unregistered)

    Someone needs to reboot Mr. TA.

  • Shiwa (unregistered) in reply to Mr. TA

    The thing is, you may have to manipulate 3 different kinds of "date/time":

    – A precise instant in time: log, creation date, expiry, etc. You may store them as timestamp or UTC or whatever, as long as you can map them back to an exact chronology.

    – A contextualized date/time: appointments, administrative dates, etc. Those require a timezone. If I save an event in my calendar for the opening ceremony of the next Olympic games, I don’t care if France drops daylight saving in the mean time. Same thing for accounting reports, etc.

    – A "wherever I am" date/time: birthday, holidays, alarms… Those must be timezone independent by definition.

    Your "save everything as UTC" approach only works for the first case. ISO 8601 covers more, but can be ambiguous and misses actual timezone representation (timezone id instead of offset). I actually haven’t seen a date API handling all those cases properly before java 8 and its Instant / DateTime / LocalDateTime classes… in 2014.

  • (nodebb) in reply to Shiwa

    Exactly, you summarized everything correctly. My point is that, as far as JSON goes, both cases 1 and 3 in your comment don't need a timezone, and those (especially case 1) are the overwhelming majority of scenarios.

    Even for case 2, I think it's better to specify the timezone separately, because you typically want to communicate what the timezone of the event is not just for one particular d/t value, but for the entire event. For example, you will often have start d/t and end d/t; or multiple d/ts because an event is comprised of a few parts, like "introduction", "main lecture", etc. Or the event is happening in Paris, France, and you have a link to Paris the city, and that city object has a timezone associated with it.

    You also raised another great point I haven't thought about before: the JSON ISO 8601 format only shows the offset, and not what the actual timezone is. That means you don't get the information you need (in some cases). This is one more reason to drop the silly offset part of a d/t value in JSON. If you need to know the timezone, pass the timezone ID in a separate string property.

    Regarding API, .NET handled all of these perfectly since version 3.5, which was released back in 2007.

  • (nodebb) in reply to konnichimade

    I think asking the team is not such a bad thing - a new dev on the team will want to learn a lot of things from them anyway. And, if the whole software world adopted the arguably simplest approach of UTC everywhere (except for things like alarms and scheduled events), then it's not even an item a new dev needs to ask the team about - you just know everything is UTC unless explicitly instructed otherwise. Again, I really don't like the idea of using JSON messages as "documentation".

  • (nodebb) in reply to Mr. TA

    I think asking the team is not such a bad thing - a new dev on the team will want to learn a lot of things from them anyway.

    The problem with the time-zones case, is that a new developer first has to realized, that there is something to ask here. More likely, they'll make an implicit assumption without being aware its wrong.

    Beyond the basic discussion though... The mentioning of daylight savings brought up a bigger issue. Dates may be absolute points in time, or may shift with local conventions. How does an implementation avoid suddenly having broken appointments, when one country has daylight saving time and the other does not? Or if, after creation of the appointment, the area abolishes DST or shifts the date for the switch.

    Let's say Austria suddenly abolishes DST and Germany does not. The appointment was created in Austria, so suddenly 20230621T12:00:00 means 20230621T12:00:00+0100, when at the time of creation of the appointment it meant 20230621T12:00:00+02:00. Suddenly, the "+0100" is insufficient information, because the offset alone does no longer sufficiently specify the time zone.

    God, am I glad I don't have to deal with date code...

    Addendum 2022-10-18 14:48: Apparently, the date of switching of DST changing and differing by country within the same time zone isn't even that rare. Outright abolishment would simply create a particularly large unforseen window, where the meaning of a time in terms of UTC changes after the fact.

  • Mark B (unregistered)
    Comment held for moderation.
  • (nodebb) in reply to R3D3

    You are the second commenter to raise the concern that the offset by itself IS NOT a good way to communicate the timezone info. Which is exactly I'm on an anti-timezone-offset crusade here. :)

    I don't think it's a problem if the software is done correctly. You have the appointment time in local timezone, say, 2023-06-21 12:00; and the timezone ID, which is set to Germany. Regardless of what Germany does with its DST, provided the underlying software (.NET, Java, the OS, etc.) is aware of the change, it is able to convert that d/t to UTC, and then wait for that UTC d/t. If you have a long running process, you may want to re-convert the local d/t to UTC daily, to make sure the new time zone DST rules are used (if any changed).

    Regarding creating the appointment in Austria, this is more of a UX concern; when I create an appointment in Outlook, for example, it allows you to choose the timezone (if it's different than the current one). It's incumbent on the user in Austria to switch to Germany timezone if the event is due to happen in Germany (despite the cultural and linguistic proximity, these are obviously 2 different countries).

  • CuteNCudlyToo (unregistered) in reply to Mr. TA
    Comment held for moderation.

Leave a comment on “A Matter of Timing”

Log In or post as a guest

Replying to comment #:

« Return to Article