
You Don't Need Moment.js - ggregoire
https://github.com/you-dont-need/You-Dont-Need-Momentjs
======
pjungwir
If you are dealing with timestamps from the past (e.g. birthdays via a
datepicker that constructs Date objects), then you should watch out for
different browsers' inconsistent handling of Daylight Savings Time. Moment is
really indispensable here, since it includes a database of past years' DST
transition dates. I wrote a blog post about it here:
[https://illuminatedcomputing.com/posts/2017/11/javascript-
ti...](https://illuminatedcomputing.com/posts/2017/11/javascript-timezones/)

~~~
robocat
Past time zones should only be a fairly specialist need: our front end code
(SPA that is especially in the time domain) doesn't need to deal with past
time zones. Then again, although our SPA is 100% JSON, we do all date and time
processing at the server.

Putting UTC times into our front end would require the front end to know too
many business rules.

> e.g. birthdays via a datepicker that constructs Date objects

> [From your comment in link]: The birthday will be wrong from the very start,
> because datepickers din't care about people can be born in some TZ and fill
> forms different TZs. Normally if you're only interested in date only, it
> doesn't matter if time part is off by hour or more hours. But if you live in
> Africa, then it could be whole day difference (because of how date will
> parsed).

I have trouble understanding your example - I am guessing you are sending UTC
date including time of birth? Seems a little contrived. Maybe pick a better
example (calendars or alerts and timezones?)

That said, I agree that trusting the browser implementation is mad. We still
have clients accessing using IE8 (we just dropped support), Safari 7 (iPhone
4), and a fair number use Chrome 30/33 because that is the version the WebView
is stuck on for Android 4.4.

Some of our users have the date on their computer set a week out (or more)!

Edit: just saw comment at end of your article "If your users enter birthdays
with some kind of date picker, you probably suffer from this bug!". I think
you just have a problem with your code: you would not use UTC date/time from a
date picker, and you should either zero the time component or don't use Date
internally when you just need a date - e.g. an input type=date naturally
returns "yyyy-mm-dd".

~~~
kbenson
The problem is that if you use a zeroed time component, but at some point it's
assumed 00:00:00 (midnight), shifting timezones might mean that it shifts to
the previous day. Even if you then truncate the hour portion before display,
the date is wrong.

For example, you use a datepicker at some point, and it stores 2000-01-01
00:00:00 in the US/Eastern time zone (because that's where you and the
computer you're on are when you do it). If you happen to store that as UTC,
you might find some interesting outputs for people on the West coast if you
convert back to a local (US/Pacific) timestamp. Specifically, you'll get
1999-12-31 21:00:00, and if you do this blindly and throw away the hour
portion, you still get the wrong date.

When you want dates, you often really want to store just the date potion. Any
time you want a date and time, you probably also want a timezone along with
it, or at a minimum, you want to know what type of output your use case
requires and handle it appropriately. Dates and times are one of those things
that seems simple until you've had to deal with the details and encountered
the problems enough that you always treat it with a bit of respect.

~~~
marcus_holmes
Even just using dates can be a mess. At midday UTC everyone experiences the
same date. The other 23 hours of the day, a varying proportion of people are
experiencing a different date.

"using dates" therefore works out to "not caring about the time of day" and
that reduces to "not caring about the time of day in the same timezone" since
the same time of day in two timezones have a ~50% chance of being in different
dates.

It really comes down to "does your application need to worry about time
zones?" If so, then you probably need to treat this seriously, and getting
help with that is good. If not, not.

~~~
kbenson
Sure, but I was referring more to the times you actually do just want a date.
It's perfect for a birthday, or "this day in history", or any number of other
things. Nobody really cares that while it was Tuesday where you were born, it
was Wednesday for them.

In some instances, if you really only care about the day something happened,
adding a time is just extra details to screw up. But if you _do_ need need a a
time, you very well may also need a timezone.

~~~
marcus_holmes
well, yes, 99% of the time you're right... but... an astrology application
(for example) will care about your timezone for your birthday.

It comes down to the use case, not the data.

------
baliex
The lack of timezone support in the two suggested alternatives (date-fns,
dayjs) means they're not real alternatives for any use-case as soon as you're
operating in a country with any DST,
[https://en.wikipedia.org/wiki/Daylight_saving_time_by_countr...](https://en.wikipedia.org/wiki/Daylight_saving_time_by_country).

~~~
sushid
Seriously... It's not like timezone support is some esoteric interest in a
Date/Time library.

~~~
kbenson
No, but it does add quite a bit of complexity, and if it's done _correctly_
usually requires not just a database of timezones, but also when and how
they've changed over the years.

Not supporting timezones is a valid design choice, but is _so_ important and
integral it should be the _first_ item both mentioned by a library and used as
criteria to decide whether it's a valid choice for those surveying libraries.

It's sort of like choosing a storage solution. Do you need persistent storage
that can survive a reboot, or is something ephemeral that works only while
powered good enough? Both have their places, but choosing the wrong one for
your specific use case is usually very problematic.

------
nicoburns
There's also Luxon from (one of?) the maintainers of Moment:
[https://moment.github.io/luxon/](https://moment.github.io/luxon/).

It abuses the i18n api (by parsing the date out of a formatted string) to
provide timezone support without shipping timezone data, which is pretty
clever.

~~~
owenversteeg
Oh, that's a beautiful hack, I love it.

------
caseymarquis
Most of moment's size is in the localizations. You can reduce it from 300kb to
100kb by removing them or only including the ones you care about:
[https://stackoverflow.com/questions/25384360/how-to-
prevent-...](https://stackoverflow.com/questions/25384360/how-to-prevent-
moment-js-from-loading-locales-with-webpack)

I think the bigger lesson, if moment's size is news to you (for those of us
using webpack), is to install webpack-bundle-analyzer. It's loads of fun, if
you like visualizations.

~~~
dcposch
You can further reduce that to 0kb by using window.Intl . You get locale and
timezone aware date formatting, built-in on all modern browsers.

The API is pretty nice!

[https://caniuse.com/#feat=internationalization](https://caniuse.com/#feat=internationalization)

------
anonytrary
Whenever a "you might not need this heavy, popular lib" gets posted to HN, the
responses are always pretty divided. I always try and write my own functions
and import things like lodash, underscore, jQuery, and moment as a last
resort. Bundle size may not be that important to the people working on
prototypes and side projects, but it certainly is to many other people.

If a library is heavy, it is in their interest to organize it instead as a
collection of submodules that can be depended on individually (IIRC, lodash
does this) otherwise they risk people just not using their stuff.

~~~
sidstling
I’ve picked up node and js more seriously recently, coming from .Net and C#
and I’ve been wondering why people in my learning material are relying so much
on third party libraries for very basic things.

I’m probably a little old fashioned, but I didn’t even know moment existed and
I’ve been fooling around quite a bit with JS dates recently. It didn’t take a
long time to write the .ToString(dd-MM-yyyy) module, that was the only thing I
really needed aside from the standard library, but I guess it would’ve been
faster to import moment.js.

~~~
FlorianRappl
Coming from .NET you should know Noda Time
([https://nodatime.org](https://nodatime.org)) and the problem it solves.
Consider moment the JS alternative, however, with JS native Date being more
limited / broken than .NET's DateTime.

TL;DR: Goes way beyond standard formatting.

~~~
Sacho
The C# DateTime has more useful methods than JS Date, but DateTimeKind and the
way it counts ticks makes it an absolute trap for anyone to use, so I wouldn't
say it's less broken.

------
jmhain
A good lightweight alternative is js-joda. I recently switched from moment.js
and I've been very happy with it.

[https://js-joda.github.io/js-joda/](https://js-joda.github.io/js-joda/)

~~~
ricardobeat
At 43kb gzipped, it's hardly lightweight - that's 70% of moment.js' size, 4x
larger than date-fns

~~~
dmm
js-joda offers a lot more than lightweight native Date type wrappers like
date-fns. It offers separate time and date implementations which allows you to
more precisely model your problem. The native Date object always consists of a
time, date, and timezone.

For example, a js-joda LocalDate is just a date without a time or timezone.
This allows you to cleanly represent things like birthdays, anniversaries or
holidays in an unambiguous way.

js-joda is also immutable which in my experience is more predictable and less
error prone. With js-joda, "d.plusDays(366);" leaves d unchanged.

js-joda also has very good duration support.

Because it does not use the native Date implementation it is potentially more
consistent across platforms. It is also has lots of tests.

If all you are doing is formatting a few dates, date-fns is probably
sufficient and it is certainly smaller, but for more intensive manipulations
of dates and times I think js-joda is well worth the size.

------
the-pigeon
For all the problems with Moment.js this article really sells it as the better
solution for many use cases.

------
ENGNR
The problem is that moment didn’t include locales as a default at one point,
and then suddenly it did. And it’s the kind of thing you don’t want to do
module splitting on, date functions can be used in all sorts of places so it’s
really a core lib

------
andy_ppp
Yes, I’m using date-fns and bits of this pull request [1]. It works very well
and uses the Intl browser API to support time zones.

Also worth noting that the mutable nature of moment can make things very
confusing where as date fns is immutable and consistent.

Remember that unless building a calendaring system, all dates should be stored
in UTC and only converted into a specific Timezone for presentation.

[1] [https://github.com/date-fns/date-fns/pull/707](https://github.com/date-
fns/date-fns/pull/707)

------
koblas
While you might not need moment.js and can remove it from your project. The
problem is that every other project is using it, so you're already picking up
the dependency. Many months ago I went digging into if we could remove it and
while I successfully pulled it out, found that three of the packages we
install all needed it -- thus having one date library was preferable to extra
code size.

------
ggregoire
But react-dates has moment as dependency, so…

~~~
BigJono
Welcome to the wonderful world of code re-use. Hey, at least we're not re-
inventing the wheel.

~~~
nkozyra
We're reimporting the wheel (which, by the way, also has moment.js as a
dependency)

------
patriot_prayer
I need Moment because Date.parse does not do the same thing in Safari as it
does in Chrome

------
h1d
When will JS engines ship with timezone data to not let a third party maintain
it?

~~~
guitarbill
Ironically, it's possible every browser includes this already internally, but
doesn't expose it to Javascript [0].

Packages still have their place, but the lack of a decent standard library
will hurt us for decades to come (already is arguably).

[0] [https://dxr.mozilla.org/mozilla-
central/source/intl/icu/sour...](https://dxr.mozilla.org/mozilla-
central/source/intl/icu/source/i18n/unicode/timezone.h#131)

~~~
boubiyeah
This. People often have a beef with the very wild npm ecosystem with tons of
libs of varying quality, abandonned projects, bloated libs, etc but mostly it
comes down to the standard library being anemic.

------
danielvinson
I really don't understand this... while yes, I might at some point be
interested in reducing my bundle size, for 99% of developers out there, a
difference in 300kb is just completely irrelevant.

I choose my JS libraries because they are actively maintained, have well
designed APIs (easy to use), are common enough to where newly hired developers
already know them, and just generally make my life easier. This doesn't
address any of that.

~~~
shados
300kb is half a second to load for someone with a 5mb connection (which is
still quite common in a lot of the world...and even in parts of the US). It's
also a LOT of crap to parse on a lower end computer.

Repeat with a few libraries, and you're going to need a Flash-style progress
part as your app loads. That's not exactly a great user experience. Doesn't
really matter if you're building an MVP or if you have bigger fish to fry, but
eventually it certainly matters. There's a reason the modern web is so freagin
slow, and only half of it is because of slow backend APIs.

~~~
angersock
After gzipping none of the variants are that large, and let's be real: the 3rd
party ads and analytics and cat pictures are gonna strictly dominate the load
time.

~~~
this_user
Just because there is even more bloat being loaded from other sources doesn't
mean that adding more bloat doesn't matter. This kind of mindset has brought
us to exactly this point where modern web sites are loading more slowly than
one from 20 years ago would have while using dial-up.

------
gpmcadam
Another light alternative (~2kB) is
[fecha]([https://github.com/taylorhakes/fecha](https://github.com/taylorhakes/fecha))

