TypeScript icon, indicating that this package has built-in type declarations

    0.0.8 • Public • Published


    year-month CircleCI

    Simple, fast date calculations with a granularity of one month.


    $ npm install year-month


    const YearMonth = require('year-month');

    What is it?

    year-month is a lightweight library for manipulating dates to a granularity of one month. YearMonth objects are immutable and methods return new instances.

    const weddingMonth = YearMonth.parse('2019-05');
    const goldenAnniversary = weddingMonth.addYears(50);
    console.log(goldenAnniversary); // toString() gives '2069-05'


    There are several time/date libraries for Javascript. However we had lots of application logic that worked at a granularity of one month.

    We found that there was a lot of cognitive overhead for the programmer when using a more granular library. For 'Jan 2020', do I use the first day of the month, the last day or a day in the middle? Midnight? Noon? One minute to midnight? UTC or local time? Can I just use thisDate.isBefore(thatDate) or must I specify the monthly granularity?

    We also found that the computer was working much harder than it needed to - accounting for the varying number of days in months; handling leap years and leap seconds. If your application doesn't care how long a month is, these are wasted CPU cycles.

    Month numbers

    Months are 1-indexed for both input and output - that is, January is 1, December is 12.


    YearMonth.fromNumbers(2020, 3) - March 2020

    YearMonth.parse('2020-03') - This is the canonical string format. YearMonth's default parser does not attempt to infer other formats, but see Custom parsers.

    YearMonth.parse('2020-03-20') - Day of month is ignored

    YearMonth.parse('2020-03-foobar') - No really, day of month is ignored

    YearMonth.safeParse('2020-03') - Equivalent to parse() ...

    YearMonth.safeParse(YearMonth.parse('2020-03')) - ... but if you pass it a YearMonth, returns it unchanged.


    const ym = YearMonth.parse('2019-05');
    YearMonth.isYearMonth(ym); // true
    ym.year() // 2019
    ym.month() // 5
    ym.toString() // '2019-05'
    ym.toJSON() // '2019-05'
    ym.addYears(10) // 2029-05
    ym.addMonths(10) // 2020-03
    ym.prevMonthOf(11) // 2018-11
    ym.prevMonthOf(05) // 2019-05 -- prevMonthOf() is inclusive
    ym.nextMonthOf(2) // 2020-02
    ym.nextMonthOf(5) // 2019-05 -- nextMonthOf() is inclusive


    YearMonth implements equals() and valueOf().

    Among other things this means that Arrays.sort(), < and > etc. work.

    The methods lt(), gt(), lte(), gte() are equivalent to <, >, <=, >=, except that comparisons against null are always true. That is, null represents 'the beginning of time' or 'the end of time' depending on context.

    yd.isWithin(start, end) is equivalent to yd.gte(start) && yd.lte(end), meaning that yd.isWithin(null,null) is true. This is useful if you're working with date ranges which may or may not be open-ended.

    JS === doesn't use valueOf() or equals(), so either use .equals() explicitly, or use a framework that does (for example Ramda's equals or assert.strictEqual())

    Subtraction results in the difference in months, but you can also use the diff() method.

    YearMonth.parse('2020-05') - YearMonth.parse('2019-05') // 12
    YearMonth.parse('2020-05').diff(YearMonth.parse('2019-05')) // 12

    Custom parsers and formatters

    The ISO-8601 inspired default format of YYYY-MM is the best format and I promise you'll be happier if you stick with it.

    But you can customise your instance of the library with your own parse and format functions.

    // The parser takes a string and returns an array where arr[0] is the year and arr[1] is the month
    // The elements may be Strings or Numbers - parse() will throw an error if they can't be coerced to numbers
    // or if the month is out of range.
    const YearMonthWithCustomParser = require('year-month').withParser( s => s.split('/').reverse());
    const ym = YearMonthWithCustomParser.parse('3/2018');
    console.log(ym.toString()); // "2018-03"
    // formatter takes numbers (year, month) and returns a string
    const YearMonthWithCustomFormat = require('year-month').withFormatter( (year, month) => `${month}/${year`});
    console.log(YearMonthWithCustomFormat.parse('2019-05').toString()); // "5/2019"
    // you can chain these
    const MyCustomYearMonth = require('year-month').withParser(myParser).withFormatter(myFormatter);

    Created by Wealth Wizards Software Engineering


    npm i year-month

    DownloadsWeekly Downloads






    Unpacked Size

    11.9 kB

    Total Files


    Last publish


    • wealthwizards