{"size": 3048, "ext": "js", "max_stars_repo_path": "src/DateTime/DateTime.js", "max_stars_repo_name": "elusivecodes/FrostDateTime", "max_stars_repo_stars_event_min_datetime": "2019-04-03T07:01:31.000Z", "max_stars_repo_stars_event_max_datetime": "2019-04-03T07:01:31.000Z", "max_issues_repo_path": "src/DateTime/DateTime.js", "max_issues_repo_name": "elusivecodes/FrostDateTime", "max_issues_repo_issues_event_min_datetime": "2020-08-12T07:10:30.000Z", "max_issues_repo_issues_event_max_datetime": "2020-08-12T07:10:30.000Z", "max_forks_repo_path": "src/DateTime/DateTime.js", "max_forks_repo_name": "elusivecodes/FrostDateTime", "max_forks_repo_forks_event_min_datetime": null, "max_forks_repo_forks_event_max_datetime": null}
{"max_stars_count": 1, "max_issues_count": 1, "max_forks_count": null, "avg_line_length": 27.9633027523, "max_line_length": 81, "alphanum_fraction": 0.498687664}
/**
 * DateTime class
 * @class
 */
class DateTime {

    /**
     * New DateTime constructor.
     * @param {string|null} [dateString] The date to parse.
     * @param {object} [options] Options for the new DateTime.
     * @param {string} [options.timeZone] The timeZone to use.
     * @param {string} [options.locale] The locale to use.
     * @returns {DateTime} A new DateTime object.
     */
    constructor(dateString = null, options = {}) {

        let timestamp,
            adjustOffset = false;

        if (dateString === null) {
            timestamp = Date.now();
        } else if (dateString === `${dateString}`) {
            timestamp = Date.parse(dateString);

            if (isNaN(timestamp)) {
                throw new Error('Invalid date string supplied');
            }

            if (!dateString.match(this.constructor._dateStringTimeZoneRegExp)) {
                timestamp -= new Date()
                    .getTimezoneOffset()
                    * 60000;
            }

            adjustOffset = true;
        } else {
            throw new Error('Invalid date supplied');
        }

        this._utcDate = new Date(timestamp);
        this._fraction = 0;
        this._dynamicTz = false;
        this.isValid = true;

        let timeZone = options.timeZone;

        if (!timeZone) {
            timeZone = this.constructor._defaultTimeZone;
        }

        if (['Z', 'GMT'].includes(timeZone)) {
            timeZone = 'UTC';
        }

        const match = timeZone.match(this.constructor._offsetRegExp);
        if (match) {
            this._offset = match[2] * 60 + parseInt(match[4] || 0);
            if (this._offset && match[1] === '+') {
                this._offset *= -1;
            }

            if (this._offset) {
                this._timeZone = DateFormatter.formatOffset(this._offset);
            } else {
                this._dynamicTz = true;
                this._timeZone = 'UTC';
            }
        } else {
            this._dynamicTz = true;
            this._timeZone = timeZone;
        }

        if (this._dynamicTz) {
            this._makeFormatter();
            this._checkOffset();
        }

        if (adjustOffset) {
            this._adjustOffset();
        }

        if (!('locale' in options)) {
            options.locale = this.constructor._defaultLocale;
        }

        this.formatter = DateFormatter.load(options.locale);
        this.relativeFormatter = DateFormatter.loadRelative(options.locale);
    }

    /**
     * Get the number of milliseconds since the UNIX epoch.
     * @returns {number} The number of milliseconds since the UNIX epoch.
     */
    valueOf() {
        return this.getTime();
    }

    /**
     * Return a primitive value of the DateTime.
     * @returns {string|number}
     */
    [Symbol.toPrimitive](hint) {
        return hint === 'number' ?
            this.valueOf() :
            this.toString();
    }

}
