[HN Gopher] Is It Time for the JavaScript Temporal API?
___________________________________________________________________
Is It Time for the JavaScript Temporal API?
Author : ceeb
Score : 133 points
Date : 2021-12-28 09:57 UTC (2 days ago)
(HTM) web link (blog.openreplay.com)
(TXT) w3m dump (blog.openreplay.com)
| toomanybeersies wrote:
| I'm happy to see that it includes primitives of varying
| precision, specifically, that it includes PlainDate [1], which
| represents a calendar date, with no timezone. This year, I've
| spent far too many days, probably weeks, fixing tedious bugs due
| to incorrect handling and parsing/formatting/reparsing of dates.
|
| [1] https://tc39.es/proposal-temporal/docs/plaindate.html
| rco8786 wrote:
| > 74Kb payload
|
| Is 74Kb really a cause for concern on modern internet
| connections? I realize death by 1,000 cuts, etc...but for such a
| core set of functionality that seems pretty reasonable.
|
| DayJs is 2 (two) Kb. Perfectly reasonable for any app with
| minimal date handling needs.
|
| (BTW I'm 100% in support of a native temporal API also, although
| have some gripes with the Dev Exp of what's shown in this post)
| mkotowski wrote:
| From my personal experience in Poland:
|
| You can have LTE+ or even 5G in cities, but traveling by train
| means that in some areas only a select few extra-lightweight
| pages like Hacker News are able to load before a timeout or
| connection loss occurs.
|
| So yes, in some situations even that amount of payload could
| have a meaningful impact.
|
| "Modern" connections are irrelevant if we are talking about
| regions, which are not viable for a high-speed infrastructure.
| And such places are almost everywhere. Mountainous parts of
| Japan, many American regions, or sparsely populated Polish
| regions.
|
| Of course, how much it is important varies greatly.
| onion2k wrote:
| _Is 74Kb really a cause for concern on modern internet
| connections?_
|
| That depends on how you define what a modern Internet
| connection is. If you mean a fast, low latency, unmetered
| connection then 74kb is obviously fine.
|
| If you mean a 4G connection on a train, or a metered rural
| satellite connection, or a typically-low-income-user pay-for-
| data connection, or even a fast cheap Internet connection but
| with a low-end device that will waste a lot of battery power
| parsing and running all that JS code, then it's a lot less
| obvious.
|
| Most of the time you don't know who the user is, so it's best
| to assume the worst case. If your site works well when things
| aren't ideal then it'll be awesome when they are good too. Only
| thinking about the happy path of users with M1 Macbooks with
| unlimited gigabit ethernet will mean everyone else has a sucky
| time on your site.
|
| Also, if someone posts your site on HN, most of the comments
| will be about how bad the code is and you'll miss out on
| feedback that's actually useful. If you're deploying a 74kb
| date library, think of your karma.
| jacobr wrote:
| It's also 74 additional kb to parse and evaluate on the main
| thread before it can continue doing more interesting things
| like rendering the main content you came to the page for. On
| many devices (a huge number of users globally are on dirt cheap
| underpowered phones) this adds up to significant user
| experience problems.
| tofflos wrote:
| I see it more as issues with fragmentation, wasted effort, and
| security. An anemic standard library forces every developer to
| either evaluate, or author, an alternative. This leads to an
| explosion of alternatives, which in turn makes it harder to
| agree on best practices and harder to secure the software
| supply chain.
| enumjorge wrote:
| There are a lot of places in the world and even the US where
| people have slow connections. It's also not just download speed
| that's the problem. Slower phones need to process all that JS.
|
| I'd say that time-related API being core functionality makes it
| more of a reason why this should be baked into the standard JS
| API. Why make users download something that most sites and web
| apps use?
| nobleach wrote:
| My take: ABSOLUTELY! 74kb or image data? Probably not. But
| unzipping, parsing/JITting/running/whatever that large of a
| payload.... on crappy 3 year old low-memory Android devices...
| yes. That is going to lag.
|
| Not too long ago, Google tried to push AMP on all of us because
| devs were getting way too careless with their bundle sizes.
| We're still not to a decent place just yet. Internet speeds in
| The United States, Europe and populated Asia may be growing but
| there's an entire world that are still at "slow-3G" speeds.
| jazzyjackson wrote:
| Even in locales with high speed internet, I find myself sharing
| a wifi router with a dozen or more devices in classrooms or
| coffee shops. It is a bit disheartening seeing google docs and
| slack struggle to stay responsive, and in a college town with
| fiber internet. I've also tried collaborating on satellite
| internet on a farm and at the end of a microwave-tower-daisy-
| chain, where youtube works great if you're the only one in town
| using the connection.
|
| I think people assume Starlink will bring high-speed internet
| to every corner of the globe, but that being the case, there's
| more situations where groups of people will share a single
| downlink, and still every kilobyte counts.
| moksly wrote:
| I view it as more of a conceptual thing than a size issue. The
| 74kb is a symptom of the issue, which is that bad things can't
| be deprecated because of backward compatibility.
|
| If there is solution that removes the necessity of a 74kb
| package then I think we should embrace it.
|
| I'm still fairly new to TypeScript but it's quickly replacing
| Python as my daily driver for most things that aren't back-end
| APIs.
| moksly wrote:
| I view it as more of a conceptual thing than a size issue. The
| 74kb is a symptom of the issue, which is that bad things can't
| be deprecated because of backward compatibility.
|
| If there is solution that removes the necessity of a 74kb
| package then I think we should embrace it.
|
| I'm still fairly new to TypeScript but it's quickly replacing
| Python as my daily driver for most things that aren't back-end
| APIs, and Date is certainly one of those things I would love to
| see changed.
| thrower123 wrote:
| I weep when I think of how many millions of times libraries
| like jQuery, lodash, moment and so many others have been
| downloaded and re-downloaded and re-downloaded again over the
| decades.
|
| A considerable fraction of all the data ever sent on the
| internet is JS libraries that could have been bundled into
| browsers instead of every web page using slightly different
| versions.
| adam_arthur wrote:
| Anyone know why all new Ecmascript APIs are implemented to be
| used as "newable classes" rather than ordinary functions?
|
| The community seems to be moving towards functional
| programming/away from classes.. and pretty much every mainstream
| JS lib is function rather than class oriented (yes, I know
| classes are simply special functions)
|
| Also adds unnecessary verbosity/more syntax noise.
|
| Is there some internal performance reason for why ordinary
| functions couldn't be optimized to perform the same as "new"?
| (Seems like it would be easy to wire the prototype internally to
| the function, resulting in same semantics).
|
| At this point better to be consistent, but I'd still use a date
| library just to avoid added verbosity of this native solution.
| Luxon API reads a lot better than this... Though I'm sure there
| are reasons a standard implementation needs added complexity (has
| to cover every edge case)
| oaiey wrote:
| Because most original API (DOM, browser, date, etc) are OO
| oriented and you stick your standard library in one pattern.
|
| And speaking of everyone moving to functional programming: i
| work with several hundred developers in four continents in a
| very dynamic envirnment.... And I have not seen a FP advocate.
| Not that FP is not good (I prefer it where applicable) but
| mindset/winning/moving towards are words I would not choose
| when it comes to describing the state of FP and OO in the
| world. There is a strong influence but not to a degree where an
| established language changes its core paradigm: see Java, C#,
| JS, ...
| jacksnipe wrote:
| Really? I have seen -- across many jobs and company sizes and
| frameworks, over about a decade -- a slow but inexorable
| trend of moving toward FP.
|
| Be it in React, where hooks are pushing everything to be
| functional; to the fact that Monads have started showing up
| in unexpected places in codebases I've worked on; to the
| fundamentally functional nature of frameworks I have to use
| every day working at a FAANG.
|
| Along the way, until the FAANG, I never met any functional
| advocates. What I did meet are people who reach for the
| appropriate functional tools when building solutions; others
| see the much better solutions they arrive at, and copy.
| lnxg33k1 wrote:
| I would be more prone to say that the original API are
| something that came up by using buzzwords from growing
| languages or something else, for sure they're a thing, but
| like it's not that `new` makes an OOP approach if then you
| miss inheritance, abstraction, encapsulation and
| polymorphism, I'm not sure if I am being picky but like if
| there is just a keyword and nothing else more important to
| the paradigm then I think it might be confusing for some
| reader to see something like that statement
| jitl wrote:
| > Is there some internal performance reason for why ordinary
| functions couldn't be optimized to perform the same as "new"?
| (Seems like it would be easy to wire the prototype internally
| to the function, resulting in same semantics).
|
| Not particularly -- JIT vms should inline `(() => new
| Thingy)()` as `new Thingy`. The temporal API provides a lot of
| nice factory functions that don't need any `new` keyword. Here
| are the first several examples of the Temporal API all
| concatenated together with comments removed:
| Temporal.Now.instant().epochSeconds;
| Temporal.Now.instant().epochMilliseconds;
| Temporal.Now.zonedDateTimeISO();
| Temporal.Now.timeZone();
| Temporal.Now.zonedDateTimeISO('Europe/London'); Tempora
| l.Instant.from('2022-03-04T05:56:78.999999999+02:00[Europe/Berl
| in]'); Temporal.Instant.from('2022-03-04T05:06+07:00');
| Temporal.Instant.fromEpochSeconds(1.0e8); Temporal.Zone
| dDateTime.from('2025-09-05T02:55:00+02:00[Africa/Cairo]');
| Temporal.Instant('2022-08-05T20:06:13+05:45').toZonedDateTime('
| +05:45'); Temporal.ZonedDateTime.from({
| timeZone: 'America/New_York' year: 2025,
| month: 2, day: 28, hour: 10,
| minute: 15, second: 0, millisecond: 0,
| microsecond: 0, nanosecond: 0 });
|
| It seems like the style is to provide these factory functions
| for almost every use-case except "build me a specific object
| with these exact values", which you need to use `new
| Constructor(...)` for. Where is the noise?
|
| As a side note, there are concrete performance reasons to use
| class/prototypes over plain objects or closure-over-hidden
| state in your own code:
|
| - Class and/or constructor functions helps ensure your long-
| lived objects instantiate their properties in a regular order.
| V8 has trouble unifying objects with the same properties but
| different property orders into the same hidden class. Each
| hidden class costs JIT time and memory space, so minimizing
| both is nice. You can fix this yourself by forcing
| instantiation of a value to go through a factory function to
| normalize property order, but at that point, why not use a
| class to take advantage of `instanceof`?
|
| - Closures over hidden state, eg long-lived closures you would
| use to implement your own object system over enclosed local
| variables, cost more than plain objects or class instances.
| It's more straight-forward to define classes at the top level
| and wrap them in sugared factory functions than to code-review
| factories that manually build objects with function properties.
| adam_arthur wrote:
| You've covered a lot here, but just want to comment on a few
| things.
|
| Factory functions can return objects that have a prototype
| just the same as "new", there is no inherent reason object
| constructors should require "new". Given that most of modern,
| idiomatic JS relies on factory functions, it seems very
| inconsistent to me to then randomly require invoking "new" to
| construct an object.
|
| Why not simply Set([1, 2, 3])? The noise comes when you have
| a nested expression with random "new" statements sprinkled in
| which disrupts the flow. Though I agree that overly complex
| expressions are an anti-pattern
|
| My underlying point is that "new" does not provide any
| clarity, given that objects are created and returned all the
| time without "new", so represents an inconsistency in design
| to me. The presence or absence of "new" basically tells you
| nothing, except implying that the object likely has prototype
| functions. But whether or not they are prototyped is more of
| an implementation detail anyway.
|
| I agree with you that most of Temporal has factory functions
| that obviate "new".
|
| To your point on performance of closures, this isn't going to
| materially matter for majority of use cases. Yes, prototype
| is more efficient than closures functions, but benefits of
| prototypes can also be achieved through separation of data
| and function (singleton utility functions that operate on
| data).
|
| Also syntax sugar for prototype could have been done in an
| (IMO) more consistent way through some syntax addition to
| functions rather than creating class. Generally modern
| userland code shouldn't really be using prototype and "this"
| anyway, as "this" has tons of footguns in JS, and I would
| guess majority of developers don't understand the intricacies
| of "this" when passing functions around, or when using arrows
| vs classical function declarations.
| olliej wrote:
| The problem with relying on JITs inlining things is that
| you're hoping that an opaque optimizer will come to the same
| conclusion as you, and historically there have been all sorts
| of things that spontaneously kill optimizations (I recall
| there being a point where one of the JS VMs made decisions
| based on source text size, so comments could change
| optimization behaviour).
|
| There's also all sorts of optimizations you have to depend on
| to avoid excess object allocations, etc.
|
| That said object allocation in JSC and V8 (not sure about
| spider monkey) is essentially a pointer increment in the
| common case, so its not exactly expensive.
| 323 wrote:
| One good reason is to avoid polluting the global namespace.
|
| Otherwise you end up like Mathematica, which has ten thousand
| or so functions in a single namespace.
|
| Or PHP which had (has?) a similar problem (but on a smaller
| scale).
| paavohtl wrote:
| You can easily split stuff into modules without getting
| classes involved. For example the `Math` module which has
| been in JS basically forever.
| adam_arthur wrote:
| But they are on the global namespace. E.g. new Set() is same
| as new window.Set()
| 323 wrote:
| Right, but just the constructor. Everything else is a
| method of Set/Temporal.
| bern4444 wrote:
| The Temporal API supports a `from` method/function on most of
| the options - that's very much the functional approach to avoid
| `new`.
|
| Often objects that are class based will expose a `of` or `from`
| method that abstracts over the `new` keyword `Array.from()` is
| one example instead of `new Array()` (of course the most common
| way is `x = [1, 2, 3]` but these other options exist too).
|
| This seems fairly functional to me.
| newlisp wrote:
| Because they are obsessed in converting JS into Java.
| adam_arthur wrote:
| It's been a bit of a headscratcher for me.
|
| I was quite against adding the class keyword to begin with to
| be honest.
|
| Think a lot of that came at the tail end of the "JavaScript
| is terrible" generational mentality, and the idea was to copy
| other languages rather than improve what they had
| independently.
|
| To be clear, having additional functionality is fine in and
| of itself, but now the waters are mudied between function
| oriented and class oriented approaches, and by and large
| community seems to be settling on function oriented.
|
| In the end, class just created unnecessary fragmentation.
| egeozcan wrote:
| I was also happy with prototypes, now when I use them, and
| I use them rarely, other developers look at my code like
| black magic and my "others should be able to understand my
| code" circuit breaker kicks in and I convert it to a class.
|
| Is it more readable? Yes.
|
| Do I feel like we are dumbing JS down? Yes.
|
| Is it worth it when we consider that it helps onboarding
| hundreds of thousands of developers who want to choose JS?
| Oh f* yes!
| adam_arthur wrote:
| Creating prototypes in general is not necessary for 99%
| of JS code. Using completely cloned/closured functions
| will perform just fine for the majority of use cases...
| And the code there reads very simply... Just a function
| that returns an object that has functions.
|
| Or you can simply separate out functions into utility
| objects rather than attaching to the specific data
| object, and performance should be the same as using
| prototype, without any of the special syntax
|
| This model of programming is also much simpler, I'd
| argue. There is no use of "this", everything is explicit.
| Especially in JS, "this" sucks because the semantics
| change depending on whether you use function declarations
| or arrow functions. And "this" will also reference the
| caller, so changes if the function gets passed around.
| Much more obvious to pass an explicit argument to a
| function than to rely on "this"
|
| I do agree there are use cases where prototypes are more
| useful, performance sensitive games/server code etc. But
| pretty rare that you can't take one of the approaches
| described above. And people writing performance sensitive
| code aren't generally also going to be the newbies.
| Additionally, could have had syntax sugar for functions
| that wired prototype without the new/class paradigm,
| which I argue just adds unnecessary verbosity to the
| language.
| egeozcan wrote:
| I was just replying to the class vs prototypes part.
| There usually is a once-in-a-year situation that is
| solved better with classes, so I somewhat agree with your
| 99% code doesn't need it estimation.
|
| Also I should mention that in the rare case when I did
| use the prototypes, I always used the adapter pattern (an
| adapter function that takes a slice of "this", calls an
| independent function, and merges it back to "this"), it
| was easier to test.
|
| But people are so unused to declaring dependencies as
| parameters (even function dependencies aka services),
| they cry untestable whenever they see independent
| (static) functions. I know this from the PHP, Java and
| .NET world. To this day, it didn't help to explain what
| they call DI is just passing parameters (but rather more
| bureaucratically).
| wruza wrote:
| What you propose will likely drive the code to functional
| equivalent of FacadeAdapterArrayController, but written
| not only once but in every line of code. Because think of
| what even a simple .filter().map().filter() would expand
| into. Of course we can just _stream()_ or | everything,
| but the original "simple functions" idea will quickly get
| lost in the woods.
| adam_arthur wrote:
| Not clear how you're reaching that conclusion. Native
| constructs can still implement prototype methods
| transparently to the developer without the class keyword.
| Just as devs could in userspace.
|
| But contrary to what you're saying, most popular userland
| libs are indeed function oriented, and they don't end up
| like you're suggesting. E.g. RxJS, lodash
|
| By function oriented in this context, I mean that they
| don't rely on the new keyword for ordinary code. Which
| reads cleaner
|
| Anyway, functional stdlib can be pretty clean, such as
| something like Stream(persons).filter(person =>
| person.age > 18).map(person => person.firstName).
|
| Also there's the Pipes spec in the works that would allow
| for chaining distinct functions that are not on same obj.
| Not sure of current status
| lowwave wrote:
| For sure, do also see cases where class can be good working
| with a larger team. However, since js's biggest advantage is
| function as a first class citizen, I do feel like they ought
| to make the API to be functional., however OO design may
| attract more developers coming from OO programming world.
| wruza wrote:
| First, how do you tell a date from a string or a number easily
| in the code. Second, the functional thing happens for many
| reasons, and biggest ones are practical. You can't DCE
| (treeshake in hipsterish) classes in js due to highly dynamic
| semantics, but builtin code doesn't suffer from that. If it was
| a non-special type, then _maybe_ it was worth just Foo(), but
| usually there are some methods attached to it as well as
| introspection capabilities like toJSON(), toString(), etc.
|
| _The community seems to be moving towards functional
| programming /away from classes_
|
| The community moves to where React is, no real CV choice. Other
| parts of the community are non-functional, e.g. new
| WebpackPlugin, etc.
| adam_arthur wrote:
| The community was in the functional space before react.
| Angular 1 was very function oriented too, and relied heavily
| on ordinary functions and closure scope rather than class.
| And then everybody latched onto class in the phase of time
| between angular 1 and next gen frameworks.
|
| Class was something pushed by all the next gen framework
| authors at the time. Then most next gen frameworks abandoned
| class, because it proved to be worse in many ways than
| ordinary functions did. Which was the position I held at the
| time, and seem to have been borne out.
|
| The easy way to tell types apart in ordinary JS is to have
| consistent naming conventions. If you always name things such
| that the name implies the type (not Hungarian style, but more
| natural language oriented), you can infer the type from the
| name correctly 90% of the time. E.g. always write arrays as
| plurals, map-like objects as keyToValue, and so on.
|
| But the easier answer is to just use Typescript.
|
| Inferring type from instantiation point is pretty meaningless
| anyway. The type needs to be inferrable at the consumption
| site to be readable, not the production site. Understanding a
| type only matters in the context where it's used
| chipsa wrote:
| > (not Hungarian style, but more natural language oriented)
|
| Apps Hungarian wasn't actually a stupid idea. It just got
| bastardized into Sys Hungarian, which was. Apps Hungarian
| could tell you whether the string was unsafe (and needed to
| be sanitized), or safe to use. Or tell you if the integer
| type you were using was an offset, or a row number, or
| whatever. It was supposed to give you semantic info that
| wasn't necessarily obvious from the given type.
|
| Sys Hungarian told you that you were using a long pointer
| to a zero terminated string. But not what the string
| actually meant. It just regurgitated the type of the object
| again.
| olliej wrote:
| What do you mean by ordinary functions? There has to be some
| value to represent a date or time that you pass around, so
| something somewhere has to return it.
|
| If your concern is `whatever(date)` vs `date.whatever()` then
| the issue you run into is pollution of the global object, which
| is bad, and frequently not possible due to naming collisions
| with existing sites (fun story, `let` required some exciting
| rules to deal with existing content using variables named
| `let`). Given an inability to add a million new functions to
| the global object your concise `whatever(date)` becomes
| `Temporal.whatever(date)`
| LAC-Tech wrote:
| > The community seems to be moving towards functional
| programming/away from classes..
|
| Anecdotal observation follows:
|
| In the span of my career so far it looks like the community
| moved from imperative programming with a few classes/prototypes
| sprinkled in there, to imperative programming with a few
| lambdas and HOF sprinkled in there.
|
| I've yet to come across anything significantly functional or OO
| in the wild, it's still mostly plain old data mutable
| structures and for loops.
| livinglist wrote:
| I kinda agreed
| devadvance wrote:
| Excited to get to use this. One area of concern is i18n. The
| article touches on this briefly at the end, but I hope a zoned
| value can be used with Intl as well; having to use only Plain
| values would be frustrating.
| tmikaeld wrote:
| Awesome, hoping to see this in Cloudflare Workers as soon as V8
| has it! (Currently using day.js)
| TameAntelope wrote:
| > Modern alternatives such as Day.js and date-fns may be better
| but should a library necessary when your app has minimal date-
| handling requirements?
|
| Yes? Or at least, I don't think this is the, "obvious question
| that leads to the rest of the article" that the author may have
| assumed.
|
| As another commenter mentioned, Day.js is 2kb. That's the answer:
| use Day.js.
|
| But I guess that doesn't get you a blog post you can reference
| when applying to jobs, so here we are.
| nobleach wrote:
| From someone who used MomentJS back in the day, Day.js is such
| a nicer alternative! Moment was like 59k or something!
| the__alchemist wrote:
| Both the builtin lib, and the popular moment lib are missing
| separate date and time types, which leads to subtle errors. (ie
| when using their workaround of using datetime types for either).
| From the article, it appears Temporal has the same problem.
| There's nothing wrong with mutable types, which is common in JS
| discussions; the problem is when the API mutates in place where
| this isn't obvious.
|
| I hand-wrote date and dt types with basic operations instead.
| Limited functionality, eg timezones, formatting etc, but behaves
| as you'd expect.
|
| Another option might be to wrap Rust's Chrono lib in WASM, then
| call from JS; it's the best DT lib I've seen in any language.
| spankalee wrote:
| There is a separate time type: https://tc39.es/proposal-
| temporal/docs/plaintime.html
| the__alchemist wrote:
| Awesome. It looks like it has a PlainDate type as well.
| yashap wrote:
| Nice, it looks to be quite similar to the Java 8 date/time APIs
| (java.time.*), which are excellent. Looking forward to this!
| ferdowsi wrote:
| Ironic because Javascript's Date behavior was also modeled
| after the original java.Util.Date (which was immediately
| deprecated, whoops).
| stickfigure wrote:
| Why is that ironic?
| lstamour wrote:
| Because copying Java got them into this mess? ;-)
| yashap wrote:
| Yeah, but the Java 8 date/time API has been around for
| ~7-8 years, and is basically universally loved, while the
| original java.util.Date was hated for ages. Plus Java 8
| date/time is based extremely strongly on joda-time, which
| hit 1.0 about a decade before that, and was also pretty
| universally loved.
|
| So we're dealing with an API that has been considered
| great, and an excellent way to deal with dates/times, for
| nearly 2 decades. Seems like a safe bet to copy :)
| bluedevil2k wrote:
| There's a direct JS port of Java time as well - https://js-
| joda.github.io/js-joda/
| mikeocool wrote:
| Wahoo, it doesn't use 0-indexed months! Probably the biggest
| cause of bugs with js Date objects.
| mkotowski wrote:
| That does remind me: why that even is a thing? Ordering days of
| a week from zero can make sense since there is Monday/Sunday as
| a week start divide, and this can be seen as a bypass (0/7 as
| Sunday and 1 as a Monday), but with months?
| tshaddox wrote:
| Zero indexing for arrays/collections generally makes sense.
| If you had the months in a normal array they would obviously
| be zero-indexed (unless you deliberately put a placeholder
| value in the first position in the array, which would be
| pretty weird since all the normal ways of getting the first
| thing in the array would break).
|
| The reason it apparently feels weird to many people to have
| months be zero indexed is that months are often _referred to_
| by their ordinal number, and ordinal numbers obviously start
| at 1.
| yunohn wrote:
| > months are often referred to by their ordinal number
|
| What do you mean by "often"? Humans always use ordinal
| numbers for counting things like months, days, weeks, etc.
| There is no concept of 0 to be applied here, except for
| programming array indexing purposes.
| tshaddox wrote:
| What I mean is that people use the ordinal number as the
| _name_ of the month (as well as the day of the month). If
| you ask someone their birthday they'll often say
| something like "five twenty, nineteen eighty-four."
|
| This is a potential cause for confusion when writing
| computer code, because it's very common for code to refer
| to items in a collection starting at zero.
| kevin_thibedeau wrote:
| It is lifted from C's struct tm. If you're maintaining
| tables of month names you're going to 0-index them so
| tm_mon is 0-based to facilitate that.
| istjohn wrote:
| Lay people indicate the month with an ordinal all the
| time since it's how dates are standardized (12/30/2021).
| People don't often indicate the day of the week with a
| number, they use "Monday" or "Tuesday". So there's no
| strongly held convention in people's minds about how to
| number days like there is for months.
| WA wrote:
| Even if this is true, days in JS still start at 1. It is
| inconsistent.
| lucian1900 wrote:
| The week starts on Monday in most of the world.
|
| Date & time APIs must match local reality.
| pavel_lishin wrote:
| When reality differs by locales, at least one "local
| reality" won't match the API.
| mikewhy wrote:
| https://stackoverflow.com/a/41992352
| SippinLean wrote:
| > it was copied from Java's JDK1.0 (1995) java.util.Date,
| which also had this quirk
| jauco wrote:
| No. It's definitely older than that.
|
| https://mobile.twitter.com/hillelogram/status/13292284196
| 289...
| mikeryan wrote:
| Just because the issue predated Java doesn't preclude the
| fact that the initial JavaScript Date implementation was
| lifted from java.util.Date. Brandon Eich has explicitly
| stated it was so.
|
| https://maggiepint.com/2017/04/09/fixing-javascript-date-
| get...
| Taywee wrote:
| Twitter is such a bad platform for this. Code in images
| means it's completely inaccessible to the blind and very
| inaccessible to people with poor vision, and you can't
| copy and paste it into an editor for syntax highlighting
| or better examination.
| [deleted]
| matsemann wrote:
| Another one is JS parsing numbers with leading zeroes as octal
| (unless specifying base, which is why linters are so strict on
| it). Often surfaces when parsing date strings.
| toomanybeersies wrote:
| That hasn't been the case in JS for almost a decade.
|
| parseInt('0700') returns 700. But parseInt('0x700') will be
| parsed as octal, so now it's just a more subtle gotcha.
|
| Loose parsers (such as parseInt(), and Date.parse() in JS)
| are one of the worst ideas ever. Nothing like tracing a bug,
| and finding that a junior dev is trying to parse DD/MM/YYYY
| strings using Date.parse(), except that instead of throwing
| on trying to parse an incorrect [non-RFC] format, the parser
| makes a best-guess and propagates an incorrect date because
| it was parsed as MM/DD/YYYY.
| alkonaut wrote:
| Not sure why any api ever had functions like float.parse(s)
| or date.parse(s). Even more modern ones like .NET (circa
| 2000) had it. And it's literally _never a good idea_. Not
| even for a one off script is it convenient or ergonomic to
| omit the information about what format you expect (or try
| to suck it out of thin air such as a static locale on the
| thread). It 's just a bad.idea. If it does accept date
| parse(s) it has to be with a fixed format (e.g. iso) unless
| specified. Not "system local format" or something. The same
| applies to number formatting. I haven't met one single
| person who prefers automatic string formatting to switch
| decimal point and decimal comma due to the system language.
| olliej wrote:
| Why would you not have a parseFloat/float.parse/whatever?
|
| Parsing floating point values correctly is not a trivial
| amount of work - to the extent that there have any been
| security vulnerabilities in implementations.
| matsemann wrote:
| They are not arguing about the stdlib including them, but
| the api they choose. Instead of parseFloat(str) that
| tries with a system dependant comma or period, have the
| decimal type be a parameter or have two explicitly named
| functions.
|
| Same with dates. Don't try lots of formats on an
| arbitrary string, force the user to specify the expected
| format somehow.
| alkonaut wrote:
| Of course it should be a api but it should be either
| explicitly requiring a format OR (more likely) default to
| an invariant format.
|
| That is, if I do this float f =
| 123.456; Console.WriteLine("value is "+f);
|
| The output shouldn't vary depending on whether it's run
| in France or the US (which it does by default).
|
| For parsing, the argument should even be explicitly
| required I think. So float f =
| Float.Parse("1,23", frenchLocale);
|
| So that it's not ever forgotten or the reader has to
| wonder if the author forgot it.
| olliej wrote:
| JavaScript's numeric parsing is locale independent.
| People write too much code blindly to make any kind of
| locale inference anywhere.
|
| Otherwise I agree with you whole heartedly - I have been
| stung by absurd locale dependent behaviour in the past
| (windows' font loading APIs inexplicably translate the
| font variant _in the programmatic api_ )
| toomanybeersies wrote:
| I wonder how much of that has to do with the fact that
| ISO8601 was relatively newer back then (published 1988),
| and date formats were much less standardised 20+ years
| ago.
|
| For instance, RFC 1945 (HTTP 1.0) specifies three
| acceptable date formats. Add ISO dates, and now you're
| writing software that needs to handle 4 different
| formats. Easier to just use a heuristic parser that's
| capable of accepting HTTP, email, Usenet, and ISO
| timestamps.
|
| Fortunately, these days it's generally considered a bad
| idea to use anything but ISO timestamps, with the
| exception of a former colleague who tried arguing that
| DD/MM/YYYY was an acceptable format to be transmitting
| and storing dates in.
| postalrat wrote:
| Years aren't 0-indexed either. Nobody has a problem with that.
| llimos wrote:
| Betteridge's law does not apply here!
| dragonwriter wrote:
| Temporal is great, and the sooner it lands and is usable the
| better (AFAIK, there isn't a production-grade polyfill yet.)
|
| In the interim, JS-Joda [0] seems pretty decent, and doesn't use
| the wrapper approach.
|
| [0] https://js-joda.github.io/js-joda/
| httgp wrote:
| My favorite has always been Day.js [0] - it is really small,
| has a very clean API, great documentation and does pretty much
| everything I want.
|
| [0] https://day.js.org/
| moogly wrote:
| Used that as a replacement for momentjs until we had to make
| things seriously timezone-aware, and some quite crippling tz
| bugs (granted, probably 2 years ago now) made us move to
| Luxon. That worked well, but I'm glad to have something
| JodaTime-ish coming now that doesn't conflate instants with
| zoned datetimes with durations.
| aidos wrote:
| It's not really the same thing though, right? It doesn't
| handle instants vs zonedtimes etc.
|
| Even the simplest of future cases is handled poorly by these
| other libraries. If you want to say that something happens on
| a certain date in the future (say, a due date), your only
| option is to use an instant as an approximation (often
| midnight utc on that day). It works ok, but you're better to
| have a proper datatype that represents a day without a time
| and timezone component (it's effectively a 50hr ish window).
| Temporal gives you all that and more.
| aidos wrote:
| I've been keeping an eye on it myself. The implementation in
| Chrome looks pretty complete already, which is promising.
|
| I don't quite get the point of the other libraries like moment
| etc. They have a bunch of convenience stuff, but unless you've
| modelled the different _types_ of times that crop up in real
| life, it's all a bit pointless. When I first read through the
| Temporal api, I was physically nodding along in agreement. It's
| dates and times done right in js. Can't wait to be able to use
| it.
___________________________________________________________________
(page generated 2021-12-30 23:01 UTC)