We now consider Moment.js to be a legacy project in maintenance mode
momentjs.com
momentjs.com
Done is good. Done should be the goal.
But it’s not. Because if you’re not adding new features and pushing code changes every day, your project is abandoned, dead. To quote another thread from two minutes ago: “I’m quite sad to see the end of Moment.js”
I wish the was a way to fix this attitude. So that project maintainers didn’t need to write two page apologies for finishing their thing.
In this case, the reason why Moment.js is "dead" and not "done" is because it has fundamental flaws in its design: Mutable objects + huge bundle size which doesn't work well with tree-shaking.
Trust is major factor when depending on third party libraries especially in the JS ecosystem.
[1] reason libre office or deno gains traction
Until very recently it was impossible to make objects immutable in JS. Even now its really only done using third party libraries.
Huge bundle size is only a problem because tree shaking is done on a "module" level. Most languages are static enough that it's called dead code elimination and doesn't need to use tree pruning. You can tell statically that the code is not used.
Moment isn't compatible with modern workarounds which I don't blame it for. The way JS is, immutability and true dead code elimination will probably show up as built in features in a few years and make all this obsolete again
There's a big difference between "literally impossible to mutate" (only important in the most security-critical contexts) and "designed around immutability as the default" (which is what is desired in most of the real world.)
The former not being possible is not a reason to exclude the latter.
When all your objects are hashmaps you can't really make fields immutable. Even if you wrote getters, someone can just reassign the function reference.
Even if you check your fields in incoming object parameters, somebody can randomly add more fields that you don't know about. Until recently you couldn't stop people from randomly adding fields to your objects
Nowadays JS supports stuff like freeze thaw which makes it easier
You don't need, or particularly benefit from, language-level mutability to specify the next state of UI as a function of previous state plus new inputs, which is really the best way to model interactivity.
One of the shortcuts is that all objects are hashmaps. Fully mutable hashmaps with string keys. You can do this:
obj.prop = "hi"; obj["prop"] = "bye";
And you set the same field. And you can do that to any object, reassigning any field type.
Most languages have static number of fields in an object, or at least static types for fields already created.
Another huge shortcoming is prototype chain based inheritance. Someone can rewrite a random link in your chain and suddenly you have another object type entirely. It's also very bad for performance. Essentially, the inheritance tree of an object can change at runtime.
And since they aren't intractable, and smart people regularly decide that it's worth the downsides, you're making the uninteresting observation that $lang has warts.
My point was that the reason we’re transitioning away from it is because of technical reason, not because it’s not being updated.
I kinda hate being vindicated years later, the time in between as an outsider kinda frustrates me.
I wish we had a more thoughtful, less packrat culture in programming. Fighting off the pushback is exhausting. It's not even worth bringing things up most of the time.
And as a disclaimer to those feeling tempted, I've got zero interest in debating this reality, water is wet.
The important thing to keep in mind that we don't know which of today's counter-culture takes will end up winning (I don't say "being right" because cultural evolution is, like biological evolution, not teleological).
In other words, you had a belief, and in hindsight you were "vindicated". But there were many others who had equally strong beliefs that were not.
moment has a, to me, counterintuitive "hidden" type system that is a different-kind-of-menacing. In code I've had to review and maintain, the moment parts or more than often a soupy mess of the previous coders in combat with the nuanced hairy complexities of the library as opposed to straightforward execution of the api (compare to say, jquery, where setting all architectural disagreements aside, there's no substantial evidence of frequent "programmer struggle" in the codebases using it)
This leads to poor long-term maintainability as the code passes through many hands over the years.
If, after a year or two of average "blue collared" programmers touching a codebase it gets so convoluted that you generally need to abandon it, then fundamentally you are using poorly designed tools.
Again, we all only have our own personal lived experiences to make such assessments on, and I way too often end up "debating" what mostly amounts to my work history of parachuting in and rescuing code (it's a psychiatric problem I have) so the pessimistic aspects become quite sharp to me.
Now give me a golang library that hasn’t been touched in four years and it would be a completely different situation (knock on wood go2 doesn’t ruin this).
So actually there are many libraries and tools that could be done and just work forever, timezone stuff is much more dynamic than I'd ever realised.
FWIW I loved moment and made the move this year to date-fns[2] as I trusted browser availablity of the prerequisites enough to finally switch, and I do like working with it, but its focus on lightweight makes it less "magic" than Moment.
- [1] https://www.insider.com/europe-to-get-rid-of-daylight-saving...
- [2] https://date-fns.org/
(edit formatting)
https://en.wikipedia.org/wiki/French_Republican_calendar#Dec...
https://en.wikipedia.org/wiki/Traditional_Chinese_timekeepin...
I think the parent’s point was that things like security updates still need to happen. So there may be scrutiny if you come across a package and there hasn’t been a change for a couple of years, in the JS ecosystem it would raise red flags for many. Maybe not so much in the Go ecosystem.
And the purpose and tone of the article does not seem to be an apology at all, but rather simply setting the expectations for future work so that the maintainers don't have to answer the same questions over and over.
Overall, good to see honest documentation of project status.
Re: "obsolete"... jQuery is somewhere laughing, having gone through this already.
If there were nothing to fix, they wouldn't be telling people not to start new projects with Moment. They actually do mention a few significant issues that they can't / won't fix in Moment such as bundle size and mutability.
I will concede that perhaps Moment was "done" at some point before, some years back. When it was quite complete, yet was still the best way to do reliably work with timezoned dates in JS. But as Intl support improved, and better designed alternatives grew, it got rather obsolete, and will get more obsolete over time.
jQuery for comparison, while largely obsolete for rich web app development, is still very relevant to ecommerce, website-development-for-hire and other niches, and it will probably stay that way for a long time because it's the right design for those problems. Moment isn't the right design for any problem anymore, unless, as the article says, you need to support old browsers.
I'm not going to stop using moment in new or existing projects for petty reasons like the ones presented. I'm tired of having the rug pulled out from under me every time I'm comfortable with something.
I think it is. It basically solved all the problems that were there at its inception and the world moved on. It continues to offer a solution for the original problems (which legacy software most likely still has) and can still be used with minimal engineering effort.
I would call that done.
There is a widespread meme/trope about something being "dead". Whenever I hear someone saying that a language/library is "dead", I make a point of checking that person's credentials. It almost always turns out that these are not people who write big applications or well-known libraries, but rather ambulance chasers — constantly looking for the next shiny thing.
One of the problems is that GitHub is full of OSS libraries where the last commit was three years or more ago and you have no idea (without forensically analysing commits, issues, etc.) whether it's because the project is done or because the maintainer(s) lost interest, had other priorities, etc.
And you have no idea because they haven't said. They haven't told anyone: it's just drifted into an unclear state of unmaintained-ness.
I would suggest rather that what the Moment.js team have done here should be the norm: i.e., clear communication of the situation. That situation, as here, might be "done", or it might be "the thing's only half finished but we don't care enough to carry on any more", or something completely different. These are all good reasons to stop working on something even if they're potentially frustrating for users. E.g., in the "don't care" scenario, people have the option to step in and pick up maintenance, fork the project, or simply not use it.
Doesn't matter: understanding the state of a potential dependency in terms of maintenance and development is the key factor that will enable people to make an informed decision about whether to use it or not.
I don't think there's any at least medium sized project that is considered to be done but not abandoned/legacy and does not receive any commits.
Any non-trivial project that has no commit since the last three years is abandoned. Even in the case a project is considered to be done/finished, in order to not abandon it you have to maintain it: fix security issues, update outdated dependencies, update tooling so that you can still run/compile with non outdated tools and so on.
If you spend some time and effort removing whatever obstacles you have in place that are keeping you from being able to do that, you'll have a lot more free time to spend building new things.
For what it's worth, this world does in fact exist. And there are lots of us living in it. Here's hoping you find a way to join us!
Some programming languages make guarantees that old code will build in new versions (eg, ISO C even refuses to introduce new warnings for code that would previously build without warnings), while others will introduce backwards incompatible changes in minor releases. How much maintenance a project needs after it is "done" really depends on the tooling environment.
And, if it's open source and it's easier than switching to a new dependency, you can just adopt maintenance of the dependency—not necessarily generally, just enough to address any bugs induced in or evolution in needs for the project(s) you have that depend on it.
Sure it can; there's no reason a project has to take every upstream update, if, for instance, it vendors dependencies, or otherwise doesn't directly depend on the remotely maintained source.
Stability is great as long as you have the luxury of no pressure for new features or better security. (Eg. operating systems, browsers, compilers, critical libraries don't.)
Therefore you want to keep your code at least somewhat up to date so that people don't run into weird bugs.
For example, en-US excel will automagically parse TRUE and "TRUE" to be the logical value TRUE. The way to get Excel to see a literal string TRUE is to make a formula ="TRUE". Many CSV writers implement this hack specifically assuming files will be read back in Excel. So now your parser, if you're trying to process data like Excel, has to do the same.
So then you discover that this is actually localized! If you set your UI language to French (France), Excel will treat VRAI and FAUX as booleans while TRUE and FALSE are treated as literal strings.
What you thought was a simple CSV parser now has to handle localization as well. So that CSV parser library can roll its own dodgy localization support, use a tried and true solution, or just choose not to support the feature. Each choice has its own drawbacks
CSV, which isn't even a standard and the closest thing to a standard is a description of the breadth of different behaviors seen under the name at a particular point in time with some notes about their relative frequencies and respective practical issues, does, in fact, evolve.
Yep. For example you have to basically air-gap your software, no input/output, especially nothing that touches crypto/TLS/networks/protocols, usually no support for fancy file formats either.
Or you can just go ahead and implement all those by hand. Perfectly.
I mean it's possible, but bumping BoringSSL/Libre/OpenSSL version every few months seems easier.
¯\_(ツ)_/¯
I recently found my old GPS logger, and wanted to pull data from it. I installed "mtkbabel" package and it worked wonderfully. This code was last updated in 2013 [0].
I was recently copying some files from one of my embedded boxes. It had rsync 3.1.2, released in 2015. Still works and no need to upgrade (the page lists some security vulnerabilities for this version, but this is only for "untrusted server" scenarios, which I never have)
The embedded systems not connected to internet will generally work forever without any updates. I do have a 20 year old MP3 player and it still works fine.
[0] https://metadata.ftp-master.debian.org/changelogs//main/m/mt...
Browsers, compilers, SSL/TLS libraries, operating systems and so on doesn't have this luxury, and thus this has a knock-on effect.
Remember, the post I am replying to says "no commit since the last three years" -> "abandoned". The software life of 3 years is really not that long for many contexts.
I agree with that anything browser-related needs to be constantly updated, especially if you need fancy functionality. But if you do not need this functionality, then HTML 4 based stuff still works and does not need to be updated.
Compilers (and programming languages by extensions) do not need to be updated very often. 5 years ago we had gcc 5 and python 3.5. There is no reason to upgrade them at all if your build system does not require it (for example, if you use buildroot or customized emerge or docker). And you do want to use latest versions, then there is a very high chance your software will work with the latest versions without any changes.
SSL/TLS libraries are important to keep patched. Luckily, the critical faults do not happen that often. For example, last critical vulnerability in OpenSSL was in 2016 -- so you really did not need to update your SSL libraries in the last 3 years.
Operating systems upgrades are probably the biggest drivers for the changes. But again, Ubuntu LTS have full security support for 5 years -- so if you can require a specific OS (embedded device or container) then you can update the software only twice a decade.
The software world is very big. The web / GUI world is most visible of them all, but it does not mean everything else is "obscure".
I meant obscure as in: except from a very specific persistent and advanced adversary (APTs) no one will even try to hack something like that directly. Sure, it's possible, so it's put behind a lot of firewalls, middlewares, wrappers and message queues. At least that's how one insurance company I work with uses COBOL. And if they can avoid touching it, they won't, because it's so hard/risky/expensive, and the risk of external security intrusion has been deemed low. It's abandoned as a product, as a goal, it's basically an aging power tool at this point, that will eventually give up. (Like embedded stuff.)
I know 3 years is not that long. I'm just saying that the various forces (business and security aspects) that be usually dictate fast turnaround, or at least a certain minimal level of upkeep.
Java, C++, Rust, PHP, JS, etc. all have quite a big velocity nowadays.
Python 3.5 just got EOLed.
Sure, you don't have to upgrade every last piece of python script. After all RHEL and other distros still provide some py2 support too. And if your business is not growing fast, your build system is "done", then you don't have to touch it much. But eventually it'll need some maintenance, maybe just a few touches to keep it future proof, but that again also implies that it's a niche, a custom software that does what you need it to do, that's likely not a high-profile target directly.
Why you would need to modify your code because you have dependencies ? Libraries'API are supposed to be stable. You can update them when they need a security patch without having to change anything in your own project.
This is literally impossible for many JS libraries. Chromium / NodeJS / other JS environments are themselves constantly changing. Irrespective of the evolving timezone info, the core MomentJS can only be "done" for a particular set of browser versions. Each bug pertaining to dates, like https://bugs.chromium.org/p/v8/issues/detail?id=7863 , is a potential browser/engine version for which Moment needs a fix.
> this world does in fact exist
It only exists for certain proprietary software and SaaS developers because of the hard work of open source developers to keep up with the changing landscape. If everyone adopted your attitude, you would be forced to contend with the true nature of the ecosystem directly.
If you step back a little, you can see a "positive" feedback loop. The entire issue is that maintainers have to catch crazy rabbits who have no rest, change things and abandon "old" versions that worked but were not perfect. Perfect is the enemy of good.
As another commenter mentioned, this can be pretty common in math libs.
Here's an example: https://github.com/fommil/netlib-java
This project BLAS/LAPACK/ARPACK bindings for JVM languages. The repository is marked as archived and the owner explicitly states that the project is done. The last commit was 21 Jun 2017.
This project is still heavily used, there are still multiple libraries that use those bindings.
> This project is still heavily used, there are still multiple libraries that use those bindings.
Heavily used does not imply that a dependency is not abandoned.
So I’ll post here admitting to be wrong in my instinct.
TeX: The Program has had its most recent release in January 2014.
It's both a responsible thing to do and a form of virtue signalling. Yes, we are still here.
One case in point is (was) atftp. Since it's packaged with most distros you might be tempted to assume it's safe to use. But then I encountered a crash on Debian. Tracked down the official project page to sourceforge, found the bug was reported years ago including fix, nothing happened. Found it had several other issues like not checking return values of calls like setuid(). Debian at the time had their own patches for this in sid, since coincidentally someone must have hit the same issue around the time. Checked suse out of curiosity and they also had their own patches which were around for quite some time. Same with gentoo (I think). Obviously all three had different patches for different bugs, because unresponsive upstream. I wish there was a joint effort of distros for such cases instead of duplicating work. Or just drop dead projects with known security issues instead of this half arsed approach.
Sorry, second part is only semi related with the original issue but it's just one more way in which picking the right open source solution for a problem can be difficult because of lacking communication.
Does it? The alternative might be to write your own code, which will carry your own flavour of security issues. No matter what code you adopt, be it your own or someone else's, will require some level of commitment in maintaining it.
You can't tell if a project is dead by the commit dates, but you might be able to tell via open PRs that go unacknowledged.
In this case, considering the creators are discouraging people from using the package and explicitly saying there won't be future bug fixes, TZ/locale updates etc., it is pretty clear that done really means deprecated.
Older open source was more okay with this, but it's a huge issue with the modern JS/github model, where quality is measured by recent updates, "stars" within the last month etc.
I am wary to use software that is not maintained, because bugs won't get fixed, and new requirements that will eventually arise won't get taken up. And usually at that point a competitor rises up and releases a better product.
It takes a lot of guts to make this kind of announcement. When faced with younger, faster competitors, it's natural to try and fight your corner. This is rarely good for a software project.
The devs have put their hands up and called it off. They can move on to more exciting projects. The rest of us can make better decisions now that the thinking behind this decision is out in the open.
Congrats, moment.js, on a great project!
https://img.shields.io/badge/Maintenance-Legacy-success
or
https://img.shields.io/badge/Maintenance Level-Done-success
and have that as a convention.
Additionally to being easy to implement, it is literally a 3 second task for maintainers to add something like this into their Readme.
But in this case they also say they don't actually recommend Moment.js for new new projects, generally. "we would like to discourage Moment from being used in new projects going forward." In this case "done" also basically means "obsolete", "newer better alternatives exist".
That doesn't seem to be the kind of "finished" that you are talking about, or that would be a goal of developers. Or is it?
Examples of open source projects which are very popular, mature, not obsolete, still recommended by their maintainers for new projects -- but also "done" -- might be closer to what you are trying to compliment. They are definitely few and far between.
Those who have been developing it for years and are most familiar with it, and the alternatives, discourage it's use in new projects, although also outline the exceptions that in their opinion make it reasonable to keep using it. You are going to take a stand to disagree with them, based on superior understanding?
Uh, no. I read their list and the two things I cited (from their stated reasons) seemed to be the key drivers.
This isn't a universal attitude. Numerous language ecosystems exist where it's completely normal to use dependencies that haven't been updated in a while _because_ they warrant no change.
This is a problem with the general attitude of the community of JavaScript developers.
And they're too stuck in their JS ecosystem bubble to realize this isn't necessarily "normal" or "the way things should/have to be."
A great example is the issue newcomers to Common Lisp face. I don't want to get in specifics regarding the Lisp community here but one common complaint is that only "old libraries" are available and no recent releases.
Side note: Although I'm not sure it initially started in the JS community, it is by far the most affected community. Besides that issue it also suffers from Not Invented Here syndrome.
They don't need to write me an apology, but just a notice like this one is very nice so I can be sure what is up.
For a real example, look at lodash. You could easily argue it's 'done' and that it has better alternatives now, but look what happened: a security bug was discovered, the original author pretty much abandoned it, and it took about a week to figure out how to get a working build while meanwhile many thousands of other projects were failing due to npm audit checks.
The fact is even if nothing really needs to change in your project, the ecosystem around it can change requiring updates to your code.
It's fine to say "This project needs no new features and is in maintenance mode", but otherwise, if you're not willing to deploy new releases, "done", "dead" and "abandoned" all mean exactly the same thing.
In the Linux distribution model, Debian, Red Hat, etc maintain older libraries in maintenance mode. Patching them for security or other less glamorous fixes and adjustments.
In the Github, NPM model of opensource, the original author also controls the default means of distribution. There is not 3rd party like Debian in the middle to maintain it when the original authors leave. So many thousands of projects will still point to an abandoned distribution channel as opposed to simply an abandoned project.
There are likely solutions, and this is not to say that the second model is better or worse. It is only to describe that it is not as simple as a project being considered "done".
I think the best way to fix this attitude is to have more examples of "done but not dead" projects in the wild. You can't blame people for assuming they're the same thing when in most cases they are.
Times change, and when open source software doesn't change with the times it becomes vulnerable for some newer, shinier, more intuitive thing to pop up and take over. Software simply isn't going to reach some "Done" state and then have people using it for 100 years with no changes. Pretty soon, no one uses the project that is "Done" anymore, because it's old and does things the old ways, and not long after that, it's "Dead".
Time to die.
I didn't even bother looking for alternatives, so I didn't know about Intl, Luxon & day.js until today.
The size of the library has always been one of these things where I thought that the benefits outweigh the costs, and I knew that it wouldn't be like this forever. To me, this time in the future has come now, and I will switch to day.js (or Luxon, day.js has its size on its side, but I still need to compare).
No other library has filled a huge gap in JavaScript like Moment.js did for so many years.
On a note aside: I wish HTML had a <time>-tag, so we could also settle the timezone problem in publications like rocket launches or starting times of keynotes once and for all, where the publisher would use something like <time tz="Europe/Berlin">2020-09-15 10:26:48</time> and the browser would show it to the reader in the reader's local timezone.
While the browser won't convert it automatically, this is what the HTML <time>⁰ tag is for. The publisher can use <time datetime="2020-09-15T10:26:48+2">2020-09-15 10:26:48</time> and include a script which will read the datetime attribute and convert it to the browser's local time zone.
⁰ https://developer.mozilla.org/en-US/docs/Web/HTML/Element/ti...
No other library has filled a huge gap in JavaScript like Moment.js did for so many years.
I might say jQuery... which is mighty fine company to be included with! > new Intl.DateTimeFormat('zh', { hour: 'numeric' }).format(new Date)
< "下午11时"
[1]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refe... "MDN: Intl.DateTimeFormat"[2]: https://caniuse.com/mdn-javascript_builtins_intl_datetimefor... "Can I Use: Intl.DateTimeFormat"
Only Chrome seems to have actually implemented the spec this strictly, they don't want to change it: https://bugs.chromium.org/p/chromium/issues/detail?id=104579...
Not all of us are in a situation where we're iterating through the JavaScript new hotness every couple years and still have significant legacy systems to maintain and support.
I pulled in moment.js 5 years ago for a suite of state death and birth certificate registration apps we are working on.
Due to the amount of “business logic” and small staff size on these, they take years to roll out. I appreciate that this library will “hold still” for a few years.
Not all of us are churning out a new e-commerce app every 3 months. E.g. we replaced the birth certificate app from the 80s, and I expect some version of our app to be around for at least a decade, albeit with patches for new browsers on the front end and new Java app servers on the back end.
moment.js: Mutable. Thank you, next.
Luxon: Takes the effort to implement `Interval`, which would be `Range<DateTime>` in any proper language, but somehow avoids providing separate `Date` and `Time` objects.
Day.js: When you kinda like moment.js, but your bundler says it's too fat.
date-fns: The finest of pure, curry-able functions over the minefield that is Javascript's `Date` object.
js-joda: If Javascript didn't have classes already, this project would probably port the entire Java runtime to JS just to replicate them. Likely the most correct handling of date/time stuff available for the browser, but damn, at what cost?
------------
Edit: this turned out way too negative, my bad. All I wanted was a library that offered:
0) Type definitions.
1) Immutable classes of `Date` (year, month, day), `Time` (hour, minute, etc), `DateTime` (the prior two combined), `Instant` (for a certain moment on the global timeline), and `Duration`.
1b) `DateTime` should probably be split into two separate things, one of which is aware of time zones.
2) All the obvious date arithmetic functions - duration between dates, adding/subtracting durations, etc etc.
Mutable is not bad, buddy. You live in mutable world.
These are all just models of the real world, not the reality. The real world can be modeled equally accurately as mutable or immutable, it just depends which properties of the real world you care about modeling.
Just like you don't expect the expression a + 5 to change the value of a but to return a new number, most people don't expect myDate.add(5, 'days') to change the value of myDate.
I know that moment values are mutable, yet I often forget it while writing code and make dangerous mistakes because of how unnatural it is to see an arithmetic expression that is not immutable.
I would expect to use something like Moment.addDate(date1, 5, 'days') if I wanted a new instance of a date to be returned.
Even in javascript-land, methods like that will have side-effects, yet still return this often just for the sake of method chaining. E.g. date.add(5, 'days).format("%Y-%m-%d") would mutate date, but return the same instance as a convenience.
I like my consts and all where relevant, but I don't see why mutability is such a problem. Javascript is an imperative language where almost everything more complicated than a number is mutable. I see the lack of creating copies of objects with every operation as a benefit because of the RAM and CPU cycles it saves.
Is it because the API returns a reference to an object as well as updating said object? That's the API I'd expect, personally; if I want to do an addition of 1 to i, I'd write i += 1 and expect i to have incremented. I don't see why moment.add() should behave differently?
That said, we wouldn't be in this position if more companies used a shared CDN for libraries instead of always bundling them.
That helps with transfer but clients still have to parse and execute the javascript which can be significant, especially on mobile devices.
You call a function that requires a date (moment) object, and after the call you want to do something else with that date. Was it modified? Who knows. You will have to clone it before calling the aforementioned function. Otherwise, bugs.
You write a function that expects a date (moment) object. You want a different date (say "the day after"). If you call a method on the object, will the parent be smart enough not to touch anymore the date? You can't know that, so you will have to (remember to) start by cloning the date. Otherwise, bugs
I see your concerns about performance, but 1) temporal objects are so small that there are plenty of optimization opportunities for the JS engines to eliminate or greatly reduce allocations.
2) The larger and older your project, and the more people are working on it (including authors of third-party dependencies), the murkier data ownership becomes. With that you are more likely to slip into defensive programming practices. "I have a `Date` object that is someone's birthday, but I need to pass it to multiple functions and then serialize it to storage. But I can't tell for sure what those functions are doing with that value. Should I serialize the date right away and persist that value later? Should I just create copies of the object to pass to the functions?"
But birthdays don't mutate, so now you're worrying about a thing that shouldn't be an issue! In the unlikely case that someone's birthday date is corrected, May 9th doesn't suddenly turn into July 15th. In the real world you don't drag the red circle drawn in marker on a paper calendar with your finger from one cell to another, or white out the day number and write in another one. You cross the old circle off and draw a new one in the right place.
My background is in backend services, hundreds of threads running on dozens of cores. The peace of mind that comes with being able to pass values to async functions and thread pool executors, and knowing that they won't turn into a pumpkin at midnight is a very real thing. There's a performance price to pay, sure, but it's so tiny compared to the wins in development and debugging times. And in the particular case of date/time objects, most things are around 8-16 bytes anyway so it ends up not mattering much.
Tangent: this is the fear that Rust talks about in its value proposition btw. Technically, everything is mutable in Rust. You can flip a bit in an integer that is passed to a function from inside that function if you want. But the difference is that you have control over who gets to do that, and you have visual cues in the code (the `mut` keyword), and you have assurances from the compiler that the rules are followed. One owner at a time. Many can look, but not while a value is modified. Best of both worlds. The end result is that it never bothered me that `Date` is mutable in Rust. Either I'm the owner, or I borrowed the value to look at it, or I borrowed it for mutation and have the guarantees that 1) nobody else is doing the same; and 2) nobody will see in-progress modifications until I'm done.
A petty, thoughtless dismissal that reflects more on the one saying it than the library.
due to daylight saving timezones depend on the date, which makes it hard to separate date and time
Sometimes you need "Wake me up on December 24th at 10:00, regardless of where I am that day", and sometimes you want "The match will start on May 1st at 21:00 British Standard Time, and I want to be alerted about this even if I'm in New Zealand at that moment."
What I meant is a distinction between a `LocalDateTime` (first example, timezone is not relevant) and a `ZonedDateTime` (second example). The latter is very close to `Instant`, which is a point on the UTC timescale, but the subtle difference is that if timezone definitions were to change - as they often do - the `ZonedDateTime` would correctly remap to the actual `Instant` when the event was happening.
But regardless of semantics, they're being transparent on the project's status.
Every project has cons and they should embrace it and call it out like this project did instead of forever targeting a perfect library but nothing is perfect. It serves its purpose.
I am not sure if they are telling people not use it just because chrome now says to exclude it or they came up with it independently.
Independent. The maintainers have been recommending other alternatives (like Luxon) long before Chrome started to advise users on it. Moment has been in maintenance mode for a while now, this is just an updated confirmation of the fact, I'm guessing because users kept asking.
More code should be done. More developers just need to know how to quit the project when the time is right.
This is weird to say, but this is strong leadership.
I retired https://pypi.org/project/setuptools-pep8/ in 2013 but I still periodically check in on it since even today it gets 1.5k downloads per month https://pypistats.org/packages/setuptools-pep8
Besides, this announcement probably makes moment.js less stable than it was previously, since the web will continue to change but it won't change with it.
I mean, you can see that even in the high-tech realm, it takes years for obsolescence to be acknowledged. But at least it does eventually happen.
I actually think that a lot of the problems that our society has in general is because we take too many decades to move on from obsolete ways of doing things.
What we need is for other core assumptions or technologies in our society to be able to upgraded. For examples: roads, cars, cities, government, money. I truly believe that all of those fundamental structures are often stuck in outdated forms that are holding us back.
And if within that period they release an incompatible version, your upgrade path is worse, beacause your version is too old.
> Luxon is built around a few core ideas:
> * Keep the basic chainable date wrapper idea from Moment. Make all the types immutable. Make the API explicit; different methods do different things and have well-defined options.
> * Use the Intl API to provide internationalization, including token parsing. Fall back to English if the browser doesn't support those APIs.
> * Abuse the Intl API horribly to provide time zone support. Only possible for modern browsers.
> * Provide more comprehensive duration support.
> * Directly provide interval support.
> * Write inline docs for everything.
https://moment.github.io/luxon/docs/manual/why.html#ideas-in...
moment.js's API is intuitive and I have been using Dayjs and it has been doing great.
const somedate = moment(...somedate...);
const oneMonthLater = somedate.add(1, 'M');
const dateToCheck = ...; // between somedate and somedate + 1 month
if (dateToCheck.isBetween(somedate, oneMonthLater)) {
// do something
}
The puzzled looks when the tests fail. I'll miss that. Seriously.Main technological advancements that are breaking old monolithic libraries are, 1. async/await along with promises 2. Need for smaller footprint. Compile to what is needed not this is what I all got. I think, lodash done that to underscore.js at one time. 3. Typing support with libraries for runtime type safety. It's not breaking existing but new typescript, flow, etc projects opt for newer libraries with typing support.
Moment can be thought of as an instance (or build) of the iterative development of a strong usable, robust and bug free javascript api for dates. It's just that moment is the major release version that is still extremely popular but is a dead end in terms of design. Eventually the end goal is a solid, community agreed upon standard lib and in between versions (moment in this case) should be obsoleted while also not breaking existing code bases.
But read the attached article, it does a much better job of explaining than I do.
https://moment.github.io/luxon/docs/manual/moment.html helps getting up to speed.
I was doing mostly basic things and it has been straightforward (note that I don't have tests): https://github.com/conradfr/ProgRadio/commit/d52d9aed219281f...
edit: halved my app.js' size (before gzip).
edit2: Needed a new polyfill for timezones on IE11
I'm a big fan of Luxon and have been using it lately.
There was some back-and-forth about this on Twitter the other day:
I'd love to see something like Rust's Chrono ported to JS via WASM. In a TS project I did a few years ago, I had to roll my own DT lib.
It would be nice to see more flexible dependencies in such libs for example like material-ui pickers [0] which let’s you bring your own date/time lib.
[0] https://material-ui-pickers.dev/getting-started/installation
You either ship without any date support at all or you pick a library and go. Very little comes close to Moment for i18n and timezone support, so lots of libraries go with that.
The Temporal proposal to replace Date can't happen fast enough.
Moment’s developers realized that their job is done and that there are potentially better solutions now.
How refreshing is that?
But as long as the API doesn't completely suck, that stuff is worth less to me than stability. Updating libraries, especially in the world of JS, is always a fingers crossed moment hoping nothing will break. As long as there are no security flaws I am happier with no updates than with continual nice-to-have additions and changes to the API -- especially if those nice-to-haves come with opinionated deprecations to the "old and busted" way of doing things.
This is, all I need moment for, is simple date.formatAs('DD-MM-YYYY') and date.parse(date, 'YYYY-MM-DD') stuff. moment is overkill for that, but js Date somehow doesn't do it. It would probably be quicker to write one myself than to find a library that does just that.
var options = { year: 'numeric', month: '2-digit', day: '2-digit'};
console.log(new Intl.DateTimeFormat('te-IN', options).format(new Date()));
// outputs 16-09-2020So long, moment, and thanks for all the fish!
I too stuck with Moment for longer than I should have because of inertia and familiarity.
I found myself always starting with native Date library, then eventually adding Moment.js when we needed to robustly support timezones and timezone conversions.
Nothing like receiving a text at 5am pacific, because the system is calibrated to Eastern Timezone work hours.
Many UI libraries use that format so using different libraries with different notation will be harder to manage for me.
The only real "standard" in this area is LDML tokens, which are part of CLDR. Luxon follows those.
... and folks kept telling me I was wasting time writing my own time and date stuff in JS.
It did the job well and now time to move on. Why save something when another thing already does it and so well.
In my experience, it works reliably and easily. I've never had issues with it, and it does a fantastic job for a pretty big range of requirements.
Example snippet (CMIIW, it's as I remembered):
let date1 = moment("2020-01-01");
let date2 = date1.add(2, "days");
console.log(date1.format("YYYY-MM-DD")); // 2020-01-03
date2.add(2, "days");
console.log(date1.format("YYYY-MM-DD")); // 2020-01-05
Usually the date1.add operation won't change the date1 value, and any operation to date2 won't change date1, but it isn't. It's made worse because people like to return moment object outside function scope, so operation outside can modify the object inside and weird bugs happen.It's actually a manageable problem IF you know the behavior, and only using moment object reference inside scope, and using immutable objects as parameter / return, such as milliseconds timestamp and js date.
Most software has "reference types", like a customer. A customer is mutable; for example their name can change for a variety of reasons, their shipping address can change etc.
And then there are "value types", like integers or strings. The integer 42 can never change to be any other value.
If your customer lives in Rando Street no 42, and moves to Rando Street 41, you don't change the integer (value type) 42 to 41, you set `custtomer.address.house_number` to the new integer 41. If any other code referenced the number 42, it still has number 42 stored.
Now, many people argue that a moment in time (like timestamp/datetime) is usually better modeled as a value type. If you have two references to one moment, you can rely on the fact that nobody else can modify that moment after the fact.
This is usually safer, since it makes the case of accidentally over-shared objects a non-problem, though possibly a little bit less performant (since all "modifications" must create new copies).
Love the work your team has done, best of wishes!
"We will address critical security concerns as they arise."
Perhaps a better term than "done" is "feature complete".
Every project that I do; even experimental and “unending” projects are done as “ship-quality.” This is because I often revisit previous work, looking for snippets. If they are already at “ship” quality, then that’s one less problem.
I’m also a grizzled veteran of “the prototype becomes the product.” That’s something that many of us have experienced. It sucks, but it’s real. If the prototype is already “ship-quality,” then that’s one less problem.
I tend to tag ongoing projects, so the head may be dynamic, but cloning a tag will generate a stable release, or branch point. That’s a fairly typical Git workflow. I’m not a fan of too many branches. I used the Mainline Model (a Perforce pattern) for years, but I like no more than two branches, these days (dev and master, and sometimes, dev can be in a private repo, squashing to master). Often, I only have one branch. If I create a branch (like a retrospective fix to a release tag), I merge that branch back into master, or apply the same fix to master (not my preferred pattern). I will, occasionally, create experimental or exploratory branches, which are short-lived, and designed to be reintegrated with master. Again, not a unique workflow. This will be familiar to many folks.
So, lots of “done,” as mileposts on a continuum. In some cases (like when I am preparing course materials), I may do a lot of work in a dev branch, and squash over to master, in order to reduce the “noise” in master, but the “done bits” are always tags in master. I always reintegrate back to dev, so the branches remain in sync, and the tags propagate to dev.
One exception to the “continuum model,” is that fix tags may be in small, short-lived branches. If possible, I try to add the tag to master, at the reintegration point, but that isn’t always practical or safe, especially if I can’t actually reintegrate, but have to introduce the fix as new code, down the road.
Since I have started using the Swift Package Manager, this has been a good fit. I believe that many package managers rely on that pattern, so I don’t think the way that I work is especially creative or standout. Pretty much garden-variety configuration management.
Speaking of package managers, I often extract subprojects from my work in the master branch, as I progress, spinning them off as standalone package projects, with their own project lifecycle, and reintroduce them as dependencies. This gives me little pockets of “done,” that have encapsulated state and identity (and their own repo), along with focused testing. Each project I spin off, is one less thing to worry about, and another tool on the pegboard, for future projects.
So, in my case, “done” is really just a signpost along the road, but there can be many signposts.
Why
Are there really millions of not-toy javascript projects out there?