Luxon Home Reference Source Repository

src/info.js

import { DateTime } from './datetime';
import { Settings } from './settings';
import { Locale } from './impl/locale';
import { Util } from './impl/util';

/**
 * The Info class contains static methods for retrieving general time and date related data. For example, it has methods for finding out if a time zone has a DST, for listing the months in any supported locale, and for discovering which of Luxon features are available in the current environment.
 */
export class Info {
  /**
   * Return whether the specified zone contains a DST.
   * @param {string|Zone} [zone='local'] - Zone to check. Defaults to the environment's local zone.
   * @return {boolean}
   */
  static hasDST(zone = Settings.defaultZone) {
    return (
      !zone.universal &&
      DateTime.local()
        .setZone(zone)
        .set({ month: 1 }).offset !==
        DateTime.local()
          .setZone(zone)
          .set({ month: 5 }).offset
    );
  }

  /**
   * Return an array of standalone month names.
   * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DateTimeFormat
   * @param {string} [length='long'] - the length of the month representation, such as "numeric", "2-digit", "narrow", "short", "long"
   * @param {object} opts - options
   * @param {string} [opts.locale='en'] - the locale code
   * @param {string} [opts.numberingSystem=null] - the numbering system
   * @param {string} [opts.outputCalendar='gregory'] - the calendar
   * @example Info.months()[0] //=> 'January'
   * @example Info.months('short')[0] //=> 'Jan'
   * @example Info.months('numeric')[0] //=> '1'
   * @example Info.months('short', { locale: 'fr-CA' } )[0] //=> 'janv.'
   * @example Info.months('numeric', { locale: 'ar' })[0] //=> '١'
   * @example Info.months('long', { outputCalendar: 'islamic' })[0] //=> 'Rabiʻ I'
   * @return {[string]}
   */
  static months(
    length = 'long',
    { locale = 'en', numberingSystem = null, outputCalendar = 'gregory' } = {}
  ) {
    return new Locale(locale, numberingSystem, outputCalendar).months(length);
  }

  /**
   * Return an array of format month names.
   * Format months differ from standalone months in that they're meant to appear next to the day of the month. In some languages, that
   * changes the string.
   * See {@link months}
   * @param {string} [length='long'] - the length of the month representation, such as "numeric", "2-digit", "narrow", "short", "long"
   * @param {object} opts - options
   * @param {string} [opts.locale='en'] - the locale code
   * @param {string} [opts.numbering=null] - the numbering system
   * @param {string} [opts.outputCalendar='gregory'] - the calendar
   * @return {[string]}
   */
  static monthsFormat(
    length = 'long',
    { locale = 'en', numberingSystem = null, outputCalendar = 'gregory' } = {}
  ) {
    return new Locale(locale, numberingSystem, outputCalendar).months(length, true);
  }

  /**
   * Return an array of standalone week names.
   * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DateTimeFormat
   * @param {string} [length='long'] - the length of the month representation, such as "narrow", "short", "long".
   * @param {object} opts - options
   * @param {string} [opts.locale='en'] - the locale code
   * @param {string} [opts.numbering=null] - the numbering system
   * @param {string} [opts.outputCalendar='gregory'] - the calendar
   * @example Info.weekdays()[0] //=> 'Monday'
   * @example Info.weekdays('short')[0] //=> 'Mon'
   * @example Info.weekdays('short', 'fr-CA')[0] //=> 'lun.'
   * @example Info.weekdays('short', 'ar')[0] //=> 'الاثنين'
   * @return {[string]}
   */
  static weekdays(length = 'long', { locale = 'en', numberingSystem = null } = {}) {
    return new Locale(locale, numberingSystem, null).weekdays(length);
  }

  /**
   * Return an array of format week names.
   * Format weekdays differ from standalone weekdays in that they're meant to appear next to more date information. In some languages, that
   * changes the string.
   * See {@link weekdays}
   * @param {string} [length='long'] - the length of the month representation, such as "narrow", "short", "long".
   * @param {object} opts - options
   * @param {string} [opts.locale='en'] - the locale code
   * @param {string} [opts.numbering=null] - the numbering system
   * @param {string} [opts.outputCalendar='gregory'] - the calendar
   * @return {[string]}
   */
  static weekdaysFormat(length = 'long', { locale = 'en', numberingSystem = null } = {}) {
    return new Locale(locale, numberingSystem, null).weekdays(length, true);
  }

  /**
   * Return an array of meridiems.
   * @param {object} opts - options
   * @param {string} [opts.locale='en'] - the locale code
   * @example Info.meridiems() //=> [ 'AM', 'PM' ]
   * @example Info.meridiems('de') //=> [ 'vorm.', 'nachm.' ]
   * @return {[string]}
   */
  static meridiems({ locale = 'en' } = {}) {
    return new Locale(locale).meridiems();
  }

  /**
   * Return an array of eras, such as ['BC', 'AD']. The locale can be specified, but the calendar system is always Gregorian.
   * @param {string} [length='short'] - the length of the era representation, such as "short" or "long".
   * @param {object} opts - options
   * @param {string} [opts.locale='en'] - the locale code
   * @example Info.eras() //=> [ 'BC', 'AD' ]
   * @example Info.eras('long') //=> [ 'Before Christ', 'Anno Domini' ]
   * @example Info.eras('long', 'fr') //=> [ 'avant Jésus-Christ', 'après Jésus-Christ' ]
   * @return {[string]}
   */
  static eras(length = 'short', { locale = 'en' } = {}) {
    return new Locale(locale, null, 'gregory').eras(length);
  }

  /**
   * Return the set of available features in this environment.
   * Some features of Luxon are not available in all environments. For example, on older browsers, timezone support is not available. Use this function to figure out if that's the case.
   * Keys:
   * * `timezones`: whether this environment supports IANA timezones
   * * `intlTokens`: whether this environment supports internationalized token-based formatting/parsing
   * * `intl`: whether this environment supports general internationalization
   * @example Info.feature() //=> { intl: true, intlTokens: false, timezones: true }
   * @return {object}
   */
  static features() {
    let intl = false,
      intlTokens = false,
      zones = false;

    if (!Util.isUndefined(Intl) && !Util.isUndefined(Intl.DateTimeFormat)) {
      intl = true;

      intlTokens = !Util.isUndefined(Intl.DateTimeFormat.prototype.formatToParts);

      try {
        Intl.DateTimeFormat({ timeZone: 'America/New_York' });
        zones = true;
      } catch (e) {
        zones = false;
      }
    }

    return { intl, intlTokens, zones };
  }
}