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

    3.0.3 • Public • Published


    MIT License

    A JavaScript module for accurately calculating times of sunrise, solar noon, sunset, as well as moon phases.

    Based on "Astronomical Algorithms" by Jean Meeus.



    MeeusSunMoon requires Luxon.


    Script Include

    Compiled versions (both minified and not) are located in dist/.

    <script src="{yourjspath}/meeussunmoon.min.js"></script>


    npm install meeussunmoon

    For bundling (e.g., with Rollup) you can then import the ES6 module via

    import MeeusSunMoon from 'meeussunmoon'

    or directly use it in the browser via

    import MeeusSunMoon from 'node_modules/meeussunmoon/dist/meeussunmoon-es.js'


    There are three configuration settings that can be set as

      roundToNearestMinute: true, // default: false
      returnTimeForNoEventCase: true, // default: false
      dateFormatKeys: {'SUN_HIGH': '‡', 'SUN_LOW': '†'} // default {'SUN_HIGH': '‡', 'SUN_LOW': '†'};

    roundToNearestMinute rounds the reported time: up if seconds are 30+, down if less.

    returnTimeForNoEventCase handles the behaviour when no sunrise, sunset, etc. time can be returned because the sun is too high or too low during the entire day. If set to false, a string is returned, either 'SUN_HIGH' or 'SUN_LOW'. If set to true, the return time will be 6:00 local standard time (i.e. 7:00 local time if DST is in effect) for sunrise and 18:00 local standard time for sunset (For civil, nautical, and astronomical dawn and dusk, the times returned are 0:30h, 1:00h, and 1:30h earlier / later, respectively, than for sunrise and sunset). Additionally, the DateTime object that is returned will have a property errorCode set to either 'SUN_HIGH' or 'SUN_LOW'. This way, the fact that this is not an actual sunrise/sunset time can be retrieved later, e.g. with MeeusSunMoon.format (see below).


    Sunrise & Sunset

    MeeusSunMoon.sunrise(datetime, latitude, longitude);
    MeeusSunMoon.sunset(datetime, latitude, longitude);

    Returns the sunrise or sunset for the given date and location as a Luxon DateTime object.

    datetime is a Luxon DateTime object designating the day for which the sunrise/set time should be calculated. The object should either contain a definite timezone, or be in UTC, just a UTC offset will lead to unexpected behaviour

    latitude is the geographic latitude in degrees (-90 to 90, North is positive, South negative).

    longitude is the geographic longitude in degrees (-180 to 180, East is positive, West negative).

    If there is no sunrise or sunset event on the given day, a string or a tagged time will be returned (see above).

    Civil, Nautical, and Astronomical Dawn & Dusk

    MeeusSunMoon.civilDawn(datetime, latitude, longitude);
    MeeusSunMoon.civilDusk(datetime, latitude, longitude);
    MeeusSunMoon.nauticalDawn(datetime, latitude, longitude);
    MeeusSunMoon.nauticalDusk(datetime, latitude, longitude);
    MeeusSunMoon.astronomicalDawn(datetime, latitude, longitude);
    MeeusSunMoon.astronomicalDusk(datetime, latitude, longitude);

    As above but for civil (center of the sun is 6° below the horizon), nautical (center of the sun is 12° below the horizon), and astronomical (center of the sun is 18° below the horizon) dawn and dusk.

    If the specified event does not occur on the given day, a string or a tagged time will be returned (see above).

    Solar Noon

    MeusSunMoon.solarNoon(datetime, longitude);

    Returns the solar noon for the given date and location as a L DateTime object. Inputs as above.

    Moon Phases

    MeeusSunMoon.yearMoonPhases(year, phase, timezone);

    Returns an array of the datetimes as Luxon DateTime objects for all moons of the given phase in the year.

    year The Gregorian year for which the phases should be returned. Note: years need to be written out in all digits, setting e.g. 96 as the year will NOT return phases for the year 1996 but the year 96!

    phase Phase of the moon as an integer. 0 for new moon, 1 for first quarter, 2 for full moon, 3 for last quarter.

    timezone Optional. IANA timezone string, e.g. 'Europe/London'. If not specified, times are returned as UTC.

    MeeusSunMoon.yearAllMoonPhases(year, timezone);

    Returns an array of { datetime, phase } objects that corresponds to all moon phases in the given year in chronological order.


    format is a helper function of MeeusSunMoon which uses the custom property attached to returned DateTimes in case of no event to provide an appropriately marked string representation.

    By calling MeeusSunMoon.format(datetime, formatString), where datetime is a Luxon DateTime object as above and formatString uses the same syntax as luxon.DateTime.toFormat(), if the datetime was created with a key as described above, a string as defined by dateFormatKeys is appended to the formatted date.


    // datetime, latitude, and longitude correspond to a location and time which
    // experiences midnight sun
    MeeusSunMoon.sunrise(datetime, latitude, longitude)
    console.log(MeeusSunMoon.format(sunrise, 'HH:mm'));
    >> 06:00


    The algorithms themselves use many higher-order corrections in order to achieve a high degree of accuracy. To ensure a correct implementation, I have compared over 50,000 times across 16 locations spanning extremes of latitude and longitude to outside sources such as the US Naval Observatory and and found that almost 98% agreed to the minute, with almost the entire rest deviating by at most one minute. The only exception to this are days immediately preceeding or following periods for which the given event does not occur, where the discrepancy can be larger. For sunrise and sunset, this only affects regions within the polar circles which experience polar night and midnight sun.

    test/index.html can be run to verify this if you downloaded the entire repository. When maxError (maximum deviation in minutes for the test to pass) in test/tests.ts is set to 0, about 2% of the tests will fail. When set to 1, all will pass. (Some times which fall under the exception above have been excluded from testing, they are listed as empty strings in referenceTimes.ts.)

    Tests can also be run in the console via npm run node-test.



    Switched to using Luxon instead of moment-timezone.

    Added function yearAllMoonPhases.

    Breaking Changes:
    • Inputs and outputs are now Luxon DateTime objects instead of moment objects
    • Browser support for browsers not supported by Luxon dropped. Any reasonably modern browser will work. No version of IE is supported.
    • formatCI has been renamed to format
    • options renamed to settings
    • options.returnTimeForPNMS renamed to settings.returnTimeForNoEventCase
    • keys for settings.dateFormatKeys have been changed from ** to SUN_HIGH and from -- to SUN_LOW


    Updated dependencies, use moment import as global, added coverage


    Updated dependencies, fixed imports for node usage


    Added functions for civil, nautical, and astronomical dawn and dusk.


    Refactored into ES6 modules and distributed via node.


    Initial release


    MeeusSunMoon is freely distributable under the terms of the MIT license.


    npm i meeussunmoon

    DownloadsWeekly Downloads






    Unpacked Size

    401 kB

    Total Files


    Last publish


    • janrg