Back to Luxon

For Moment users

docs/moment.md

3.7.216.9 KB
Original Source

For Moment users

Luxon borrows lots of ideas from Moment.js, but there are a lot of differences too. This document clarifies what they are.

Immutability

Luxon's objects are immutable, whereas Moment's are mutable. For example, in Moment:

js
var m1 = moment();
var m2 = m1.add(1, 'hours');
m1.valueOf() === m2.valueOf(); //=> true

This happens because m1 and m2 are really the same object; add() mutated the object to be an hour later. Compare that to Luxon:

js
var d1 = DateTime.now();
var d2 = d1.plus({ hours: 1 });
d1.valueOf() === d2.valueOf(); //=> false

This happens because the plus method returns a new instance, leaving d1 unmodified. It also means that Luxon doesn't require copy constructors or clone methods.

Major functional differences

  1. Months in Luxon are 1-indexed instead of 0-indexed like in Moment and the native Date type.
  2. Localizations and time zones are implemented by the native Intl API (or a polyfill of it), instead of by the library itself.
  3. Luxon has both a Duration type and an Interval type. The Interval type is like Twix.

Other API style differences

  1. Luxon methods often take option objects as their last parameter
  2. Luxon has different static methods for object creation (e.g. fromISO), as opposed to Moment's one function that dispatches based on the input
  3. Luxon parsers are very strict, whereas Moment's are more lenient.
  4. Luxon uses getters instead of accessor methods, so dateTime.year instead of dateTime.year()
  5. Luxon centralizes its "setters", like dateTime.set({year: 2016, month: 4}) instead of dateTime.year(2016).month(4) like in Moment.
  6. Luxon's Durations are a separate top-level class.
  7. Arguments to Luxon's methods are not automatically coerced into Luxon instances. E.g. m.diff('2017-04-01') would be dt.diff(DateTime.fromISO('2017-04-01')).

DateTime method equivalence

Here's a rough mapping of DateTime methods in Moment to ones in Luxon. I haven't comprehensively documented stuff that's in Luxon but not in Moment, just a few odds and ends that seemed obvious for inclusion; there are more. I've probably missed a few things too.

Creation

OperationMomentLuxonNotes
Nowmoment()DateTime.now()
From ISOmoment(String)DateTime.fromISO(String)
From RFC 2822moment(String)DateTime.fromRFC2822(String)
From custom formatmoment(String, String)DateTime.fromFormat(String, String)The format tokens differ between Moment and Luxon, such that the same format string cannot be used between the two.
From objectmoment(Object)DateTime.fromObject(Object)
From timestampmoment(Number)DateTime.fromMillis(Number)
From JS Datemoment(Date)DateTime.fromJSDate(Date)
From civil timemoment(Array)DateTime.local(Number...)Like DateTime.local(2016, 12, 25, 10, 30)
From UTC civil timemoment.utc(Array)DateTime.utc(Number...)Moment also uses moment.utc() to take other arguments. In Luxon, use the appropriate method and pass in the { zone: 'utc'} option
Clonemoment(Moment)N/AImmutability makes this pointless; just reuse the object
Use the string's offsetparseZoneSee noteMethods taking strings that can specify offset or zone take a setZone argument

Getters and setters

Basic information getters

PropertyMomentLuxonNotes
ValidityisValid()isValidSee also invalidReason
Localelocale()locale
Zonetz()zoneMoment requires a plugin for this, but not Luxon

Unit getters

PropertyMomentLuxonNotes
Yearyear()year
Monthmonth()month
Day of monthdate()day
Day of weekday(), weekday(), isoWeekday()weekday1-7, Monday is 1, Sunday is 7, per ISO
Day of yeardayOfYear()ordinal
Hour of dayhour()hour
Minute of hourminute()minute
Second of minutesecond()second
Millisecond of secondsmillisecond()millisecond
Week of ISO week yearweekYear, isoWeekYearweekYear
QuarterquarterNoneJust divide the months by 3

Programmatic get and set

For programmatic getting and setting, Luxon and Moment are very similar here:

OperationMomentLuxonNotes
get valueget(String)get(String)
set valueset(String, Number)None
set valuesset(Object)set(Object)Like dt.set({ year: 2016, month: 3 })

Transformation

OperationMomentLuxonNotes
Additionadd(Number, String)plus(Object)Like dt.plus({ months: 3, days: 2 })
Subtractionsubtract(Number, String)minus(Object)Like dt.minus({ months: 3, days: 2 })
Start of unitstartOf(String)startOf(String)
End of unitendOf(String)endOf(String)
Change unit valuesset(Object)set(Object)Like dt.set({ year: 2016, month: 3 })
Change time zonetz(String)setZone(string)Luxon doesn't require a plugin
Change zone to utcutc()toUTC()
Change local zonelocal()toLocal()
Change offsetutcOffset(Number)NoneSet the zone instead
Change localelocale(String)setLocale(String)

Query

QuestionMomentLuxonNotes
Is this time before that time?m1.isBefore(m2)dt1 < dt2The Moment versions of these take a unit. To do that in Luxon, use startOf on both instances.
Is this time after that time?m1.isAfter(m2)dt1 > dt2
Is this time the same or before that time?m1.isSameOrBefore(m2)dt1 <= dt2
Is this time the same or after that time?m1.isSameOrAfter(m2)dt1 >= dt2
Do these two times have the same [unit]?m1.isSame(m2, unit)dt1.hasSame(dt2, unit)
Is this time's [unit] before that time's?m1.isBefore(m2, unit)dt1.startOf(unit) < dt2.startOf(unit)
Is this time's [unit] after that time's?m1.isAfter(m2, unit)dt1.startOf(unit) > dt2.startOf(unit)
Is this time between these two times?m1.isBetween(m2, m3)Interval.fromDateTimes(dt2, dt3).contains(dt1)
Is this time inside a DSTisDST()isInDST
Is this time's year a leap year?isInLeapYear()isInLeapYear
How many days are in this time's month?daysInMonth()daysInMonth
How many days are in this time's year?NonedaysInYear

Output

Basics

See the formatting guide for more about the string-outputting methods.

OutputMomentLuxonNotes
simple stringtoString()toString()Luxon just uses ISO 8601 for this. See Luxon's toLocaleString()
full ISO 8601iso()toISO()
ISO date onlyNonetoISODate()
ISO time onlyNonetoISOTime()
custom formatformat(...)toFormat(...)The format tokens differ between Moment and Luxon, such that the same format string cannot be used between the two. Note toFormat is meant to be used for machine-readable formats. For anything human-readable, you really want to use toLocaleString() instead.
RFC 2822toRFC2822()
HTTP date stringtoHTTP()
JS DatetoDate()toJSDate()
Epoch timevalueOf()toMillis() or valueOf()
ObjecttoObject()toObject()
Durationdiff(Moment)diff(DateTime)Moment's diff returns a count of milliseconds, but Luxon's returns a Duration. To replicate the Moment behavior, use dt1.diff(d2).milliseconds.

Humanization

Luxon has toRelative and toRelativeCalendar. For internationalization, they use Intl.RelativeTimeFormat (or fall back to English when it is not supported by the browser).

OperationMomentLuxon
Time from nowfromNow()toRelative()
Time from other timefrom(Moment)toRelative({ base: DateTime })
Time to nowtoNow()DateTime.local().toRelative({ base: this })
Time to other timeto(Moment)otherTime.toRelative({ base: this })
"Calendar time"calendar()toRelativeCalendar()

Durations

Moment Durations and Luxon Durations are broadly similar in purpose and capabilities. The main differences are:

  1. Luxon durations have more sophisticated conversion capabilities. They can convert from one set of units to another using shiftTo. They can also be configured to use different unit conversions. See Duration Math for more.
  2. Luxon does not (yet) have an equivalent of Moment's Duration humanize method. Luxon will add that when Intl.UnitFormat is supported by browsers.
  3. Like DateTimes, Luxon Durations have separate methods for creating objects from different sources.

See the Duration API docs for more.

Intervals

Moment doesn't have direct support intervals, which must be provided by plugins like Twix or moment-range. Luxon's Intervals have similar capabilities to theirs, with the exception of the humanization features. See the Interval API docs for more.