UNPKG

@selfage/tz_date

Version:

Timezone aware date handling.

93 lines 13.3 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.TzDate = void 0; // Internal Date representation is set in UTC timezone. Currently only supports negative timezone offset. E.g. UTC-8 class TzDate { static fromDate(date, negativeOffset) { return TzDate.fromNewDate(new Date(date), negativeOffset); } static fromTimestampMs(timestampMs, negativeOffset) { return TzDate.fromNewDate(new Date(timestampMs), negativeOffset); } static fromTimestampString(timestampISOString, // yyyy-MM-ddTHH:mm:ssZ negativeOffset) { return TzDate.fromNewDate(new Date(timestampISOString), negativeOffset); } // The `newDate` will be changed in place. static fromNewDate(newDate, negativeOffset) { if (newDate.getUTCHours() < negativeOffset) { newDate.setUTCDate(newDate.getUTCDate() - 1); } return new TzDate(newDate, negativeOffset); } // Means there is no need to convert wrt timezone. static fromLocalDateString(localDateISOString, // yyyy-MM-dd or yyyy-MM negativeOffset) { let date = new Date(localDateISOString); return new TzDate(date, negativeOffset); } constructor(dateUtc, negativeOffset) { this.dateUtc = dateUtc; this.negativeOffset = negativeOffset; dateUtc.setUTCHours(0); dateUtc.setUTCMinutes(0); dateUtc.setUTCSeconds(0); dateUtc.setUTCMilliseconds(0); } clone() { return new TzDate(new Date(this.dateUtc), this.negativeOffset); } addDays(days) { this.dateUtc.setUTCDate(this.dateUtc.getUTCDate() + days); return this; } addMonths(months) { this.dateUtc.setUTCMonth(this.dateUtc.getUTCMonth() + months); return this; } addYears(years) { this.dateUtc.setUTCFullYear(this.dateUtc.getUTCFullYear() + years); return this; } minusDateInMonths(date) { return ((this.dateUtc.getUTCFullYear() - date.dateUtc.getUTCFullYear()) * 12 + this.dateUtc.getUTCMonth() - date.dateUtc.getUTCMonth()); } minusDateInDays(date) { return ((this.dateUtc.getTime() - date.dateUtc.getTime()) / (1000 * 3600 * 24)); } moveToFirstDayOfMonth() { this.dateUtc.setUTCDate(1); return this; } moveToLastDayOfMonth() { this.dateUtc.setUTCMonth(this.dateUtc.getUTCMonth() + 1); this.dateUtc.setUTCDate(0); return this; } toLocalDateISOString() { let year = this.dateUtc.getUTCFullYear().toString().padStart(4, "0"); let month = (this.dateUtc.getUTCMonth() + 1).toString().padStart(2, "0"); let day = this.dateUtc.getUTCDate().toString().padStart(2, "0"); return `${year}-${month}-${day}`; } toLocalMonthISOString() { let year = this.dateUtc.getUTCFullYear().toString().padStart(4, "0"); let month = (this.dateUtc.getUTCMonth() + 1).toString().padStart(2, "0"); return `${year}-${month}`; } toUtcISOString() { let hour = this.negativeOffset.toString().padStart(2, "0"); return `${this.toLocalDateISOString()}T${hour}:00:00.000Z`; } toLocalISOString() { let hour = this.negativeOffset.toString().padStart(2, "0"); return `${this.toLocalDateISOString()}T00:00:00.000-${hour}`; } toTimestampMs() { return this.dateUtc.getTime() + this.negativeOffset * 60 * 60 * 1000; } } exports.TzDate = TzDate; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHpfZGF0ZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbInR6X2RhdGUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEsb0hBQW9IO0FBQ3BILE1BQWEsTUFBTTtJQUNWLE1BQU0sQ0FBQyxRQUFRLENBQUMsSUFBVSxFQUFFLGNBQXNCO1FBQ3ZELE9BQU8sTUFBTSxDQUFDLFdBQVcsQ0FBQyxJQUFJLElBQUksQ0FBQyxJQUFJLENBQUMsRUFBRSxjQUFjLENBQUMsQ0FBQztJQUM1RCxDQUFDO0lBRU0sTUFBTSxDQUFDLGVBQWUsQ0FDM0IsV0FBbUIsRUFDbkIsY0FBc0I7UUFFdEIsT0FBTyxNQUFNLENBQUMsV0FBVyxDQUFDLElBQUksSUFBSSxDQUFDLFdBQVcsQ0FBQyxFQUFFLGNBQWMsQ0FBQyxDQUFDO0lBQ25FLENBQUM7SUFFTSxNQUFNLENBQUMsbUJBQW1CLENBQy9CLGtCQUEwQixFQUFFLHVCQUF1QjtJQUNuRCxjQUFzQjtRQUV0QixPQUFPLE1BQU0sQ0FBQyxXQUFXLENBQUMsSUFBSSxJQUFJLENBQUMsa0JBQWtCLENBQUMsRUFBRSxjQUFjLENBQUMsQ0FBQztJQUMxRSxDQUFDO0lBRUQsMENBQTBDO0lBQ25DLE1BQU0sQ0FBQyxXQUFXLENBQUMsT0FBYSxFQUFFLGNBQXNCO1FBQzdELElBQUksT0FBTyxDQUFDLFdBQVcsRUFBRSxHQUFHLGNBQWMsRUFBRSxDQUFDO1lBQzNDLE9BQU8sQ0FBQyxVQUFVLENBQUMsT0FBTyxDQUFDLFVBQVUsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDO1FBQy9DLENBQUM7UUFDRCxPQUFPLElBQUksTUFBTSxDQUFDLE9BQU8sRUFBRSxjQUFjLENBQUMsQ0FBQztJQUM3QyxDQUFDO0lBRUQsa0RBQWtEO0lBQzNDLE1BQU0sQ0FBQyxtQkFBbUIsQ0FDL0Isa0JBQTBCLEVBQUUsd0JBQXdCO0lBQ3BELGNBQXNCO1FBRXRCLElBQUksSUFBSSxHQUFHLElBQUksSUFBSSxDQUFDLGtCQUFrQixDQUFDLENB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Q29udGVudCI6WyIvLyBJbnRlcm5hbCBEYXRlIHJlcHJlc2VudGF0aW9uIGlzIHNldCBpbiBVVEMgdGltZXpvbmUuIEN1cnJlbnRseSBvbmx5IHN1cHBvcnRzIG5lZ2F0aXZlIHRpbWV6b25lIG9mZnNldC4gRS5nLiBVVEMtOFxuZXhwb3J0IGNsYXNzIFR6RGF0ZSB7XG4gIHB1YmxpYyBzdGF0aWMgZnJvbURhdGUoZGF0ZTogRGF0ZSwgbmVnYXRpdmVPZmZzZXQ6IG51bWJlcik6IFR6RGF0ZSB7XG4gICAgcmV0dXJuIFR6RGF0ZS5mcm9tTmV3RGF0ZShuZXcgRGF0ZShkYXRlKSwgbmVnYXRpdmVPZmZzZXQpO1xuICB9XG5cbiAgcHVibGljIHN0YXRpYyBmcm9tVGltZXN0YW1wTXMoXG4gICAgdGltZXN0YW1wTXM6IG51bWJlcixcbiAgICBuZWdhdGl2ZU9mZnNldDogbnVtYmVyLFxuICApOiBUekRhdGUge1xuICAgIHJldHVybiBUekRhdGUuZnJvbU5ld0RhdGUobmV3IERhdGUodGltZXN0YW1wTXMpLCBuZWdhdGl2ZU9mZnNldCk7XG4gIH1cblxuICBwdWJsaWMgc3RhdGljIGZyb21UaW1lc3RhbXBTdHJpbmcoXG4gICAgdGltZXN0YW1wSVNPU3RyaW5nOiBzdHJpbmcsIC8vIHl5eXktTU0tZGRUSEg6bW06c3NaXG4gICAgbmVnYXRpdmVPZmZzZXQ6IG51bWJlcixcbiAgKTogVHpEYXRlIHtcbiAgICByZXR1cm4gVHpEYXRlLmZyb21OZXdEYXRlKG5ldyBEYXRlKHRpbWVzdGFtcElTT1N0cmluZyksIG5lZ2F0aXZlT2Zmc2V0KTtcbiAgfVxuXG4gIC8vIFRoZSBgbmV3RGF0ZWAgd2lsbCBiZSBjaGFuZ2VkIGluIHBsYWNlLlxuICBwdWJsaWMgc3RhdGljIGZyb21OZXdEYXRlKG5ld0RhdGU6IERhdGUsIG5lZ2F0aXZlT2Zmc2V0OiBudW1iZXIpOiBUekRhdGUge1xuICAgIGlmIChuZXdEYXRlLmdldFVUQ0hvdXJzKCkgPCBuZWdhdGl2ZU9mZnNldCkge1xuICAgICAgbmV3RGF0ZS5zZXRVVENEYXRlKG5ld0RhdGUuZ2V0VVRDRGF0ZSgpIC0gMSk7XG4gICAgfVxuICAgIHJldHVybiBuZXcgVHpEYXRlKG5ld0RhdGUsIG5lZ2F0aXZlT2Zmc2V0KTtcbiAgfVxuXG4gIC8vIE1lYW5zIHRoZXJlIGlzIG5vIG5lZWQgdG8gY29udmVydCB3cnQgdGltZXpvbmUuXG4gIHB1YmxpYyBzdGF0aWMgZnJvbUxvY2FsRGF0ZVN0cmluZyhcbiAgICBsb2NhbERhdGVJU09TdHJpbmc6IHN0cmluZywgLy8geXl5eS1NTS1kZCBvciB5eXl5LU1NXG4gICAgbmVnYXRpdmVPZmZzZXQ6IG51bWJlcixcbiAgKTogVHpEYXRlIHtcbiAgICBsZXQgZGF0ZSA9IG5ldyBEYXRlKGxvY2FsRGF0ZUlTT1N0cmluZyk7XG4gICAgcmV0dXJuIG5ldyBUekRhdGUoZGF0ZSwgbmVnYXRpdmVPZmZzZXQpO1xuICB9XG5cbiAgcHVibGljIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgZGF0ZVV0YzogRGF0ZSxcbiAgICBwcml2YXRlIG5lZ2F0aXZlT2Zmc2V0OiBudW1iZXIsXG4gICkge1xuICAgIGRhdGVVdGMuc2V0VVRDSG91cnMoMCk7XG4gICAgZGF0ZVV0Yy5zZXRVVENNaW51dGVzKDApO1xuICAgIGRhdGVVdGMuc2V0VVRDU2Vjb25kcygwKTtcbiAgICBkYXRlVXRjLnNldFVUQ01pbGxpc2Vjb25kcygwKTtcbiAgfVxuXG4gIHB1YmxpYyBjbG9uZSgpOiBUekRhdGUge1xuICAgIHJldHVybiBuZXcgVHpEYXRlKG5ldyBEYXRlKHRoaXMuZGF0ZVV0YyksIHRoaXMubmVnYXRpdmVPZmZzZXQpO1xuICB9XG5cbiAgcHVibGljIGFkZERheXMoZGF5czogbnVtYmVyKTogVHpEYXRlIHtcbiAgICB0aGlzLmRhdGVVdGMuc2V0VVRDRGF0ZSh0aGlzLmRhdGVVdGMuZ2V0VVRDRGF0ZSgpICsgZGF5cyk7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICBwdWJsaWMgYWRkTW9udGhzKG1vbnRoczogbnVtYmVyKTogVHpEYXRlIHtcbiAgICB0aGlzLmRhdGVVdGMuc2V0VVRDTW9udGgodGhpcy5kYXRlVXRjLmdldFVUQ01vbnRoKCkgKyBtb250aHMpO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgcHVibGljIGFkZFllYXJzKHllYXJzOiBudW1iZXIpOiBUekRhdGUge1xuICAgIHRoaXMuZGF0ZVV0Yy5zZXRVVENGdWxsWWVhcih0aGlzLmRhdGVVdGMuZ2V0VVRDRnVsbFllYXIoKSArIHllYXJzKTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIHB1YmxpYyBtaW51c0RhdGVJbk1vbnRocyhkYXRlOiBUekRhdGUpOiBudW1iZXIge1xuICAgIHJldHVybiAoXG4gICAgICAodGhpcy5kYXRlVXRjLmdldFVUQ0Z1bGxZZWFyKCkgLSBkYXRlLmRhdGVVdGMuZ2V0VVRDRnVsbFllYXIoKSkgKiAxMiArXG4gICAgICB0aGlzLmRhdGVVdGMuZ2V0VVRDTW9udGgoKSAtXG4gICAgICBkYXRlLmRhdGVVdGMuZ2V0VVRDTW9udGgoKVxuICAgICk7XG4gIH1cblxuICBwdWJsaWMgbWludXNEYXRlSW5EYXlzKGRhdGU6IFR6RGF0ZSk6IG51bWJlciB7XG4gICAgcmV0dXJuIChcbiAgICAgICh0aGlzLmRhdGVVdGMuZ2V0VGltZSgpIC0gZGF0ZS5kYXRlVXRjLmdldFRpbWUoKSkgLyAoMTAwMCAqIDM2MDAgKiAyNClcbiAgICApO1xuICB9XG5cbiAgcHVibGljIG1vdmVUb0ZpcnN0RGF5T2ZNb250aCgpOiBUekRhdGUge1xuICAgIHRoaXMuZGF0ZVV0Yy5zZXRVVENEYXRlKDEpO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgcHVibGljIG1vdmVUb0xhc3REYXlPZk1vbnRoKCk6IFR6RGF0ZSB7XG4gICAgdGhpcy5kYXRlVXRjLnNldFVUQ01vbnRoKHRoaXMuZGF0ZVV0Yy5nZXRVVENNb250aCgpICsgMSk7XG4gICAgdGhpcy5kYXRlVXRjLnNldFVUQ0RhdGUoMCk7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICBwdWJsaWMgdG9Mb2NhbERhdGVJU09TdHJpbmcoKTogc3RyaW5nIHtcbiAgICBsZXQgeWVhciA9IHRoaXMuZGF0ZVV0Yy5nZXRVVENGdWxsWWVhcigpLnRvU3RyaW5nKCkucGFkU3RhcnQoNCwgXCIwXCIpO1xuICAgIGxldCBtb250aCA9ICh0aGlzLmRhdGVVdGMuZ2V0VVRDTW9udGgoKSArIDEpLnRvU3RyaW5nKCkucGFkU3RhcnQoMiwgXCIwXCIpO1xuICAgIGxldCBkYXkgPSB0aGlzLmRhdGVVdGMuZ2V0VVRDRGF0ZSgpLnRvU3RyaW5nKCkucGFkU3RhcnQoMiwgXCIwXCIpO1xuICAgIHJldHVybiBgJHt5ZWFyfS0ke21vbnRofS0ke2RheX1gO1xuICB9XG5cbiAgcHVibGljIHRvTG9jYWxNb250aElTT1N0cmluZygpOiBzdHJpbmcge1xuICAgIGxldCB5ZWFyID0gdGhpcy5kYXRlVXRjLmdldFVUQ0Z1bGxZZWFyKCkudG9TdHJpbmcoKS5wYWRTdGFydCg0LCBcIjBcIik7XG4gICAgbGV0IG1vbnRoID0gKHRoaXMuZGF0ZVV0Yy5nZXRVVENNb250aCgpICsgMSkudG9TdHJpbmcoKS5wYWRTdGFydCgyLCBcIjBcIik7XG4gICAgcmV0dXJuIGAke3llYXJ9LSR7bW9udGh9YDtcbiAgfVxuXG4gIHB1YmxpYyB0b1V0Y0lTT1N0cmluZygpOiBzdHJpbmcge1xuICAgIGxldCBob3VyID0gdGhpcy5uZWdhdGl2ZU9mZnNldC50b1N0cmluZygpLnBhZFN0YXJ0KDIsIFwiMFwiKTtcbiAgICByZXR1cm4gYCR7dGhpcy50b0xvY2FsRGF0ZUlTT1N0cmluZygpfVQke2hvdXJ9OjAwOjAwLjAwMFpgO1xuICB9XG5cbiAgcHVibGljIHRvTG9jYWxJU09TdHJpbmcoKTogc3RyaW5nIHtcbiAgICBsZXQgaG91ciA9IHRoaXMubmVnYXRpdmVPZmZzZXQudG9TdHJpbmcoKS5wYWRTdGFydCgyLCBcIjBcIik7XG4gICAgcmV0dXJuIGAke3RoaXMudG9Mb2NhbERhdGVJU09TdHJpbmcoKX1UMDA6MDA6MDAuMDAwLSR7aG91cn1gO1xuICB9XG5cbiAgcHVibGljIHRvVGltZXN0YW1wTXMoKTogbnVtYmVyIHtcbiAgICByZXR1cm4gdGhpcy5kYXRlVXRjLmdldFRpbWUoKSArIHRoaXMubmVnYXRpdmVPZmZzZXQgKiA2MCAqIDYwICogMTAwMDtcbiAgfVxufVxuIl19