"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.getYearEndAt = exports.getYearBeginAt = exports.getMonthEndAt = exports.getMonthBeginAt = exports.getDayEndAt = exports.getDayBeginAt = exports.atToYearEnd = exports.atToYearBegin = exports.atToMonthEnd = exports.atToMonthBegin = exports.atToDayEnd = exports.atToDayBegin = exports.isValid = exports.safeParse = exports.getAt = exports.diff = exports.equal = exports.getRoundSeconds = exports.subTimeFromNow = exports.subTime = exports.addTimeFromNow = exports.addTime = exports.addSubTime = void 0;
const at_parts_1 = require("./at-parts");
const interval_1 = require("./interval/interval");
const interval_forge_1 = require("./interval/interval-forge");
function addSubTime(at, intervalArg, direction) {
    const ainterval = (0, interval_forge_1.buildIntervalData)(intervalArg);
    direction = direction * (ainterval.inversed ? -1 : 1);
    const cloneAt = new Date(at.getTime());
    if (ainterval.Y) {
        cloneAt.setFullYear(cloneAt.getFullYear() + (ainterval.Y * direction));
    }
    if (ainterval.M) {
        cloneAt.setMonth(cloneAt.getMonth() + (ainterval.M * direction));
    }
    if (ainterval.W) {
        cloneAt.setDate(cloneAt.getDate() + (ainterval.W * at_parts_1.WeekTo.days * direction));
    }
    if (ainterval.D) {
        cloneAt.setDate(cloneAt.getDate() + (ainterval.D * direction));
    }
    if (ainterval.h) {
        cloneAt.setUTCHours(cloneAt.getUTCHours() + (ainterval.h * direction));
    }
    if (ainterval.m) {
        cloneAt.setUTCMinutes(cloneAt.getUTCMinutes() + (ainterval.m * direction));
    }
    if (ainterval.s) {
        cloneAt.setUTCSeconds(cloneAt.getUTCSeconds() + (ainterval.s * direction));
    }
    if (ainterval.ms) {
        cloneAt.setUTCMilliseconds(cloneAt.getUTCMilliseconds() + (ainterval.ms * direction));
    }
    return cloneAt;
}
exports.addSubTime = addSubTime;
function addTime(at, intervalArg) {
    return addSubTime(at, intervalArg, 1);
}
exports.addTime = addTime;
function addTimeFromNow(interval) {
    return addSubTime(new Date(), interval, 1);
}
exports.addTimeFromNow = addTimeFromNow;
function subTime(at, interval) {
    return addSubTime(at, interval, -1);
}
exports.subTime = subTime;
function subTimeFromNow(interval) {
    return addSubTime(new Date(), interval, -1);
}
exports.subTimeFromNow = subTimeFromNow;
/**
 * Retourne les secondes arrondies d'une dates
 */
function getRoundSeconds(at) {
    return Math.round(at.getTime() / 1000);
}
exports.getRoundSeconds = getRoundSeconds;
/**
 * Détermine si deux date sont équivalentes à la seconde près
 */
function equal(at1, at2) {
    return getRoundSeconds(at1) === getRoundSeconds(at2);
}
exports.equal = equal;
/**
 * Retourne l'interval entre deux object Date
 * Si le premier est plus récent que le second, l'interval
 * n'est pas "inversed", sinon il l'est.
 */
function diff(at1, at2) {
    let diffAt = at1.getTime() - at2.getTime();
    let inversed = false;
    if (diffAt < 0) {
        inversed = true;
        diffAt *= -1;
    }
    const at = new Date(diffAt);
    // Suppression du décalage horaire
    return new interval_1.Interval({
        Y: at.getFullYear() - 1970,
        M: at.getMonth(),
        W: 0,
        D: at.getDate() - 1,
        h: at.getHours() + (at.getTimezoneOffset() / 60),
        m: at.getMinutes(),
        s: at.getSeconds(),
        ms: at.getMilliseconds(),
        inversed: inversed
    });
}
exports.diff = diff;
function getAt(spec) {
    if (typeof spec === 'object') {
        return spec;
    }
    const timestamp = Date.parse(spec);
    if (isNaN(timestamp)) {
        return null;
    }
    return new Date(timestamp);
}
exports.getAt = getAt;
/**
 * @deprecated
 */
function safeParse(spec) {
    return getAt(spec);
}
exports.safeParse = safeParse;
function isValid(at) {
    return at && !isNaN(at.getTime());
}
exports.isValid = isValid;
function atToDayBegin(at) {
    at.setHours(0, 0, 0, 0);
}
exports.atToDayBegin = atToDayBegin;
function atToDayEnd(at) {
    at.setHours(23, 59, 59, 999);
}
exports.atToDayEnd = atToDayEnd;
function atToMonthBegin(at) {
    at.setDate(1);
    atToDayBegin(at);
}
exports.atToMonthBegin = atToMonthBegin;
function atToMonthEnd(at) {
    at.setDate(15);
    at.setMonth(at.getMonth() + 1);
    atToMonthBegin(at);
    at.setMilliseconds(at.getMilliseconds() - 1);
}
exports.atToMonthEnd = atToMonthEnd;
function atToYearBegin(at) {
    at.setMonth(0);
    atToMonthBegin(at);
}
exports.atToYearBegin = atToYearBegin;
function atToYearEnd(at) {
    at.setMonth(11);
    atToMonthEnd(at);
}
exports.atToYearEnd = atToYearEnd;
function getDayBeginAt(at) {
    const cAt = new Date(at);
    atToDayBegin(cAt);
    return cAt;
}
exports.getDayBeginAt = getDayBeginAt;
function getDayEndAt(at) {
    const cAt = new Date(at);
    atToDayEnd(cAt);
    return cAt;
}
exports.getDayEndAt = getDayEndAt;
function getMonthBeginAt(at) {
    const cAt = new Date(at);
    atToMonthBegin(cAt);
    return cAt;
}
exports.getMonthBeginAt = getMonthBeginAt;
function getMonthEndAt(at) {
    const cAt = new Date(at);
    atToMonthEnd(cAt);
    return cAt;
}
exports.getMonthEndAt = getMonthEndAt;
function getYearBeginAt(at) {
    const cAt = new Date(at);
    atToYearBegin(cAt);
    return cAt;
}
exports.getYearBeginAt = getYearBeginAt;
function getYearEndAt(at) {
    const cAt = new Date(at);
    atToYearEnd(cAt);
    return cAt;
}
exports.getYearEndAt = getYearEndAt;
