momentjs.com Documentation

repository·master·Indexed 20 days ago

https://github.com/moment/momentjs.com

Documentation for the momentjs.com website and the moment-timezone library. Includes guides on installing and using moment-timezone in Node.js, browsers, Webpack, and Require.js, as well as details on parsing and converting dates across different time zones and managing timezone data bundles.

Tokens
85K
Snippets
392
Records
439
Agent score
70%

What's inside momentjs.com

  1. Introduction to Moment.js Parsing

    master
    Moment.js features a flexible and advanced parser capable of handling a wide range of date/time formats. However, because the parser is highly permissive, it is one of the most frequently misused parts of the library. To ensure accuracy and avoid unexpected behavior, follow specific guidelines for your use case when parsing dates.
  2. Understand Moment's project status and maintenance mode

    master

    Moment.js is currently considered a legacy project in maintenance mode. It is not dead, but it is 'done', meaning the development focus has shifted from feature growth to stability for existing users.

    What this means for developers:

    • No new features: No new capabilities or major API changes (e.g., no version 3) will be added.
    • No immutability: The API will remain mutable to avoid breaking existing projects.
    • No bundle size optimizations: The library will not be updated to support better tree shaking or reduced bundle sizes.
    • Maintenance focus: The team will address critical security concerns and release data updates for moment-timezone following IANA releases, but may not fix long-standing bugs or behavioral quirks.
    • Locale stability: Corrections to locale strings or formats are rarely accepted unless they align with CLDR standards.
  3. Use overloaded getters and setters for date manipulation

    master

    Moment.js uses an overloaded pattern for accessing and modifying date components (like seconds, minutes, hours, etc.).

    • Getter: Call the method without any parameters to retrieve the value.
    • Setter: Call the method with a parameter to change the value.

    Important: All setter methods mutate the original moment object.

    As of version 2.0.0, both singular (e.g., .second()) and plural (e.g., .seconds()) method names are available for convenience.

    // Getter: retrieves the value
    const seconds = moment().seconds();
    
    // Setter: modifies the moment object and returns it (allowing chaining)
    moment().seconds(30);
  4. Understand sign reversal in Etc/GMT identifiers

    master

    When using fixed-offset identifiers in the Etc/GMT area, the sign is reversed compared to the standard ISO 8601 convention to maintain POSIX compatibility. This is a requirement of the IANA Time Zone Database.

    • Etc/GMT-X: Represents a zone that is X hours ahead of GMT (positive offset).
    • Etc/GMT+X: Represents a zone that is X hours behind GMT (negative offset).

    Because of this non-intuitive behavior, it is highly recommended to use locality-based identifiers (e.g., Europe/Madrid) instead of fixed-offset identifiers (e.g., Etc/GMT+1) to avoid errors.

    // Etc/GMT+1 results in a -0100 offset (1 hour behind GMT)
    moment().tz('Etc/GMT+1').format('YYYY-MM-DD HH:mm ZZ');
    // '2014-12-18 11:22 -0100'
    
    // Europe/Madrid results in a +0100 offset (1 hour ahead of GMT)
    moment().tz('Europe/Madrid').format('YYYY-MM-DD HH:mm ZZ');
    // '2014-12-18 13:22 +0100'
  5. Understand the Packed Format structure

    master

    The packed format is a highly compressed string representation of a time zone's data. It is used to minimize byte size by splitting data into 6 pipe-separated (|) sections. This format is primarily used for storing time zone information like abbreviations, offsets, and timestamps efficiently.

    Each section follows a specific schema:

    1. Name: The canonical time zone name (e.g., America/Los_Angeles).
    2. Abbr Map: A space-separated list of all abbreviations used in the zone (e.g., PST PDT).
    3. Offset Map: A space-separated list of all offsets used (in minutes, encoded in base 60).
    4. Abbr/Offset Index: A tightly packed array of indices pointing to the Abbr and Offset maps, also encoded in base 60.
    5. Timestamp Diffs: A list of timestamp differences encoded in base 60. The first value is a Unix timestamp in minutes; subsequent values are the number of minutes to add to the previous value.
    6. Population: The approximate population of the zone's namesake city, using scientific exponential notation (e.g., 15e6 for 15,000,000). This is used for the 'guessing' feature and may be empty.
    'America/Los_Angeles|PST PDT|80 70|01010101010|1Lzm0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0|15e6'
  6. How to create a Moment wrapper object

    master

    Moment.js does not modify the native Date.prototype. Instead, it provides a wrapper for the Date object. You create this wrapper by calling moment() and passing in a supported input type (such as a Date object, a connection string, or a Unix timestamp).

    // Example of creating a moment wrapper
    const m = moment();
  7. How parsing vs. converting works in Moment Timezone

    master

    Moment Timezone provides two distinct ways to handle time zones, depending on whether you want to define the starting point or change the view of an existing point:

    1. Parsing (moment.tz(..., zone)): You are telling Moment: "This string represents a time that occurred in this specific zone." The UTC time is calculated based on that zone's offset.

      • Use case: You have a log file with timestamps that are already in 'Asia/Taipei' and you want to load them correctly.
    2. Converting (moment().tz(zone)): You are telling Moment: "I have this moment in time, now show it to me as if it were in this zone." The underlying UTC time does not change.

      • Use case: You have a UTC timestamp and you want to display it to a user in 'America/Toronto'.
  8. Handle edge cases when adding months and years

    master

    When adding time, certain edge cases regarding calendar months and Daylight Saving Time (DST) apply:

    Month Overflow

    If the day of the month in the original date is greater than the number of days in the resulting month, the day will be set to the last day of that month.

    moment([2010, 0, 31]);                  // January 31
    moment([2010, 0, 31]).add(1, 'months'); // February 28

    Daylight Saving Time (DST)

    • Years, months, weeks, or days: Adding these units preserves the original hour. The hour will match the original hour even if it crosses a DST boundary.
      var m = moment(new Date(2011, 2, 12, 5, 0, 0)); // day before DST
      m.hours(); // 5
      m.add(1, 'days').hours(); // 5
    • Hours, minutes, seconds, or milliseconds: Adding these units assumes precision to the hour and may result in a different hour if a DST boundary is crossed.
      var m = moment(new Date(2011, 2, 12, 5, 0, 0)); // day before DST
      m.hours(); // 5
      m.add(24, 'hours').hours(); // 6
  9. Understand and handle Moment.js mutability

    master

    Moment objects are mutable. This means that calling methods like .add(), .subtract(), or .set() modifies the original moment instance rather than returning a new one.

    If you perform date math on an existing moment object, that object's value will change. To prevent side effects and preserve the original date, you must create a copy of the object using the .clone() method before performing operations.

    // WARNING: This mutates the original object 'a'
    var a = moment('2016-01-01'); 
    var b = a.add(1, 'week'); 
    console.log(a.format()); // "2016-01-08T00:00:00-06:00"
    
    // RECOMMENDED: Use .clone() to preserve the original object
    var a = moment('2016-01-01'); 
    var b = a.clone().add(1, 'week'); 
    console.log(a.format()); // "2016-01-01T00:00:00-06:00"
  10. Handling decimal values in Date Math

    master

    Moment.js does not officially support adding or subtracting decimal values for days, months, years, or quarters because these units have variable durations.

    As of version 2.12.0, when decimal values are provided, Moment converts them to integers by taking the absolute value and rounding to the nearest whole number.

    Key behaviors:

    • 1.5 days rounds to 2 days.
    • -1.5 days rounds to -2 days.
    • Quarters and years are first converted to months, then rounded.

    Warning: Because of this rounding behavior, passing decimals may lead to unexpected results if you expect precise fractional time increments.

    // Days rounding
    moment().add(1.5, 'days') == moment().add(2, 'days')
    moment().add(-1.5, 'days') == moment().subtract(2, 'days')
    
    // Months rounding
    moment().add(2.3, 'months') == moment().add(2, 'months')
    
    // Years and Quarters (converted to months then rounded)
    moment().add(1.5, 'years') == moment().add(18, 'months')
    moment().add(1.5, 'quarters') == moment().add(5, 'months') // 4.5 months rounds to 5