[HN Gopher] JavaScript dates are about to be fixed
___________________________________________________________________
JavaScript dates are about to be fixed
Author : thunderbong
Score : 270 points
Date : 2024-08-24 16:47 UTC (6 hours ago)
(HTM) web link (docs.timetime.in)
(TXT) w3m dump (docs.timetime.in)
| mjcurl wrote:
| Surprising it took this long. I think timezones were missing in
| earlier versions of Python as well. I wonder why they weren't
| considered.
| pacifika wrote:
| And PHP
| 8n4vidtmkvmk wrote:
| They were added to php in 2005. Js is at least 19 years late
| to the party
| 0cf8612b2e1e wrote:
| Probably just one of those hard problems which looks easy from
| the outside. Nobody wants to handle that thankless mess, which
| is guaranteed to be broken on any of a hundred edge cases.
| kstrauser wrote:
| I understood it to be because the TZ library changes frequently
| enough that it should be an external package. Date math
| shouldn't change based on the language version you're using,
| nor should you have to upgrade the language when Arizona finds
| a new way to creatively alter time.
| mjcurl wrote:
| How do other languages handle this? Do they take the
| timezones database from the OS, which keeps it updated?
| kstrauser wrote:
| I think that'd be the worst place to take it from for the
| same reason. If I build a package using today's current TZ
| database and it works on my machine, it shouldn't stop
| working if I share it with someone using an old CentOS from
| several years ago.
| mjcurl wrote:
| You're right. But then tz updates would need a patch.
| kstrauser wrote:
| True, but it's generally a lot easier to patch software
| than expect someone to update their whole OS.
|
| ( _Generally_. I know plenty of shops deployed Exchange
| in 2009 and it still works so why fix it, goshdarnit!
| Those people aren't generally updating their OS either
| though.)
| a57721 wrote:
| In Java, there is a bundled 'tz' file. It gets updated
| frequently, here's an example:
| https://bugs.openjdk.org/browse/JDK-8325150 It is possible
| to update it manually.
| akira2501 wrote:
| > TZ library changes frequently enough
|
| The zone database adds more historic entries than they do
| modern ones. You can; however, calculate the correct 1942
| "summer war time" in the british isles if you're so inclined.
| The tendency to do this while also copying copyrighted text
| into the file shows that the zone maintainers are not
| interested in the same problems most users are.
|
| The TZ database is a complete mess. The whole thing should be
| replaced with a '.timezone' TLD, each civil time keeping
| authority should get control over it, and TXT records used to
| publish current TZ information. OS Vendors can cache all that
| in the OS if they like, but this secondary central time
| authority has outlived it's usefulness.
| gitroom wrote:
| What about external libraries like dayjs?
| Xenoamorphous wrote:
| I guess the point is that you won't/shouldn't need an externak
| lib for basic date stuff.
| solardev wrote:
| Is there a timeline? I've been waiting for Temporal since like
| 2016 or so and it's still not ready.
| eyelidlessness wrote:
| It's stage 3, and they offer production-ready polyfills. For a
| project I work on, that's a reasonable enough approximation of
| "ready". Your project needs may vary. But it should be stable
| enough to use now with a userland implementation if the API is
| what you're after.
| culi wrote:
| Safari even has a flag already. I'd expect it to officially
| land in 2025 though. It's not a focus of Interop 2024
| https://wpt.fyi/interop-2024
| et1337 wrote:
| I think this might be one of those "difficulty curve" memes. On
| the left, the Padawan: "just use UTC timestamps". In the center,
| the journeyman: "no!!! we have to store time zones and translate
| between them! Time zone awareness!" On the right, the Jedi
| master: "just use UTC timestamps".
| echelon wrote:
| This is the language of your engineering team, but not the
| language of your customer.
| gvkhna wrote:
| Yes that works for most use cases but there are use cases where
| you may need to store or shuttle the time zone. For instance
| you want to know this UTC timestamp was originally created in
| PDT. You would have to store two variables. Most other
| languages have this functionality it can be useful and is good
| to have, probably only needed by Jedi's too.
| closewith wrote:
| You can make the same meme about this use case, too. One you
| get to the right, you realise you want two variables for
| this.
| nafey wrote:
| I have always wondered why breaking the timestamp (in UTC)
| and the timezone into two separate data points and storing
| both is not the accepted solution. It appears like the
| cleanest solution to me.
| tisdadd wrote:
| From my experience, it certainly is. Easy to tell time in
| sequence as well as local time then. When daylight savings
| hits you can still calculate well, and can quickly get real
| time for hours worked out drive time for freight across
| time zones to follow the hours of service rules.
| moqmar wrote:
| Two different implementations might make two different
| local times out of that, e.g. due to not being aware of
| changing DST/timezone policies. Hence the recommendation of
| separating between user/clock/calendar time (which must be
| exact to a human) and absolute/relative timestamps (which
| must be exact to a computer).
| Denvercoder9 wrote:
| You can't accurately convert future local times to UTC
| timestamps yet, as that conversion changes when timezones
| change.
|
| Let's say we schedule a meeting for next year at 15:00
| local time in SF. You store that as an UTC timestamp of
| 2025-08-24 22:00 and America/Los_Angeles timezone. Now,
| imagine California decides to abolish daylight savings time
| and stay on UTC-8 next year. Our meeting time, agreed upon
| in local time, is now actually for 23:00 UTC.
| netsharc wrote:
| The article gives an example, of you buying a coffee with
| your credit card while travelling to Sydney, and returning to
| Madrid, and a few months later seeing a charge for 3:50 AM on
| that date...
|
| Google Photos also get confused with "When was this picture
| taken?", my older model camera just stores the EXIF date in
| "local time" and I have to remember to change its timezone
| when travelling, and if GPhotos can't figure it out, it might
| show pictures out of the airplane window, and then the next
| series of pictures are from the departure airport because
| they're from a "later" hour (since it's missing the timezone
| info).
|
| I suppose I could keep it at my home time or UTC...
| mminer237 wrote:
| That is how I would expect a bank statement to read though.
| I would find it infinitely more confusing if I bought
| something online in my bank showed the time of wherever the
| seller was located.
|
| The photos problem is harder, but the app needs to just
| convert it from local time to UTC when you import it.
| There's not much that can be done if you take photos on a
| camera with a different time zone than you're in without
| more metadata.
| netsharc wrote:
| Yeah, these are workarounds we have to use because many
| pieces of software weren't implemented fully...
| lxgr wrote:
| You'll find that most bank systems avoid any notion of
| time precision higher than calendar days for a variety of
| reasons :) As a side effect, this practice conveniently
| avoids that problem entirely.
|
| > That is how I would expect a bank statement to read
| though. I would find it infinitely more confusing if I
| bought something online in my bank showed the time of
| wherever the seller was located.
|
| When using my banking app abroad (one that does show
| timestamps), I'm usually much more confused by their
| presence than by their absence.
|
| > The photos problem is harder, but the app needs to just
| convert it from local time to UTC when you import it.
|
| But I usually want to see the time in local hours and
| minutes for photos! Sunsets, new year's fireworks etc.
| happen according to local time, not UTC or my current
| timezone's offset.
| lxgr wrote:
| Exif (fun exercise: find out who specifies it and when it
| was last updated!) actually didn't even have a way of
| storing timestamps in UTC or with zone information until
| fairly recently: It was all local times without zone
| information.
|
| I've seen some software work around that by combining the
| local date/time with an embedded GPS tag, if present, which
| does contain the time in UTC.
| mlhpdx wrote:
| Ironically, time zones are a hack with bad precision
| about the position of the sun in the sky. The GPS
| coordinate side steps the nonsense (can be converted to
| the time zone as defined in that place at that moment).
| chuckadams wrote:
| And if your spouse is checking the charges from Madrid,
| they probably want to see it in Madrid time. There is no
| single correct answer.
| Etheryte wrote:
| While UTC timestamps look like they solve all of the problems
| in one passing, they have plenty of edge cases that can blow up
| spectacularly. A good example of this is daylight saving time
| and countries changing their rules around it. You would think
| this is a rare occurrence, but it actually happens pretty often
| [0]! In the last ten years, fourteen countries have abolished
| daylight saving time.
|
| [0]
| https://en.wikipedia.org/wiki/Daylight_saving_time_by_countr...
| RandomThoughts3 wrote:
| Technically you could use TAI for most things internally and
| use an offset when you display. It works perfectly for
| records. The only issue is with scheduled things when your
| users probably want to point at something in their timezone.
| labster wrote:
| The main problem is that future values of TAI converted
| into most time zones is nondeterministic. On the other
| hand, at least you can guarantee all TAI seconds will
| actually occur.
| ikekkdcjkfke wrote:
| Or toLocalDisplayString(TAI timestamp). It seems like
| timezones and their rules change over time and geographic
| location, using todays rules to show dates back in time
| with previous rules would be broken right?
| jitl wrote:
| Well, any correct time handling library will use
| something like the IANA timezone database (aka
| tz/tzdb/zoneinfo) which stores all the changes in
| timezone rules for localities over the years - a library
| that only knows "today's rules" would be fundamentally
| broken as you say. So the internals of
| toLocalDisplayString(timestamp, timezone, calendar,
| locale) should look up the appropriate rules in effect at
| the timestamp and use those to decide the local time to
| display.
| dunham wrote:
| We hit this with the US timezone change in 2005. The front-
| end devs were using moment.js which didn't know about the
| previous start/end dates.
|
| These days I try to encode everything that is logically a
| date as yyyy-mm-dd. And if I need to do math with it, I often
| work with an offset julian date as an integer. But that only
| works if you stay on this side of September 1752:
| % cal 09 1752 September 1752 Su Mo Tu
| We Th Fr Sa 1 2 14 15 16 17 18 19
| 20 21 22 23 24 25 26 27 28 29 30
| layer8 wrote:
| Before roughly 100 years ago, calendar dates were region-
| dependent anyway (Russia was still on the Julian calendar
| until 1918), and time zones didn't really exist until
| roughly 150 years ago (their establishment mostly being
| motivated by the spreading of railways). It's okay to apply
| the perpetual Gregorian calendar both into the past and the
| future by default. It probably won't last more than a
| couple thousand years into the future as well, considering
| Earth's decelerating rotation.
| nradov wrote:
| Some Orthodox Churches still use the Julian calendar even
| today. Of course they aren't major software customers.
| LoganDark wrote:
| oof, there went 12 days. at least this isn't a regular
| occurrence outside of 1752 (unless you have DID, I guess)
| Denvercoder9 wrote:
| If you're truly using Julian dates, the switch to the
| Gregorian calendar in the UK and US in September 1752
| shouldn't affect you.
| thaumasiotes wrote:
| > if I need to do math with it, I often work with an offset
| julian date as an integer. But that only works if you stay
| on this side of September 1752
|
| Wouldn't using Julian days _prevent_ the ordinary problems
| involved with doing calendar math across a renumbering of
| the dates?
| naasking wrote:
| Sure, but now you've reduced the scope of the problem to a
| few edge cases. Every other solution I've seen still has
| these edge cases and doesn't solve the core problem as simply
| as UTC. If you think otherwise, can you describe or provide a
| link to these other solutions?
| lxgr wrote:
| For region-specific events (which includes most physical
| meetings, by convention many financial processes etc.),
| it's much safer to store both the local time and time zone
| city, _as well as the UTC offset at the time of writing_ ,
| and to convert to UTC only at runtime using an up-to-date
| time zone database.
|
| That way, you can identify all of:
|
| - Future timestamps you might want to re-process, e.g. for
| notification scheduling, because the future UTC conversion
| has changed between scheduling/updating the event and now.
|
| - Equivalently, timestamps written by software/an OS
| running an outdated TZ database. You should talk to them;
| things are about to go wrong if the date is in the non-too-
| far future!
|
| - Trivially and without conversion, the local time that
| people will use in the meeting notes, documenting that you
| missed the meeting because you didn't update your TZ
| database and dialed in to the meeting an hour late
| mmis1000 wrote:
| Like, what if you only need the date but not the time? You
| can use timestamp to store a birthday, but which in which
| timezone should you transform it back to date?
|
| Or what if it is specifically about time in timezone
| independent way? You want to wake up ate 06:00 no matter in
| any timezone. Just something like alert.
|
| You could use part of ISO8601 like 2020-02-02 or 06:00:00 to
| store exactly what you specify. But with timestamp, not so
| much.
| 9dev wrote:
| I've been thinking about this; does a timestamp even work,
| then, without not only a time zone, but a location? I mean
| time zones are poor man's locations, but if we want to do
| this properly...
| happytoexplain wrote:
| No - the master's answer is that you use one or the other
| depending on whether you are representing absolute time or
| clock/calendar time. The expertise lies in understanding the
| difference between those two things, which one your use case
| falls into, and how to ensure other developers and _the very
| APIs provided by your platform_ do not make silent assumptions
| about that decision.
|
| Often it _feels_ like you can "just use UTC" because it's hard
| to imagine the fail states, and APIs often make tz assumptions
| for you so you may never notice those fail states (occasionally
| your software will just be buggy and annoy a user, decreasing
| the feeling of quality and trust - it may never result in a
| disaster).
| naasking wrote:
| There is no such thing as absolute time so the distinction
| you're trying to make is not clear.
| SoftTalker wrote:
| And even then it's difficult. Time zone definitions change.
| Summer time does not start and end on the same date
| everywhere. So you also might need to know the UTC offset
| corresponding to the time zone _at that time_ not just the
| UTC offset of that time zone today (assuming it still exists)
|
| Edit to add: still, this sounds like a great improvement. A
| common mistake that naive programmers make is to believe that
| they can hand-roll their own date/time functions. And
| JavaScript sort of forces them to do that.
|
| See also Falsehoods programmers believe about time at https:/
| /gist.github.com/timvisee/fcda9bbdff88d45cc9061606b4b...
| stefan_ wrote:
| Sounds like you are in the middle. Because the Jedi master
| knows _you need both_.
| lexicality wrote:
| Dates of past events are always UTC, dates of future physical
| events must _always_ be a timestamp and a location, dates of
| future virtual events are either UTC or location based
| depending on how virtual they actually are.
|
| I can tell you from bitter experience that if you have an event
| where a person has to arrive at a place at a time and you store
| that as UTC instead of wall clock, you will have a problem at
| some point
| mirekrusin wrote:
| Past/future doesn't matter, what matters is context. You
| don't need to use timezones for ie. setTimeout even though it
| refers to the future and you should have timezone available
| for past events ie. atm withdrawal.
| marshmellman wrote:
| setTimeout takes a duration in ms, not a timestamp. If it
| did take a timestamp, I think you would need to pass it a
| timezone to disambiguate.
|
| Maybe a better argument is, "when you're setting a phone
| alarm, you don't tell it a timezone." Maybe the distinction
| is whether the timezone is established at write time or
| read time.
| jitl wrote:
| Scheduling on a calendar (occur on date X, time Y, in
| zone Z) and scheduling based on timedelta from instant
| time (occur exactly X milliseconds before or after
| instant Y) are both valid, and you can do timedelta
| scheduling in UTC without needing timezones. The issues
| come from conflating the two; using timedelta reasoning
| for calendar scheduling, or using calendar scheduling
| when you want an exact timedelta.
| lxgr wrote:
| > when you're setting a phone alarm, you don't tell it a
| timezone.
|
| Which coincidentally and ironically makes phone alarms
| surprisingly difficult to implement in a way that does
| not break in the face of DST shifts, timezone changes
| etc., as Apple has learned the hard way a couple of
| times.
| Denvercoder9 wrote:
| > Past/future doesn't matter
|
| Past/future does matter, as generally speaking it's
| possible to accurately convert between local time and UTC
| for times in the past, but not in the future.
|
| There's a few exceptions where governments have
| retroactively changed timezones or DST rules, but at that
| point you've lost anyway.
| mlhpdx wrote:
| Yes! All past events have well defined times, even in the
| face of human silliness like changing timezones and before
| such ideas existed.
|
| The future is defined by intent which is imprecise (will
| Oregon drop daylight savings time or not -- who knows?). I
| don't know how many seconds it is until my next birthday, but
| I know exactly how many have passed since I was born.
| QuesnayJr wrote:
| I never really understood precisely what the challenges
| around dates were until this comment and the previous one.
| lxgr wrote:
| > the Jedi master: "just use UTC timestamps".
|
| That poor Jedi master is going to miss the recurring workgroup
| meeting at least twice per year though, after either DST switch
| :)
| caust1c wrote:
| Thank god!
|
| Presumably this new API will fix the fact that JS does in fact
| know about some time zones, but not most.
|
| Shield your eyes from this monstrosity that will successfully
| parse some dates using `new Date(<string>)` in some select
| special time zones, but assume UTC in the other cases:
|
| https://github.com/v8/v8/blob/781c20568240a1e59edcf0cb5d713a...
|
| This bit me hard in a previous role. :'(
| marcosdumay wrote:
| That's the Chrome V8 standard library? The one "official" thing
| that everybody uses?
|
| It knows about 8 time zones in 4 different offsets, and that's
| it?
|
| I ask because yes, everything on the site points that way. But
| it's still so hard to believe that some confirmation would be
| good.
| beeboobaa3 wrote:
| It's more about the javascript spec. If the spec says "thou
| shalt support this and that" and one of the browsers
| implements _more_ than that, we are now back in the 2000s
| where one browser may be supported by some websites but
| others aren 't.
| tmpz22 wrote:
| Canvas by Instructure, one of the largest LMS (learning
| management system) in the world officially supports all
| major browsers.
|
| Unofficially schools tell students to use Chrome because
| some tasks fail often outside of Chrome. In particular
| Safari's default settings for cookies/privacy often causes
| the system to fail - particularly with integrations that
| use iframes/popups and other antiquated tricks.
|
| The year is 2024.
| lxgr wrote:
| I'm actually less surprised about this in 2024 than I
| would have been for a webapp in 2014.
|
| I feel like we peaked somewhere around the mid 2010s with
| regards to application compatibility: No more Flash, but
| also more than just 1.5 rendering engines.
|
| Before that, it was all "oh, sorry, Windows .exe only";
| since then, "sorry, Chrome visitors only".
| jwells89 wrote:
| It was nice. As long as you weren't doing something
| totally inadvisable like using IE 7 or something, things
| generally worked fine. Blink, Gecko, WebKit, whatever.
| Even random tiny FOSS browser projects wrapping somewhat
| outdated builds of WebKit or Gecko worked ok the majority
| of the time as long as you spoofed the user agent string
| of one of the big guys.
| mondobe wrote:
| After using Canvas for 2 years, I haven't had any
| problems with Firefox (except for the Lockdown Browser
| feature our school used to require, which I think is
| being gradually phased out).
| marcosdumay wrote:
| The JS spec requires that std-libraries decode 8 US
| timezones and no further?
| saurik wrote:
| > It's more about the javascript spec.
|
| I don't think this is correct. I think the JavaScript spec
| here defines a string format which is extremely narrow, but
| then leaves it open to browsers implementing whatever they
| want.
|
| https://262.ecma-international.org/5.1/#sec-15.9.4.2
|
| > The function first attempts to parse the format of the
| String according to the rules called out in Date Time
| String Format (15.9.1.15). If the String does not conform
| to that format the function may fall back to any
| implementation-specific heuristics or implementation-
| specific date formats.
|
| https://262.ecma-international.org/5.1/#sec-15.9.1.15
|
| > ECMAScript defines a string interchange format for date-
| times based upon a simplification of the ISO 8601 Extended
| Format. The format is as follows: YYYY-MM-DDTHH:mm:ss.sssZ
|
| > Z is the time zone offset specified as "Z" (for UTC) or
| either "+" or "-" followed by a time expression HH:mm
|
| > Note2: There exists no international standard that
| specifies abbreviations for civil time zones like CET, EST,
| etc. and sometimes the same abbreviation is even used for
| two very different time zones. For this reason, ISO 8601
| and this format specifies numeric representations of date
| and time.
|
| The hint as to what is going on then comes from MDN, which
| more documents the ground truth than the goal.
|
| https://developer.mozilla.org/en-
| US/docs/Web/JavaScript/Refe...
|
| > There are many ways to format a date as a string. The
| JavaScript specification only specifies one format to be
| universally supported: the date time string format, a
| simplification of the ISO 8601 calendar date extended
| format. The format is as follows: YYYY-MM-DDTHH:mm:ss.sssZ
|
| > Note: You are encouraged to make sure your input conforms
| to the date time string format above for maximum
| compatibility, because support for other formats is not
| guaranteed. However, there are some formats that are
| supported in all major implementations -- like RFC 2822
| format -- in which case their usage can be acceptable.
| Always conduct cross-browser tests to ensure your code
| works in all target browsers. A library can help if many
| different formats are to be accommodated.
|
| That table then comes from RFC2822, which also doesn't want
| you to use string named time zones, but as RFC822 has such
| it needs to still support it a bit--I imagine this probably
| came from back when this was used by ARPA-- and so has a
| section on "obsolete" date and time format extensions,
| which only explicitly requires support for US time zones
| and (notably) military formats.
|
| https://datatracker.ietf.org/doc/html/rfc2822#section-4.3
| "UT" / "GMT" / ; Universal Time
| ; North American UT ;
| offsets "EST" / "EDT" / ; Eastern: - 5/ -
| 4 "CST" / "CDT" / ; Central: - 6/ - 5
| "MST" / "MDT" / ; Mountain: - 7/ - 6 "PST"
| / "PDT" / ; Pacific: - 8/ - 7 %d65-73 /
| ; Military zones - "A" %d75-90 / ;
| through "I" and "K" %d97-105 / ;
| through "Z", both %d107-122 ; upper
| and lower case
|
| > Other multi-character (usually between 3 and 5)
| alphabetic time zones have been used in Internet messages.
| Any such time zone whose meaning is not known SHOULD be
| considered equivalent to "-0000" unless there is out-of-
| band information confirming their meaning.
|
| So, a spec, sure, but not the _JavaScript_ spec, and not
| because if Chrome supported something weird then JS would
| get mad (as JS nigh unto suggests going above and beyond),
| and even RFC2822 (itself already outside JS) leaves open
| the door for more zones... in practice, I actually think
| JavaScriptCore might support even more formats (but could
| be totally wrong on that)?
| saghm wrote:
| Honestly, it sounds like the most reasonable behavior
| here would be to _only_ support "Z" (optionally with
| "+<offset>") and none of the 3-letter codes.
| Unfortunately it would probably a breaking change to
| remove support for the existing codes, so it wouldn't
| happen.
| marcosdumay wrote:
| Just to note, that table is from the "Obsolete Date and
| Time" section. AFAIK, RFC 2822 only really allows the
| number offsets and Z.
|
| Anyway, yeah, that does explain the situation we are in.
| And yeah, it looks like if you are extremely literal-
| minded and insist on supporting obsolete notations on
| your new thing, that would make your code be exactly like
| the one the OP pointed.
|
| It's a bad decision all around, because the RFC 2822
| isn't concerned about general purpose time handling. A
| programing language shouldn't use something like this.
| caust1c wrote:
| Yes, this is the standard library that Node JS and the
| browser uses. Wacky isn't it?
| marcosdumay wrote:
| Yes, incredibly wacky.
|
| Somebody posted the spec as a reply, and looks like the
| standard can be read in a way that mandates exactly that.
| spaceheater wrote:
| Was this blog post written by sonnet?
| deepsun wrote:
| Looks very similar to Java Joda time, released in 2005 (later
| adopted as java.time package).
| poikroequ wrote:
| I get the same impression. Not identical but the whole temporal
| API seems heavily influenced by Java.
|
| Having worked with dates and times in both Java and JavaScript,
| I'm very happy with what I see in the temporal API. _Huge_
| improvement.
| derriz wrote:
| Every language should just copy Joda time's API. It nailed it.
| yas_hmaheshwari wrote:
| I also came down to say the same thing -- Joda's library was
| the best library to deal with date & time ( Now with all the
| changes copied to the standard library, I haven't used that
| library in years )
| JasonSage wrote:
| Agree! And I like no longer having to use js-joda to support
| these types :)
| Macha wrote:
| IMO, the pattern that Joda popularised is the most robust
| option for managing dates we've seen so far. If I'm evaluating
| date/time libraries in a language I'm not used to, ones that
| looks like their authors have looked at and understood the API
| of Joda or derivatives are going to be strong leaders.
| paxys wrote:
| Having a good datetime standard is half the battle. The other
| (more difficult) half is getting broad adoption for it. If it was
| just a matter of computing within the bounds of my application
| then there are a bunch of great libraries that make this stuff
| easy already. However now the question is - if I pass an encoded
| ZonedDateTime object from my browser/server to a third party,
| will it be able to interpret it? Realistically I'm just going to
| convert it down to an ISO string or unix TS as always just to be
| safe, thus going back to the exact same problem.
| jitl wrote:
| Temporal is getting standardized by the IETF so you can expect
| it will eventually have broad ecosystem support beyond
| Javascript, here is the RFC https://www.rfc-
| editor.org/rfc/rfc9557.html
| culi wrote:
| Safari even already has a `useTemporal` flag in their
| technology preview for the upcoming version.
|
| But yes I agree. There's no way any other standard could
| resist a standard adopted by the IETF and implemented by the
| language of the web
| lxgr wrote:
| > RFC 9557 Date and Time on the Internet:
|
| > Timestamps with Additional Information
|
| Oh, cool, we're finally adopting TAI!
| burntsushi wrote:
| If you drop the time zone, then you lose essential context that
| the consumer won't have unless you encode the time zone out of
| band. And no, an offset is not a time zone.
|
| The answer to this is RFC 9557, which was recently published.
| Rust's Jiff library (of which I am the author) supports it. And
| I believe java.time supports it. Otherwise, yes, adoption will
| take time. But it's the right way forward I think.
| wging wrote:
| > In other words, the function responsible for transforming a
| timestamp into a human-readable date is not injective, as each
| element of the set of timestamps corresponds to more than one
| element of the "human dates" set.
|
| The author confuses the concept of injectivity and well-
| definedness. For an injective function f, it has to be true that
| given distinct a and b, f(a) != f(b). That's not the problem
| here; rather the problem is that for a timestamp t there's no
| unique human-readable date x such that f(t) = x. That's well-
| definedness, not injectivity.
|
| https://en.wikipedia.org/wiki/Well-defined_expression
|
| You could talk about the inverse function, from human-readable
| dates to timestamps, and correctly point out that _that_ function
| is not injective, because more than one human-readable date maps
| to the same timestamp...
| Waterluvian wrote:
| Is there any built in for human strings for durations and times?
|
| "5 days ago."
|
| "3 hours and 33 minutes."
|
| I've found this kind of thing to be the main reason I have to
| drag MomentJS along for the ride.
| ramesh31 wrote:
| >I've found this kind of thing to be the main reason I have to
| drag MomentJS along for the ride.
|
| Likewise. It feels long overdue to have template based
| formatting natively.
| simonw wrote:
| I've written versions of that half a dozen times over my
| career. I recommend ditching MomentJS and pasting in your own
| ~15 line implementation.
|
| I'm confident ChatGPT or Claude will write you one with one-
| shot prompt that does exactly what you want. Here's an attempt
| at that:
| https://chatgpt.com/share/9bfe1d60-34cc-46fc-8327-3474c4a7d6...
| jayflux wrote:
| Yes! You're looking for DurationFormat
| https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refe...
| which will work with Temporal types
| Waterluvian wrote:
| This looks perfect! Just gotta wait until anything supports
| it. I'm hoping it's progressing and there's plans to adopt
| it.
| roblh wrote:
| I sure hope so. Moment + Moment TZ = just shy of200kb gzipped.
| Learned that one the hard way the other day.
| jitl wrote:
| It's already available in browsers as part of Intl, no need to
| wait for Temporal https://developer.mozilla.org/en-
| US/docs/Web/JavaScript/Refe...
| Waterluvian wrote:
| Oh perfect! Thanks. I was looking at some other MDN page that
| suggested basically 0% support.
| lxgr wrote:
| Pet peeve: I mostly hate these.
|
| Anything for maybe the last hour or I can see; "1 day and 5
| hours ago" and making me hover over the string (and pray that
| there's an alt text available that I still can't copy-paste) is
| very annoying.
|
| I really wish, space permitting, web designers would start at
| least including the actual timestamp in the regular/non-alt
| text as well, at the very least for professional tools if not
| for social media sites.
| 38 wrote:
| about time, Go has had this since 2012:
|
| https://pkg.go.dev/time#Date
| foepys wrote:
| Go probably has the last standard library I would take as a
| reference for my own datetime implementation.
|
| Their datetime formatting implementation is simply nuts. Why
| not follow standards? Why the NIH?
| 38 wrote:
| agreed the format parser is stupid, but thats more a cosmetic
| issue. its had the ability to create location aware dates
| since the first version 12 years ago
| godisdad wrote:
| It's about.... time
| pryelluw wrote:
| I was going to post:
|
| Well, about time.
| radicalbyte wrote:
| Can we fix the numeric types next? Having the integer types and
| decimal types would resolve a whole lot of issues.
| jitl wrote:
| I can't remember wishing I had int32 or uint8 if that's what
| you mean. Not having int64 or int128 is kind of annoying but
| bigint fills in there fine.
| SushiHippie wrote:
| I think they mean splitting the "Number" [0] type into an
| integer type and a decimal type.
|
| Currently the "Number" type is used for every number and it
| gets stored as a double, and can "only" represent "integers"
| safely in the range of +-(2^53 -1). Though there is a
| "BigInt" [1] type.
|
| [0] https://developer.mozilla.org/en-
| US/docs/Web/JavaScript/Data...
|
| [1] https://developer.mozilla.org/en-
| US/docs/Web/JavaScript/Data...
| scottlamb wrote:
| Temporal will be really nice in that it supports remote time
| zones, allows you to iterate through daylight saving transitions,
| etc.
|
| I can't wait for it to be fully taken advantage of by things such
| as mui's date time picker. Imagine if after selecting the fall
| back day, it saw the transition and let you pick a time during
| the extra hour. If after selecting the spring forward day, it
| wouldn't let you pick a time during the hour that doesn't exist.
| Today that doesn't work because everyone uses different crappy
| third-party libraries and mui functions on top of a lowest-common
| adapter that certainly doesn't do stuff like "show me the DST
| transitions in this day".
|
| This stuff matters sometimes; a user of my NVR wanted to save a
| clip during the fall back hour and got the wrong result because
| these things just don't work right today.
| https://github.com/scottlamb/moonfire-nvr/issues/244
| Javiliano wrote:
| From the article:
|
| "Let's consider an example: suppose I want to record the moment I
| make a payment with my card. Many people might be tempted to do
| something like this:
|
| const paymentDate = new Date('2024-07-20T10:30:00');".
|
| What? I don't think anybody would define a date like this to
| record some moment. Most developers would simply use new Date()
| without any parameters, thereby creating a timezone-safe absolute
| underlying timestamp value. This value then is of course
| stringified relative to the timezone of the caller when
| retrieving it, but that's expected.
|
| The new Temporal api might be nice but it doesn't need flawed
| examples to make its case.
| Y_Y wrote:
| Unless the payment already happened?
| kibwen wrote:
| _> The Temporal API represents a revolutionary shift in how time
| is handled in JavaScript, making it one of the few languages that
| address this issue comprehensively._
|
| Note that there's also a Rust datetime crate, jiff, that's
| inspired by the Temporal API and features zone-aware datetimes
| (from burntsushi, author of ripgrep and Rust's regex library):
| https://crates.io/crates/jiff
| burntsushi wrote:
| Yes! A number of projects have already adopted Jiff too. numbat
| and gitoxide to name two big ones. :-)
| digger495 wrote:
| "fixed"
|
| And won't be available in non-chromium browsers and LTS versions
| of Node until 2028.
| strbean wrote:
| https://www.npmjs.com/package/temporal-polyfill
| SahAssar wrote:
| Whats your source for it not being available in browsers/node
| until 2028? Update cycles are pretty quick these days for
| browsers and mozilla/safari has been pretty good to add APIs
| that don't increase attack/privacy/interface surface.
| drunkencoder wrote:
| Still don't get it. Is it to be able to show the user a local
| time for the timestamp? If that is a requirement , why not just
| also store the timezone along with the utc timestamp? Should the
| date-object really know this?
| jitl wrote:
| The problem is that the result of toUTCTimestamp(datetime:
| January 1st 2077 1:15am, timezone: New York) may be X today,
| but timezone rules could change soon, and then it becomes Y
| tomorrow. If you've only persisted (unixTime: X, timezone: New
| York) in the database and you try to turn X back into a local
| time, maybe now you get December 31, 11:45pm. If you're a
| calendar application or storing future times for human events,
| people will think your software is broken and buggy when this
| happens, and they will miss events.
| dudeinjapan wrote:
| Since timezone definitions change, how do we guarantee consistent
| behavior across browsers and browser versions?
| prmph wrote:
| Good, I also used to think storing timestamps in UTC was
| sufficient. The examples really explained the problems with that
| well. One other issue to note is that, if you store dates in UTC,
| now the fact that they are in UTC is a tacit assumption, probably
| not recorded anywhere except in organizational memory.
|
| So the new API will be a very welcome addition to the JS standard
| library.
|
| However, and this is probably a bit off-topic, why are the
| ECMAScript guys not also addressing the fundamental reasons why
| JS continues to be somewhat a joke of a language?
|
| - Where are decimals, to avoid things like `parseInt(0.00000051)
| === 5`?
|
| - Why are inbuilt globals allowed to be modified? The other day a
| 3rd-party lib I was using modified the global String class, and
| hence when I attempted to extend it with some new methods, it
| clashed with that modification, and it took me and hour or two to
| figure out (in TS, no less).
|
| - Why can't we have basic types? Error/null handling are still
| haphazard things. Shouldn't Result and Maybe types be a good
| start towards addressing those?
| troupo wrote:
| > Why are inbuilt globals allowed to be modified?
|
| Because that was the original behavior, and you can't just
| change that behaviour, or half of the web will break (including
| that 3rd party lib and every web site depending on it)
|
| > Why can't we have basic types? ... Shouldn't Result and Maybe
| types
|
| Neither Result nor Error are basic types. They are complex
| types with specific semantics that the entire language needs to
| be aware of.
| mirekrusin wrote:
| They could use new directive though, ie:
| "use awesomeness";
| prmph wrote:
| So clean the language up, call it a slightly different name
| if you want, and let those who want to go modern do so. For
| those who can't, offer maintenance but no major new features
| for the original version.
|
| Being wedded to mistakes made in the past for fear of
| breaking current usage is the root of all programming
| language evil.
| troupo wrote:
| > For those who can't, offer maintenance but no major new
| features for the original version.
|
| How do you imagine doing that?
|
| > Being wedded to mistakes made in the past for fear of
| breaking current usage is the root of all programming
| language evil.
|
| Ah yes, let's break large swaths of the web because
| progress or something
| jitl wrote:
| Being able to modify built-in types is extremely useful in
| practice. This allows you to backport/"polyfill" newer
| features, like for example improvements to Intl or Temporal to
| older runtimes. If all the built-in types were locked down,
| we'd end up using those built-in types less because we'd more
| frequently need to use userspace libraries for the same things.
|
| Like, you are asking for a Result type. If this was added to
| the spec tomorrow and existing objects were updated with new
| methods that return Result, and you _can 't_ modify built-in
| types, then you can't actually use the shiny new feature for
| years.
|
| On the specific point of Maybe type, I think it's not very
| useful for a dynamically typed language like JS to have
| "maybe". If there's no compiler to check method calls, it's
| just as broken to accidentally call `someVar.doThingy()` when
| `someVar` is null (classic null pointer error) versus call
| `someVar.doThingy()` when someVar is Some<Stuff> or None, in
| either case it's "method doThingy does not exist on type
| Some<...>" or "method doThingy does not exist on type None".
| prmph wrote:
| > Like, you are asking for a Result type. If this was added
| to the spec tomorrow and existing objects were updated with
| new methods that return Result, and you can't modify built-in
| types, then you can't actually use the shiny new feature for
| years.
|
| And that's a good thing, because you know that with a
| specific version of JS, the inbuilts are fixed; no mucking
| around to know what exactly you have, and no global
| conflicts. I find it surprising that you would defend this
| insane state of affairs. If you have worked on _really_ large
| JS projects, you would see my point immediately.
|
| It is like saying the immutability of functional programming
| is a bad thing because it limits you. The immutability is the
| point. it protects you from entire classes or errors and
| confusion.
|
| > If all the built-in types were locked down, we'd end up
| using those built-in types less because we'd more frequently
| need to use userspace libraries for the same things.
|
| This is the correct solution for now.
| creatonez wrote:
| > - Where are decimals, to avoid things like
| `parseInt(0.00000051) === 5`?
|
| There is a draft proposal for this:
| https://github.com/tc39/proposal-decimal
|
| Additionally, BigInt has been available for years:
| https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refe...
| (unfortunately does not serve as a u64 / i64 replacement due to
| performance implications and lack of wrapping/overflow
| behavior)
|
| > - Why are inbuilt globals allowed to be modified?
|
| > Error/null handling are still haphazard things.
|
| How would you suggest addressing these in a way that is
| backwards compatible with all existing web content?
| thaumasiotes wrote:
| > How would you suggest addressing these in a way that is
| backwards compatible with all existing web content?
|
| Version numbers. Solving the problem in the future but not
| the past is still better than leaving it unsolved in the
| future and the past.
| zahlman wrote:
| >Why can't we have basic types?
|
| The same reason you couldn't in 1996: because the assumed entry
| point for the language is someone who can barely conceptually
| manage HTML; doesn't want to have to deal mentally with the
| fact that numbers and text are fundamentally different kinds of
| thing; and - most importantly - absolutely will not accept the
| page failing to render correctly, or the user being shown an
| error message from the browser, for any reason that the browser
| could even vaguely plausibly patch around (just like how the
| browser has to guess whether an unescaped random stray < is
| just an unescaped less-than symbol or the start of an unclosed
| tag, or guess where the ends of unclosed tags should be, or do
| something sensible about constructs like
| <foo><bar></foo></bar>, or....)
| jonstewart wrote:
| Oh good, from the language that brought us WAT, a new complicated
| approach to timestamps, what could go wrong.
| fzeindl wrote:
| _scnr_
|
| So JavaScript gets what Java got in version 8, 10 years ago?
| tux1968 wrote:
| The Java team didn't initiate the process of making it an
| Internet Engineering Task Force standard; whereas this team
| did. Even though this is JavaScript centered, it really
| represents a much broader effort, that should help
| interoperability between languages and across online systems.
| ta8645 wrote:
| This is a step in the right direction, but it really needs to be
| supported everywhere so that there isn't friction when crossing
| into Javascript, and out to a database or other language.
|
| A language-agnostic test suite should be provided, including
| every edge case, so that this standard can be implemented
| everywhere.
| jitl wrote:
| Yes, it's being standardized by the IETF, here's the RFC:
| https://www.rfc-editor.org/rfc/rfc9557.html
| layer8 wrote:
| The use of "instant" to denote a time coordinate always rubbed me
| the wrong way. While "instant" arguably _can_ mean a precise
| point in time ("in that very instant"), the primary dictionary
| definition is a (very small) time interval. This is also
| reflected in the meaning of "instantly", which does _not_ mean
| "simultaneously" or "at the same point in time", but rather
| something like "immediately after". Similarly for the adjective
| "instant", which likewise generally implies a chronological
| succession, however short. I can't quite put my finger on it, but
| it instinctively feels off to me to use it to denote timestamps.
| zeroonetwothree wrote:
| The first dictionary definition of instant is "a precise moment
| in time". That usage seems perfectly to fit how it's used for a
| timestamp.
| layer8 wrote:
| That might depend on your dictionary:
| https://dictionary.cambridge.org/dictionary/english/instant
|
| In any case, it's about how the word is normally used. In
| normal language you never say something like "those two
| instants are three hours apart", or "three hours passed
| between the two instants". In contrast, you _would_ say
| something like that with "points in time". For example. one
| can say "this was observed at two different points in time".
| Nobody would say "this was observed at two different
| instants".
| the__alchemist wrote:
| Thank god. Javascript is the only language where I... wait for
| it... roll my own datetimes. Moment's central failure, beyond the
| surprise mutability, is the conflation of Dates and Times with
| Datetimes. They are not the same, and this causes so many
| problems. Python's Arrow library made the same mistake, likely
| inspired by Moment. I've heard JS devs insist that Dates and
| Times have no place as standalone constructs outside of a
| Datetime, but this is incompatible with practical use cases.
|
| Rust's Chrono? Outstanding. You can find flaws, but it's
| generally predictable, and most importantly, has fewer flaws than
| those in other languages. Python's? Kind of messy, but usable.
| JS's Date and Moment? Unusable.
| lxgr wrote:
| > I've heard JS devs insist that Dates and Times have no place
| as standalone constructs outside of a Datetime
|
| As somebody having both caused and fixed many time-related bugs
| in a financial/payments context, this sentiment is creating an
| almost physiological reaction at this point.
|
| If your real-world process is concerned with things happening
| on particular days, _don 't represent these as midnight, i.e.
| 00:00, of that day_. You'll thank me the day your company
| starts hosting servers or interacting with a customer/vendor in
| a different timezone.
|
| Essentially, this is just a corollary of "don't imply more
| precision in your internal data representation than was present
| in your data source", but it bears repeating when it comes to
| date/time processing too.
|
| (And please, please don't ask me about the difference between
| "Y" and "y" in Java's SimpleDateFormat, but look it up before
| you ever use it, thinking they're equivalent... Because on some
| days of some years, they are not.)
| sorokod wrote:
| Don't wish to be a java apologist but SimpleDateFormat lives
| in the java.text package, far from where date/time stuff is.
| lxgr wrote:
| How is a function that converts an internal date/time
| representation to an external/string-based one not
| "date/time stuff", regardless of the package it happens to
| be in?
| sorokod wrote:
| You may want to check out the contents of java.time [1]
| and it's subpackages to see what I mean by stuff.
|
| [1] https://docs.oracle.com/en/java/javase/17/docs/api/ja
| va.base...
| lxgr wrote:
| java.time.format.DateTimeFormatter seems to still point
| the exact same loaded footgun (i.e. the format patterns
| "Y" and "y") at every junior developer that dares to use
| it, so I'm not sure that would have helped junior-me
| much.
|
| The important information I was missing was "the week-
| based year and the year-of-era representations of one and
| the same date differ on some days, but not all days, and
| especially not those days you're currently using in your
| unit tests".
|
| And even if it wouldn't - SimpleDateTime was the non-
| deprecated standard library method I found at the time
| that seemed to do my job, so that was the one I used.
| dexwiz wrote:
| My favorite Date v Datetime bug is that Chile changes to DLS
| at midnight and not 1am. So it's goes 11:59>1am. Many systems
| that conflate dates and date times take the existence of
| midnight as an invariant, which it is not.
| lxgr wrote:
| Oh, that's another beautiful counterexample, thank you!
|
| I was wrecking my mind trying to come up with a scenario
| where what we did could go wrong with DST shifts alone
| (i.e. without a timezone conversion/relocation), but
| fortunately, most (all?) of Europe shifts DST on a weekend,
| never at the last day of the month, and with ample safety
| buffer from midnight, for which I am very thankful.
| danielvaughn wrote:
| Oh god your comment brought back so many horrible memories.
| At my last company we had a reporting system in NodeJS that
| ran daily reports for clients around the globe, and whoever
| set it up decided that the reports should be set to 00:00.
|
| The amount of hell that ensued was never-ending. I'm not sure
| we ever truly fixed the issue, it's so hard.
| papercrane wrote:
| In defense of Java's SimpleDateFormat, it's purposefully
| designed to be compatible with the ICU formatting.
|
| The choice of 'Y' for the rarely used "week year" is
| unfortunate. For those unaware, in ISO-8601 every year has
| either 52 or 53 full weeks. If you want to format a date like
| "2023-W52-6" (the 6th day of the 52nd week of 2024) you would
| use "YYYY-'W'ww-u".
|
| https://unicode-
| org.github.io/icu/userguide/format_parse/dat...
| treyd wrote:
| > don't imply more precision in your internal data
| representation than was present in your data source
|
| Matrix's e2ee message formats have a form of this issue. The
| AES IVs generated are only a subset of the possible IV space
| than the cryptography actually uses. This gets expressed in
| the JSON base64 string storing the IV always having an AAAAA
| prefix for the zero-padding.
|
| I'm not sure if this is _still_ true and I don 't believe it
| was responsible for any security vulnerability due to how the
| IVs are used, but it's still a sloppy design.
| leontrolski wrote:
| Here's a nice modern Python library in this space that claims
| to take influence from Temporal and Chrono -
| https://github.com/ariebovenberg/whenever
| jvanderbot wrote:
| Where did the overlap of JS and Rust knowledge come from? Is
| one a day job and the other tinkering? Are both somehow "work"?
| have_faith wrote:
| Have you ever used date-fns or Luxon? although Moment is still
| popular, I thought that was it succeeded by other libraries. If
| my memory is completely wrong I thought that Luxon might have
| been made by the creators of Moment?
| MrJohz wrote:
| Date-fns uses the native Date object which makes the same
| mistake, but then has a bunch of additional mistakes like not
| accounting for timezones and being painful to use. Date-fns
| can resolve some of these issues, but it's generally too
| simple to do a good job. It's great for manipulating
| timestamps in the user's local time zone, but beyond that it
| starts becoming difficult to get right.
| ravenstine wrote:
| > Even when working with dates on an ISO format, including the
| offset, the next time we want to display that date, we only know
| the number of milliseconds that have passed since the UNIX epoch
| and the offset. But this is still not enough to know the human
| moment and time zone in which the payment was made.
|
| Can someone explain to me what this means? ISO date strings
| should capture that exact information. Sure, there are caveats to
| storing dates/times, but I find the idea that JavaScript (or any
| language) needs built-in constructs for this purpose to be
| questionable.
|
| Beyond that, both Temporal and Date solve what should be very
| simple problems in very complicated ways. I've yet to run into a
| circumstance where ISO strings don't suffice.
| mmis1000 wrote:
| > but I find the idea that JavaScript (or any language) needs
| built-in constructs for this purpose to be questionable.
|
| Either this, or every project starts with a 200kb date library
| import. In reality, I haven't met a single project that I don't
| need to deal with dates and timezone. And I almost always have
| a date.ts in my utils library because I don't want to import a
| giant date library either. But for real, developers shouldn't
| need to deal with this. These operations and constructs that
| every sites need should be build into the language itself.
| ravenstine wrote:
| > Either this, or every project starts with a 200kb date
| library import.
|
| It's interesting you say this but then go on to explain that
| you roll your own date library. Doesn't that discredit the
| idea that the alternative for every project _must_ be a 200kb
| date library? I agree that most projects work with dates and
| time zones in some way, but that doesn 't mean we'd have to
| use moment.js in the absence of the Date API. There's plenty
| of incompetent developers that would still do as such in the
| current year, but then this becomes a whole different
| argument.
| redman25 wrote:
| Shouldn't datetime handling happen in the backend. I cannot
| imagine why you would trust the client to give you accurate
| time.
| lxgr wrote:
| If you want to display a time you have in UTC in the user's
| local timezone, what other choice do you have (unless
| there's a way you can ask them for their timezone, but I
| always find that incredibly annoying when traveling)?
| jayshua wrote:
| Let's say I'm sorting some information about an event occuring
| in Florida, USA next year. It will be on July 4th at 3:00pm. I
| store this as an ISO string: "2025-07-04T03:00:00Z-5".
|
| Florida (and the USA as a whole) have been discussing getting
| rid of the daylight savings change on-and-off for several
| years.
|
| If that law goes through in December of this year, the date I
| stored for my event will now be off by an hour because come
| July 2025 Florida will be on UTC offset -6, not -5.
|
| On the other hand, if I store the date with a fully qualified
| tz database timezone like this: "2025-07-04 03:00:00
| America/New_York" the time will continue to be displayed
| correctly because the tz database will be updated with the new
| offset information.
| filleokus wrote:
| If the calendar application want to be really accurate in a
| couple of years it's probably best to ask the user for
| coordinates for the event. You never know if that spot in
| Florida will be part of America/New_York next year.
|
| (Of course a tz identifier will be better than an integer
| offset, but I'm only half joking:
| https://en.wikipedia.org/wiki/Time_in_Indiana#tz_database)
| lxgr wrote:
| You're highlighting an important edge case here: The TZ
| database only splits regions reactively, not proactively.
|
| But an actual lat/long pair is often neither available, nor
| desirable to be stored for various reasons.
|
| Now that you mention it, I think I've seen some web
| applications that had a list of cities much longer than
| what's present in the TZ database for calendar scheduling
| purposes, probably to accomodate for just that future edge
| case.
| thaumasiotes wrote:
| > You never know if that spot in Florida will be part of
| America/New_York next year.
|
| The example really threw me; in the case where you assume
| that Florida stops observing DST, Florida is definitely not
| going to be part of America/New_York, so that example is
| guaranteed to have the same problem as the UTC timestamp.
| simple10 wrote:
| I think the author is talking about how ISO dates typically get
| converted and stored as integers or normalized (to UTC) ISO
| strings. If a payment was made in a different timezone from the
| server, the timezone locale (e.g. America/Los_Angeles) also
| needs to be separately stored in the db in order to preserve
| the full human readable meaning of the original payment date.
|
| If timezone offsets are separately stored (or the UTC
| normalized ISO strings), this still isn't sufficient to know
| which locale the offset is referring to since multiple locales
| use the same timezone offsets.
|
| It gets even more complicated when different locales shift
| their timezone offsets throughout the year due to daylight
| savings.
| andrewaylett wrote:
| The very most difficult part of writing date and time handling
| code is interfacing with systems whose developer thought date
| and time handling was completely straightforward :P.
|
| It's hard, but it's not _that_ hard so long as all the data is
| there. The biggest difficulty is working out the right frame of
| reference to store timestamps with. That 's mostly only a
| catastrophic problem for future events involving people, but
| (as others in the thread note) it's still potentially an issue
| for audit (and other) data too.
|
| Knowing which time zone a meeting is supposed to be held in is
| especially important around time zone changes.
| zahlman wrote:
| Because the timestamp and offset (i.e., a numeric indication of
| the time zone, as a difference from UTC) _aren 't actually
| enough information to calculate_ the local time, pedantically.
|
| Why not?
|
| 1. Leap seconds. They exist at irregularly spaced intervals
| based on the Earth's actual rotation, which is a) not perfectly
| consistent and b) ever so slightly, continuously, on average,
| slowing down. The offset would only allow you to figure this
| out, in principle, if you already had the UTC time - which has
| to be calculated from the timestamp in a complex way that
| accounts for leap second information retrieved from a database.
|
| 2. Time zones change over time. Some parts of the world use
| daylight savings time and others don't. It's possible in
| principle for a daylight savings time transition (which occurs
| on different dates in different parts of the world) to occur
| between two displays of the date, invalidating the offset.
|
| 3. Time zones change over (longer periods of) time. They've
| historically been created, removed or had their borders
| changed. Sir Sandford Fleming's system is now 148 years old
| (and there were others before it), and geopolitics happens.
|
| 4. Calendars. Maybe _you_ don 't care about, say, the eras of
| the Japanese calendar
| (https://en.wikipedia.org/wiki/Japanese_era_name), but some
| applications will require knowing about it. If you need to deal
| with history, then the conversion between Gregorian and Julian
| calendars will also depend on locale, because the Gregorian
| calendar was adopted at different points in different parts of
| the world.
| mlhpdx wrote:
| Aren't all of those example problems solved with a versioned
| database of timezones and calendar algorithms? Any past
| "universal" date can be converted to a fully defined local,
| contextual time based on such a resource. But, it doesn't
| exist.
| zahlman wrote:
| Such databases do exist, and they're how more heavyweight
| libraries solve the problem. But there has to be code that
| applies the algorithms; there has to be a reasonable
| guarantee that the code will actually be used in the
| appropriate situations; and dates need to encode the
| information about which database version to use (otherwise
| you will run into problems e.g. if you're trying to plan
| around _future_ dates; "render the date according to the
| current rules for the current locale" isn't always correct,
| and "render the date according to the rules for the place
| and time when and where the object was created / data was
| stored" isn't either, and "render the date according to the
| rules for the place and time _that it represents_ " isn't
| _either_ ).
|
| tl;dr: dates are hard because they represent an
| intersection between adjusting a model to meet physical
| reality, with l10n/i18n concerns ( _even if you don 't care
| about language translation_). Both of those are hard enough
| individually already.
| makeitdouble wrote:
| In theory it's a solvable problem. In practice most
| libraries handling date and time aren't living up to that
| expectation, in particular and core system libraries,
| because it's just hard and tradeoffs are made.
| lxgr wrote:
| Here's a simple example for where ISO timestamps break down:
|
| "Thank you for meeting with me on 2024-03-27T15:00:00-07:00!
| See you same time next week."
|
| When was the next meeting?
| tyingq wrote:
| Something built into the language that can do real date math
| that accounts for leap seconds, DST, and so on is unusual.
| Especially if it's handling details like saving the timestamped
| history of political decisions in various places to start/stop
| using DST. Maybe not earth-shattering since you can get it with
| a library elsewhere, but handy.
| scosman wrote:
| I had to write a bunch of date logic in go a few weeks ago.
| Assumed it would be riddled with bugs, so wrote a dozen test
| cases for time zones, daylight savings, and leap seconds.
|
| Everything just worked. Not one bug. A good library is so so
| helpful for complex use cases like dates.
| jrflowers wrote:
| Seems shortsighted to make dates fixed. The date changes almost
| every day
| izwasm wrote:
| I don't get it, you can already get the user time zone with
| javascript ``` Intl.DateTimeFormat().resolvedOptions() ``` a good
| library like dayjs can handle timezones
| jitl wrote:
| It's quite annoying to deal with different library dependencies
| that all picked a different userspace library for something
| that should be standardized. For example, you might ship a date
| picker component using dayjs, but I already adopted Luxon in my
| application, so now I need to write some janky adapter or end
| up using both.
|
| I would love to not have to import dayjs or another userspace
| library, so that i can pass datetime-with-timezone to other
| libraries and instead use an IETF standard way of handling time
| that's backed by performant native runtime code.
|
| In my experience, userspace timestring parsing and timezone
| conversion can also be a surprising CPU bottleneck. At Notion,
| we got a 15% speedup on datetime queries by patching various
| inefficiencies in the library we selected. The runtime can be
| more efficient as well as saving page weight on tzdata and
| locale stuff.
| dclowd9901 wrote:
| The value of this didn't really hit me until this line (which
| frankly should be the lede):
|
| "This precision means that regardless of DST changes or any other
| local time adjustments, your date will always reflect the correct
| moment in time."
|
| Probably a failing on my part but I had somehow assumed all this
| time that calculating DST was a separate concern from time zone
| offset, given how tremendously opaque it can be.
|
| To my knowledge, there is an area in Arizona that does observe
| DST, within an area that does not observe DST, within an area
| that does, within Arizona at large, which does not. Does this API
| really accurately represent this peculiar arrangement?
|
| It looks like canonically there's an America/Shiprock timezone
| but you'd think you'd need at least 4 to accurately represent the
| various areas.
|
| https://upload.wikimedia.org/wikipedia/commons/3/38/AZNMUT_D...
| thaumasiotes wrote:
| > To my knowledge, there is an area in Arizona that does
| observe DST, within an area that does not observe DST, within
| an area that does, within Arizona at large, which does not.
| Does this API really accurately represent this peculiar
| arrangement?
|
| What are you envisioning? That sounds like two timezones, with
| different regions belonging to one or the other. Does it matter
| to the API if two regions that aren't contiguous with each
| other share a timezone?
| thangalin wrote:
| On a related note, here's an algorithm for parsing user input
| into a sanitized time format:
| String.prototype.toTime = function () { var time =
| this; var post_meridiem = false; var
| ante_meridiem = false; var hours = 0; var
| minutes = 0; if( time != null ) {
| post_meridiem = time.match( /p/i ) !== null;
| ante_meridiem = time.match( /a/i ) !== null; //
| Preserve 2400h time by changing leading zeros to 24.
| time = time.replace( /^00/, '24' ); // Strip the
| string down to digits and convert to a number. time =
| parseInt( time.replace( /\D/g, '' ) ); } else
| { time = 0; } if( time > 0
| && time < 24 ) { // 1 through 23 become hours, no
| minutes. hours = time; } else if(
| time >= 100 && time <= 2359 ) { // 100 through 2359
| become hours and two-digit minutes. hours = ~~(time /
| 100); minutes = time % 100; }
| else if( time >= 2400 ) { // After 2400, it's
| midnight again. minutes = (time % 100);
| post_meridiem = false; } if( hours == 12
| && ante_meridiem === false ) { post_meridiem = true;
| } if( hours > 12 ) { post_meridiem =
| true; hours -= 12; } if(
| minutes > 59 ) { minutes = 59; }
| var result = (""+hours).padStart( 2, "0" ) + ":" +
| (""+minutes).padStart( 2, "0" ) + (post_meridiem ?
| "PM" : "AM"); return result; };
|
| I posted it a while back to the following thread:
|
| https://stackoverflow.com/a/49185071/59087
|
| One of my minor bug bears is why we humans have to enter time
| into input fields in such rigid formats when there's a
| straightforward algorithm to make such inputs far more natural.
| Denvercoder9 wrote:
| Your function converts "0:23" into "11:00 PM".
| thaumasiotes wrote:
| If you were a human, you would have written "00:23", not
| "0:23".
|
| It'll also convert "0:45" into "00:00AM" (and "0:23" into
| "11:00PM").
| Denvercoder9 wrote:
| > If you were a human, you would have written "00:23", not
| "0:23".
|
| No, I wouldn't. Leaving out the leading zero is pretty
| common where I'm from.
| thedougd wrote:
| Does this mean I will no longer have to suffer with so many sites
| only offering relative times in lists without even hover for
| absolute date & time?
|
| I'm looking for a particular build or deployment near a certain
| date and time and I must first calculate how many days ago it was
| then binary search through the items from that day.
| eyelidlessness wrote:
| > Does this mean I will no longer have to suffer with so many
| sites only offering relative times in lists without even hover
| for absolute date & time?
|
| Why would it mean that? It seems tangentially related at best.
| The sites you're complaining about don't use the presentation
| you're complaining about for lack of more precise Date APIs,
| they use it intentionally as a feature (even if you consider it
| a misfeature).
| wnevets wrote:
| Dealing with dates in JS is easily one of the most annoying parts
| of the language. I usually avoid it at all cost.
| culi wrote:
| Am I naive? It seems like POXIS ignoring leap seconds is a major
| mistake. Wouldn't a standard that means "number of seconds since
| January 1, 1970 UTC" be much more useful than "number of non-leap
| seconds since January 1, 1970 UTC"?
|
| Does this mean that converting two DateTimes into their POSIX
| time and subtracting them will not yield an accurate
| representation of number of seconds between two timestamps?
| lxgr wrote:
| > Does this mean that converting two DateTimes into their POSIX
| time and subtracting them will not yield an accurate
| representation of number of seconds between two timestamps?
|
| It will indeed not, and if you care about that difference, you
| should not do that, and use something like
| https://github.com/qntm/t-a-i instead.
|
| > Am I naive? It seems like POXIS ignoring leap seconds is a
| major mistake.
|
| Depending on your needs it can be either seen as a massive
| mistake or a big convenience win.
|
| In either case it's arguably not a complaint with POSIX, but
| rather with the commercial and scientific world at large using
| UTC instead of TAI (and there are indeed people arguing for
| abolishing leap seconds!). POSIX in turn just followed that
| standard.
| culi wrote:
| If we simply stored all timestamps as "number of seconds
| since X" then we could safely convert that to whatever
| timezone, apply whatever leap adjustments, apply daylight
| savings time, convert to whatever calendar, etc anywhere we
| want
|
| Instead of browsers/libraries handling all the complexity
| (standards and localization, dst, leap seconds, etc),
| couldn't we just do all our math and logic in this format and
| then convert back to whatever when we need to display a time
| to a user.
|
| It seems like saving a #seconds along with lat/long
| information is enough to handle all timestamp use-cases.
| lxgr wrote:
| > If we simply stored all timestamps as "number of seconds
| since X"
|
| That works - if you never want to represent dates in the
| future (because we don't know how many leap seconds there
| will be in the future). But that way, you'd be incapable of
| implementing even a trivial calendar application involving
| more than one timezone.
|
| > couldn't we just do all our math and logic in this format
| and then convert back to whatever when we need to display a
| time to a user
|
| We could - using all the libraries encapsulating that
| complexity.
|
| > It seems like saving a #seconds along with lat/long
| information is enough to handle all timestamp use-cases.
|
| That's even worse, since often that's not available, and
| even if it is, now you need a database representing local
| UTC offsets as polygons on the surface of the earth!
| LegionMammal978 wrote:
| > It will indeed not, and if you care about that difference,
| you should not do that, and use something like
| https://github.com/qntm/t-a-i instead.
|
| That solution, as with most simple leap-second solutions,
| relies on the fixed file being kept up-to-date ad infinitum
| to account for any future leap seconds. Unfortunately, there
| isn't and still won't be any way to get a current list of
| leap seconds from JS, except for downloading them from
| someone else's API.
| lxgr wrote:
| > That solution, as with most simple leap-second solutions
|
| I never claimed it was a simple solution, just that it was
| necessary if you do care about that difference :)
|
| The only solution that works for the future as well as for
| the past would be to schedule and communicate only in TAI,
| but good luck trying to convince the rest of the (non-
| scientific, and a good chunk of the scientific as well)
| world of that.
| llsf wrote:
| Is this article arguing that a timestamp should include space ? I
| get that timestamp can be display differently depending on the
| space (i.e. TZ and locale).
|
| But does it mean that we need to add the space component to a
| timestamp ? Feels like 2 distinct things. Sure, when I record an
| event, I might not only want to record "when" it happened, and
| "where". But the "where" does not change or impact the "when",
| and vice-versa. Those feel 2 distinct properties to me, and I
| might want to store them separately.
|
| Maybe I am missing something.
| Macha wrote:
| For past timestamps, arguably a UTC record of when it happened
| is sufficient as converting it for display in a specific
| timezone is a fixed, and no longer mutable transformation. For
| a future looking time, it's not sufficient, because e.g. DST
| rules might change, timezones might change (and there's usually
| at least several occurrences a year of some timezone or DST
| rule changing somewhere in the world). If you have a
| reservation for the concert hall from 6pm next September, you
| don't want to show up there with the previous show still
| occupying the venue just because your government abolished DST
| in the year in between.
| lxgr wrote:
| Kind of, but space in the social sense of "set of places and
| people agreeing on what is local time", not the physical one.
|
| We need to record that whenever we want to talk to people about
| time and schedule things for them, just like we need to record
| their language and regional format preferences.
|
| In other words, you might not need that level of metadata for a
| physical simulation, but you'll definitely need it for a
| calendar app. For everything in between, it depends, and the
| safest bet is accordingly to just do it, if you can.
| crote wrote:
| A complete timestamp should include a timezone, and a timezone
| is best defined with a geographic location.
|
| Example: you want to schedule events in Madrid, Spain and
| Warsaw, Poland. _Currently_ they both use the CE(S)T timezone,
| but the EU is looking into abolishing summer time - which would
| lead to countries adopting their own timezones. At the moment
| "Europe/Madrid" and "Europe/Warsaw" are identical to CET/CEST,
| but that hasn't always been the case in the past and obviously
| there's no guarantee it'll always be the case in the future.
|
| If you stored those events as CE(S)T, what are you going to do
| when summer time gets abolished and Madrid ends up at +1:00
| year-round but Warsaw at +3:00 year-round?
| penguin_booze wrote:
| For once, an article on the internet has commas in the right
| places. Well done.
| moomin wrote:
| It is a source of wonder to me that every programming language I
| know has to go through this process where the design half-asses
| time handling and end up coming back decades later with a whole
| new API which, inevitably, fewer people use than the older,
| footgun-friendly API.
| preya2k wrote:
| Can anyone shed light on the timeline behind the rollout of the
| Temporal API? I've been reading about it for many years, and it's
| always "soon" or "right around the corner". I'm kind of annoyed
| by all this teasing.
| AlexErrant wrote:
| "about to be fixed" is pretty clickbaity with no substance.
|
| From the July TC39 meeting [0]:
|
| > After 7 years, Temporal is close to done. Our only focus is
| making sure in-progress implementations are successful, by fixing
| corner-case bugs found by implementors, and making editorial
| changes to improve clarity and simplicity.
|
| It's not (yet) on the October TC39 agenda [1].
|
| The Chromium implementation issue hasn't been updated since 2022.
| [2]
|
| Webkit's implementation issue was updated once this year... to
| add a blocker [3]
|
| V8 is passing 75% of test262's tests, and JavascriptCore is
| passing 41%. Spidermonkey is a no-show. [4] Note that test262 is
| incomplete and hasn't seen activity this year [5], so those
| percentages may _decrease_ over time.
|
| "about to be fixed" ehhhh. If it lands this year I'd be
| surprised. [0]
| https://ptomato.name/talks/tc39-2024-07/#2 [1]
| https://github.com/tc39/agendas/blob/main/2024/10.md [2]
| https://chromestatus.com/feature/5668291307634688 [3]
| https://bugs.webkit.org/show_activity.cgi?id=223166 [4]
| https://test262.fyi/#|v8,v8_exp,jsc,jsc_exp,sm,sm_exp [5]
| https://github.com/tc39/test262/issues/3002
| doctornoble wrote:
| Yeah, I've been waiting for this for years and not optimistic
| it's "near".
|
| The polyfill is too heavy and the services we deal with seem to
| cover the whole range of dates and times. Julian, epoch,
| ISO-8601.
| LegionMammal978 wrote:
| It's a shame that this new API still doesn't support querying
| leap-second information within web-based JS, in any shape or
| form. The only solutions are either to store a big list yourself
| and keep it updated, or download it from someone else's website
| and trust them to keep it updated and keep their CORS settings
| permissive. Meanwhile, most OSes are fully aware of leap seconds
| (or at least, browsers could easily include an updated list), but
| there's just no way to retrieve them from the inside.
| theteapot wrote:
| > "... number of milliseconds since the EPOX given this CET
| instant"
|
| What? UNIX epoch? Central European Summer Time?
| masswerk wrote:
| I wonder, when dealing with human readable formats, is there a
| notation dealing with the repeated hour at the end of daylight
| saving time (DST)?
|
| E.g., in the US, DST ends on Nov. 3, 2024 and the hour from 1:00
| to 2:00 am will be repeated. Is there a way to distinguish the
| second pass from the first one?
| jjnoakes wrote:
| For human-readable purposes I usually just stick in the
| timezone. 1:59am EDT plus 1 minute is 1:00am EST.
| Asmod4n wrote:
| What do the authors of tzdata say about it?
| trescenzi wrote:
| I've been using Temporal, via a different polyfill than in the
| article[1], in production for about 6 months now. It's a game
| changer. But JavaScript people are also broken from years of not
| having this so it's been a hard sell. To many it's just extra
| work. We're about to start doing international stuff though so
| really hoping it becomes clear why it's amazing to the team soon.
|
| [1]: https://github.com/js-temporal/temporal-polyfill
| robjwells wrote:
| "About to be fixed" [?] "this is the year of Linux on the
| desktop"
|
| Wake me up when a browser ships Temporal.
|
| Edit: Here's Temporal on caniuse.com:
| https://caniuse.com/?search=temporal
|
| Handful of APIs in the Safari Technology Preview, otherwise nada.
| I look forward to Temporal landing but it is still a very long
| way off.
| ak_111 wrote:
| This thread is making me panic that I don't understand handling
| time in programming and now I am paranoid that one day it will
| bite me hard.
|
| What is a good primer in understanding most of the serious issues
| raised in this thread and how they manifest themselves in
| (preferably) languages like Python?
| codersfocus wrote:
| Read the luxon.js docs (the timezone section.) It's the
| successor to moment.js. They do a great job explaining the
| common footguns developers face.
| Kailhus wrote:
| Interesting, some of us migrated to date fns since
| austin-cheney wrote:
| The military solution is to standardize on a zero offset time,
| specified as time zone _Zulu_. That is just a named time zone
| representing the TAI variant of UTC.
|
| The challenge is that local computer time comes from a time and
| time zone set locally and stored in the hardware CMOS. That is
| not precise, varies from computer to computer, and provides all
| the offset problems mentioned in the article. Network hardware
| solved for that long ago using NTP. So the military applied a
| similar solution as an OS image enhancement that receives updates
| from a network time service whose time is defined according to
| the mesh of atomic clocks. Then it does not matter what offset is
| shown to the user by the OS when all your reports and data
| artifacts log against a universally synchronized time zone
| defined by a service.
|
| The military solution works fine for the military but it requires
| centralized governance normal people do not have.
| hamandcheese wrote:
| The article would be more convincing if it used more examples of
| dates in the future.
|
| For timestamps (i.e. recording things that happened), I still
| believe all you need is UTC and a location.
|
| The bank example is just a matter of poor UX, not lost
| information (surely the bank could map transactions to a local
| time zone if they wanted).
___________________________________________________________________
(page generated 2024-08-24 23:00 UTC)