If you are considering switching to a (different) date library, I would suggest to hold off. ECMAScript is about to introduce a native date and time API that is much better than the current Date functionality. It may also make the need for a third-party date library obsolete (as long as you do not need to parse custom date formats).
As far as I know, issue #1450 is the last remaining blocker for the standardization. I'd assume that this will be resolved in the next months. So Temporal will likely be officially released with ECMAScript 2023, but browser vendors and other implementors will start shipping it before the offical release.
Welllll… “works right now” is perhaps an overly strong assertion when it comes to day.js. I was working on a library we use for parsing "schedules" (like, alarm turns on at 9:00pm on Thursday, and off again at 7:00am on Friday). I was doing things like computing the number of seconds until the next scheduled transition. I tried switching from moment to day.js, and my unit tests immediately failed. Within a couple of hours I’d opened two bugs [1][2], both related to incorrect behaviour in corner cases (like generating the incorrect date when near a daylight saving time transition).
The fact that it only took me a few hours to find these suggests there are plenty more bugs like these to find. The fact that these bugs have been open since the start of March with no movement on them suggests they aren’t too interested in correct behaviour (or perhaps they’re just your typical under-staffed open source project).
Maybe I just got super unlucky and ran into the only two bugs here… but it’s not likely.
Luxon and moment.js both handled these cases perfectly. If you’re looking to move from whatever you’re using now, and you can’t wait for the new standard, I’d pick one of those.
They mentioned "switching" which implies an already working solution. Within that context, yeah, maybe wait a few months if you can afford to.
Also, once the spec is finalized, there may also be a compliant polyfill available. If so, you'll get the functionality early and still have good compatibility down the line.
If you have something working, perhaps delay refactoring to a new library.
Or as it is coming RealSoonNow(tm) perhaps start looking into polyfills as you are going to need one anyway for a story time at least to support LTS browser versions.
you don't need to hold off - you just wrap the library in an api of your own, specific for your usage. Then, when/if the ecmascript standard library adds a good one in, you just need to re-implement the wrapper, which would be presumably pretty easy as the api surface area is fairly small.
If I were helping someone start a web project _right now_ I'd probably tell them to just use Moment.js and forget about it. Any live web product I've ever worked on has always had more than enough to work on to keep updating the date-time library at the bottom of the to-do list almost indefinitely.
I was tangentially involved in the back-end data part of a web project in the last few weeks.
Right from the beginning, I told anyone who would listen that the underlying data was in UTC. So far, so good.
They get to T-24h for the client's Big Demo Day...
...and someone in London, UK notices the front end UI times are all an hour out (that would be because the UK is still on summer time, UTC+1). I happened to be in Germany and after finally being given a login for the UI found that, wonder of wonders, the timings were two hours out!
<groan>
So we had to bodge the API to fiddle the times forward to UTC+1 for the purposes of the damned demo.
Someone is presumably going to find this in the repo waaaay in the future and ask themselves "wtf were they thinking?". I wish I knew the answer.
I wouldn't recommend anyone use moment.js if they're starting a new project. It's an unnecessarily large library, and the fact that moment objects are mutable almost always causes more issues than it solves. The only reason to use it is if you're working on software that is already using it. Otherwise use a more modern, immutable datetime library like day.js, date-fns, or luxon.
Having read the cookbook [1], and wow that's a complex API out there. I can see that there will be a `Temporal Light` to allow us to do `now().startOf('month')` like calls.
Moment.js was one of our biggest dependencies, and the transition to Day.js was easy. I'm certainly glad we didn't hold off. I'm sure we'll switch to Temporal eventually, but it's misguided to suggest everyone should wait a year or more to improve their sites just to save a little effort in the interim.
One has also got to hope that Temporal offers all the features a well built daytime library does offer. What good is it if Temporal is lacking that one feature you need, so that you end up including another library as well.
By then you can assume that the other library will be a lightweight wrapper around Temporal.
The mutability in Moment.js is not really a feature though, just a massive inconvenience/source of bugs (unless you use `.clone()` all over the place).
It's not quite exactly the same API - you'll need to do some testing afterward - but if you're using Moment idiomatically, nearly everything should just-work
Both libraries have the greatest differentiating feature from moment: immutable objects. Being able to compose dayjs objects together without fear of modifying them afterwards makes everything a breeze.
Full disclosure I haven't used Luxon nearly as much as I've used DayJS, but I would say IMO DayJS is way simpler and more intuitive, this is a very small thing but for example, why would they format Months, by "L" instead of by "M"?
The other reason I like DayJS over Luxon is the sheer number of plugins you can pull in to do various things. Like for example I was building an application where I had to build a weekly calendar form for a timesheet, the requirement was weeks start on Saturday and end of Friday.
In DayJS I was able to do this pretty easily by doing: dayjs().startOf('week').subtract(1, 'day') to get the start and then took the result and did res.add(6, 'days') to get the end. I'm not sure if Luxon has this type of functionality.
Lastly I like the plugin architecture rather than giving you everything up front. By default DayJS does not include any of those cool transformations like I talked about above, you have to pull them in as plugins from DayJS, this results in a bit more setup but smaller bundle sizes at the end of the day.
> why would they format Months, by "L" instead of by "M"
"M" is used for months in Luxon, and is usually what you should use. "L" is only for standalone months, i.e. not within a date string, usually not what you want. In English these are the same thing, but in some languages they are different.
Day.js seems cool, but when I was evaluating these libraries I noticed the ‘startOf’ function doesn’t take a time zone argument… I guess it just presumes you want the system offset?
I can’t trust a date/time library that’s blasé about time zones at the API level. Undefined behavior around time zones causes a steady stream of off-by-one bugs in your codebase if you’re not vigilant.
As a dev who’s used all three, is there a massive difference? Not really. Stick with what you like (though moment is no longer maintained so maybe not that)
I never use any date library and I never had a problem with it.
I just use what the native Date() object offers.
Other devs always say "Just wait, one day it will fall on your feet".
But this has been going on for many years, in which my software has served millions of users and nothing ever fell on my feet. I think the complexity of a library like this (423 files, 1433 commits, 53004 lines of code) would have created more problems during this time. So not using one is a net positive.
Any minimal code example of what is prone to break without a date library and how this date library is supposed to prevent it?
Examples of essential complexity you have to worry about if you want your code to be correct, and even if you want to test/detect all issues that can/do come up:
In my experience engineers will often brush these sorts of things off as “edge cases”, but really all of these complexities are just how dates and time work in the real life (I’d argue that they’re just “normal cases” to test for)… So any anomaly in software will cause real problems of varying importance for users.
I posted about this elsewhere in the comments, but my experience with day.js is that if you're concerned with these kinds of corner cases, maybe day.js isn't the library for you.[1][2]
I only see this being an issue storing times as strings. Why not store them as integers (like a Unix timestamp) or at least some standardized string format? The only reasonable use case I can think of where you absolutely need all this complexity is if you're rendering a calendar or something similar.
It's 10PM right now. At what time should the alarm be set? 6AM? Woops, tomorrow is the switch to DST! What now?
User: remind me to brush my teeth on November 21st at 8AM.
Okay, will do! Wait, you took a plane on November 2nd and are now on the other side of the world? Should I remind you at 8AM or 5PM?
User: please note my doctor's appointment in two weeks at 10AM.
Sure thing bub! Wait, but you live in Morocco in 2019? And the government just announced that reverse DST will be in effect for the month of Ramadan, which begins next week?! WTF do I do now?
---
tl;dr It's not just an issue of storage. Managing time is hard. There are requirements that we, as humans, will intuitively find the right interpretation for, that computers will absolutely break their teeth on.
I mean, there is no way to write code to “handle” this that isn’t just guessing on the part of the programmer. The correct thing to do is to prompt the user for verification or further information.
> There are requirements that we, as humans, will intuitively find the right interpretation for…
Interpretation is subject to error. (Yes humans have immensely more context to work with than computer programs, but just because we we’re better guessers doesn’t mean we’re not still guessing.)
You can still add a library once it’s really needed and an area is proved to cause bugs. Most of the times though, developers will add them upfront “just in case”, making the bundles always heavier and thus harming the user experience with a slower UI.
I’d argue that we already know how time works, so the proof exists up front and there is no “just in case”.
You could make an argument that there are more important things to fix, but then you’d be deciding consciously that it was okay to ship software known to be incorrect.
I think you’re missing the point entirely. If Date has a method that does what you need, by all means use it directly.
Libraries come in handy when doing things that aren’t one liners.
A colleague thought it was super easy to change that exact ISO string to use the local timezone instead of UTC, against my advice. Guess what. The minus sign broke it and he would have never known because most customers are in the US, then they travel to Singapore and your product is worthless. By the time you hear about it, you lost the customer’s money and time therefore you lost the customer.
Moment and Luxon are too heavy, I agree, but date-fns isn’t.
Those articles are more empirical in nature than theoretical.
> This logs that an image with a given id was updated
As a thought exercise, imagine that your log trail needed to be created in a distributed system, spanning multiple machine time zones, or that you needed to build a report that is read from browsers in multiple time zones that differ from multiple differing written time zones, and you need to account for human readable things like knowing what day of the week it is and what some given locale calls that day.
If you are doing the equivalent of printf debugging with your times, maybe you likely don’t need a time library.
If you are using time as a central part of a distributed algorithm, web content, or a business workflow, then you may likely need a time library.
You are trying to convince me with the popular "This is not going to work for a much more complex system".
I heard it very often. I don't buy it. Any system, no matter how complex, can be composed of small, simple systems.
I never ran against a "complexity wall" when writing software in a lean way and suddenly thought "Damn, those tens of thousands of lines of library code now would be the better approach".
That’s very true. A colleague recently started using the same method and is achieving bundles and dependencies orders of magnitude smaller. As a result, he has to care less about security, build times and build breaks and spends more time coding. Developers have unlearned to build basic functionality apparently, especially in the front end area.
Moment and friends shine when you need to display and interact with dates from a human perspective. Calendars, scheduled events, etc., all are hard to do without something like moment.
Users in timezone A need to schedule events many months in the future in timezone B, and display them in a report in timezone C.
In addition, should the legal authority in timezone B change their DST rules in the meantime, the local time of the event as observed in timezone B should still be what the user initially selected, which is not the same in UTC as it was at creation time
And they would be guilty of misleading the consumer when doing so, and possibly accounting fraud as well because neither GAAP nor IFRS recognise such a calendar; the closest available is the 4-4-5 standard.
This is why we don’t let engineers write contracts. Many seem to think that law is a programming language in which they can redefine reality. It ain’t.
Yes, that's what we do mostly, except to track external subscriptions that actually use months (I believe the Google playstore does that but I could be mistaken with another service)
At some point you will need to calculate how many leap years to account for and whether or not a leap second was introduced in between two arbitrary times.
Absolutely. moment has a definition of that and compute it in a consistent way, which is useful. But if you want to come up with a different definition then it cannot help you indeed.
Can you write a one liner to give me the timestamp for start or end of current week, or month? How about a text representation of a difference between two dates? Relative date string (eg. “2 weeks ago”)? Date comparison between two dates that are in different time zones? Does your date calculations take leap hours and leap seconds into account? Date libraries make all these and many more operations a breeze, while rolling these on your own can be tricky, error prone and you’ll be just wasting your time.
> Can you write a one liner to give me the timestamp for start or end of current week, or month?
And... it's a multi tenant system, where some organizations use Sunday as the start of a week, and some use Monday. And they all want to be able to switch.
I've always found moment to just present the same problems you would otherwise have with a few new ones tacked on stated in a different and more complicated way but with a pitch site and artwork.
The js date is a bit primitive and moment looks easier but in practice it's actually a convoluted clunky type system that hides important nuance behind impressively bad defaults.
I approach all of these "better than what the language offers" solutions the same way: it would be truly remarkable if some kid had a more nuanced and correct take then people with years of experience and PhDs in language design who made the language but more likely, I think the kid who wrote the library is just better at drawing cartoon characters, hype posting on social media and making something popular.
I used to get immediate hostility and belittling insults when I stated this about 10 years ago. I think people have finally come around. Let's see how the replies go.
You are succumbing to the fundamental attribution error.
You described your comment being an attack on modern development culture, as your use of euphemism, you chose the insultingly denotative word “kid” to attack the project.
Intentionally unspecified. This isn't a personal attack but instead a systemic and cultural critique
It's been like this for decades. Emotional salience sells software better than hard practicality to just about everyone. Then people rationalize their irrational choices then the timeline slips and the product sucks.
You can just sit and watch it play out like someone studying monkeys. It's remarkably predicable.
Formal peer-review does trump download count, nonetheless.
And I’m all for professional licensure, continuing education programs, and formal, public reviews of the software engineering behind the open source libraries that comprise global infrastructure.
You see something that looks like it's pretty popular. You try it. You find it has nothing but problems. After much research you then find out that other people don't have the level of sophisticated asks for the product and they are doing less complicated and less critical things.
It's the disconnect between the hype and the reality that really rubs me the wrong way. I've personally lost so much time on inappropriate tools.
Again I'm not here to insult anybody specifically or to speak poorly upon any specific product. I know how many people read these comments and I don't want to cast shade on anybody's hard work. I just wish there was more authenticity to the fit and purpose of things.
I know a lot of this depends on the users. I speak as somebody who has very popular projects and very not so popular projects. The popular ones are hyped (but sarcastically) and the ones that I worked very hard on to be extremely technical about do quite poorly.
To make things super current I haven't working for about a month on an article and I have been making sure it is extremely accurate and I know that that will probably hurt me because the liberties which inherently contain inaccuracy are simply more entertaining
This is a shared experience except for a select few. This carries is over to other things. Inaccurate pop science is read much more widely then the direct research material. There's something more emotionally approachable through this tactic. It just hurts productivity and it's a shame
> I think the kid who wrote the library is just better at drawing cartoon characters
Quoting your writing that is probably rubbing others the wrong way, as it certainly reads easily as being specific to “these” solutions, as you put it.
You might avoid triggering people’s negative emotions by sticking to your main point and avoiding the marginalizing.
What is the obsession with xKB? With tracking, analytics, monitoring and gazillion other scripts, I'd wager that an average webpage size is probably closer to 1MB.
Checked some of the popular sites (caching enabled)-
> I'd wager that an average webpage size is probably closer to 1MB.
And the average American is heavier than they should be. Doesn't make it ideal. Always endeavour to trim the fat.
This is HN, and despite the likely predominance of US big-city devs here, I'd wager that most of them like money from rural dwellers just as well as they do the money of their fellow city-slickers.
When you can, you save, you’ll be faster. Also you are more willing to include more libs if they are all small, and more easily include new big ones when necessary without the soon need to rewrite your code as it became too big.
I love dayjs! I’ve been using it for the past 4 years in most projects and I have no issue at all. Current company used moment, but recently they also changed to dayjs as well. Love to see the author being very active in github as well :)
Moment has always been absurdly large. There's really no reason for it. The vast majority of usages can be solved with 4 lines of native `Date` object based code.
I'm a fan of Moment... it's served me well for most of a decade, including in some really heavy scheduling/timetable applications. The size of importing Moment is really fairly negligible for a full-scale single page app. The one drawback I find with it is the overhead for creating new Moment objects. You never want to, for instance, run through a for/next loop of SQL dates and convert each into a Moment for sorting. If you must have them as Moments, you really need to cache once and compare later. Usually in my code I even avoid writing `new Moment()` within a control structure that only needs the current day or hour, and I set up an interval to run permanently in a utility class to just cache a recent Moment every 10 seconds or so, for comparison wherever else it's needed in the code.
That's the only real issue for me with Moment and I'm not sure this lib would change that... especially if I need to extend it for various uses every time it's called, which for me would be a rather large drawback that would end up polluting lots of modules with extra lines of code for specific date comparison purposes.
> The size of importing Moment is really fairly negligible.
This attitude is why large parts of the Internet suck these days.
I recently visited a friend in Kallithea, Athens, Greece. With his Internet connection, that would add about half a second. It‘s a typical speed for residential connections in Athens.
Again, my context here is a large (1-2Mb) single page application. I wouldn't use a library like that in a static/informational webpage, and it's hard to think of a context where it would be necessary.
It's embarrassing we never evolved the date api which comes with the browser.
That said, I tend to err on writing a custom function / importing only a custom function over importing an entire library just to run a 2 lines function.
It’s literally final pending commitments from/to another standards body. If they hadn’t made that commitment there’d be people chastising them for something else. I swear to fuck, we can’t have nice things because no one will ever accept having nice things.
not bad, a quick skim of the repo shows that the locale file sizes might be 50% or less as compared to Moment.js - approx. 1 kB per locale from day compared to 2+ kB per locale from moment
Interesting to see the support for luxon. When moment was announced as a done project they recommend a number of alternatives; one of those was luxon. Date-fns was also in there, and given I was already using it I carried on my merry way! I'm curious what the difference between luxon and date-fns is. Npm trends are interesting
IIRC, moment's website listed luxon as their recommended replacement via a top-site banner. The banner seems gone now, but luxon is still the first listed on the recommendations page.
Btw most libraries (luxon, dayjs) that use Intl api to do timezone manipulation in chrome and nodejs and are excruciatingly slow. So slow that pods would get restarted because they would fail to respond to health check while doing the timezone manipulation, on moderate traffic (50req/s). I still use moment-timezone because it comes with it's own tzdata and it's 100x faster.
Not sure if this is a gotcha, but how does one make a JS date object (across Safari, FF and Chrome) that refers to the same day of the year regardless of timezone?
There's an error in the documentation. What's the standard procedure to submit a pull request or bug report here? The docs subdirectory just links to the website and I couldn't find them in the gh-pages branch, either.
- https://github.com/tc39/proposal-temporal
- https://github.com/tc39/proposal-temporal#polyfills
- https://tc39.es/proposal-temporal/
- https://tc39.es/proposal-temporal/docs/index.html
- https://github.com/tc39/proposal-temporal/issues/1450
- https://tc39.es/proposal-temporal/docs/parse-draft.html
As far as I know, issue #1450 is the last remaining blocker for the standardization. I'd assume that this will be resolved in the next months. So Temporal will likely be officially released with ECMAScript 2023, but browser vendors and other implementors will start shipping it before the offical release.