diff --git a/package.json b/package.json index cb7e4e3..d74fc92 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "zeed", "type": "module", - "version": "0.19.3", + "version": "0.19.4", "description": "🌱 Simple foundation library", "author": { "name": "Dirk Holtwick", diff --git a/src/common/data/day-legacy.ts b/src/common/data/day-legacy.ts index 7d69cfb..f81f9ed 100644 --- a/src/common/data/day-legacy.ts +++ b/src/common/data/day-legacy.ts @@ -49,9 +49,9 @@ export class Day { return Day.from(+dateString.replace(/[^0-9]/g, '').slice(0, 8)) } - static fromDate(date: Date, gmt = false): Day { + static fromDate(date: Date, utc = false): Day { return ( - gmt + utc ? Day.fromString(date.toISOString().substr(0, 10)) : Day.from( date.getFullYear() * 10000 @@ -61,11 +61,16 @@ export class Day { ) as Day } + static fromDateUTC(date: Date): Day { + return Day.fromDate(date, true) + } + + /** @deprecated use fromDateUTC */ static fromDateGMT(date: Date): Day { return Day.fromDate(date, true) } - static from(value: DayInputLegacy, gmt = false): Day | undefined { + static from(value: DayInputLegacy, utc = false): Day | undefined { if (typeof value === 'number') { if (value < 100) return @@ -81,7 +86,7 @@ export class Day { return new Day(year * 10000 + month * 100 + day) } else if (value instanceof Date) { - return Day.fromDate(value, gmt) + return Day.fromDate(value, utc) } else if (value instanceof Day) { return value @@ -110,8 +115,8 @@ export class Day { ) } - toDate(gmt = false): Date { - return gmt + toDate(utc = false): Date { + return utc ? new Date(`${this.toString()}T00:00:00.000Z`) : new Date( this.days / 10000, // year @@ -120,6 +125,11 @@ export class Day { ) } + toDateUTC() { + return this.toDate(true) + } + + /** @deprecated use toDateUTC */ toDateGMT() { return this.toDate(true) } @@ -141,8 +151,8 @@ export class Day { dayOffset(offset: number): Day { // Important! Don't use local time here due to summer/winter time days can // be longer or shorter! - return Day.fromDateGMT( - new Date(this.toDateGMT().getTime() + offset * DAY_MS), + return Day.fromDateUTC( + new Date(this.toDateUTC().getTime() + offset * DAY_MS), ) } @@ -167,7 +177,7 @@ export class Day { daysUntil(otherDay: DayInputLegacy): number { return Math.round( - (new Day(otherDay)?.toDateGMT().getTime() - this.toDateGMT().getTime()) + (new Day(otherDay)?.toDateUTC().getTime() - this.toDateUTC().getTime()) / DAY_MS, ) } diff --git a/src/common/data/day.spec.ts b/src/common/data/day.spec.ts index 95c257a..49d029a 100644 --- a/src/common/data/day.spec.ts +++ b/src/common/data/day.spec.ts @@ -75,7 +75,7 @@ describe('days', () => { // This only works locally, but not on Github Actions ;) // expect(day?.toDate()).toEqual(`1987-12-30T23:00:00.000Z`) - expect(day?.toDateGMT()).toEqual(new Date('1987-12-31T00:00:00.000Z')) + expect(day?.toDateUTC()).toEqual(new Date('1987-12-31T00:00:00.000Z')) expect(Day.fromString('2000-01-01')?.days).toEqual(20000101) @@ -87,7 +87,7 @@ describe('days', () => { expect(Day.from([2022, 12, 31])?.days).toBe(20221231) // Following depend on timezone - // let day2 = Day.fromDateGMT(new Date("1987-12-31T00:02:03")) + // let day2 = Day.fromDateUTC(new Date("1987-12-31T00:02:03")) // expect(day2?.days).toEqual(19871230) // expect(new Date().toISOString().startsWith(today().toString())).toBe(true) } @@ -102,7 +102,7 @@ describe('days', () => { // This only works locally, but not on Github Actions ;) // expect(day?.toDate()).toEqual(`1987-12-30T23:00:00.000Z`) - // expect(day?.toDateGMT()).toEqual(new Date("1987-12-31T00:00:00.000Z")) + // expect(day?.toDateUTC()).toEqual(new Date("1987-12-31T00:00:00.000Z")) // expect(Day.fromString("2000-01-01")?.days).toEqual(20000101) @@ -114,7 +114,7 @@ describe('days', () => { // expect(Day.from([2022, 12, 31])?.days).toBe(20221231) // Following depend on timezone - // let day2 = Day.fromDateGMT(new Date("1987-12-31T00:02:03")) + // let day2 = Day.fromDateUTC(new Date("1987-12-31T00:02:03")) // expect(day2?.days).toEqual(19871230) // expect(new Date().toISOString().startsWith(today().toString())).toBe(true) } diff --git a/src/common/data/day.ts b/src/common/data/day.ts index 7225c7b..f38e15f 100644 --- a/src/common/data/day.ts +++ b/src/common/data/day.ts @@ -27,8 +27,8 @@ export function dayToParts(day: DayValue): [number, number, number] { return [dayYear(day), dayMonth(day), dayDay(day)] } -export function dayToDate(day: DayValue, gmt = false): Date { - return gmt +export function dayToDate(day: DayValue, utc = false): Date { + return utc ? new Date(`${dayToString(day)}T00:00:00.000Z`) : new Date( day / 10000, // year @@ -43,7 +43,7 @@ export function dayFromToday(): DayValue { export function dayFromAny( value: DayInput, - gmt = false, + utc = false, ): DayValue | undefined { if (typeof value === 'number') { if (value < 100) @@ -58,19 +58,24 @@ export function dayFromAny( return dayFromParts(year, month, day) } else if (value instanceof Date) { - return dayFromDate(value, gmt) + return dayFromDate(value, utc) // } else if (value instanceof Day) { // return value.days } } +export function dayToDateUTC(day: DayValue): Date { + return dayToDate(day, true) +} + +/** @deprecated use dayToDateUTC */ export function dayToDateGMT(day: DayValue): Date { return dayToDate(day, true) } -export function dayFromDate(date: Date, gmt = false): DayValue { +export function dayFromDate(date: Date, utc = false): DayValue { return ( - gmt + utc ? dayFromString(date.toISOString()) : date.getFullYear() * 10000 + (date.getMonth() + 1) * 100 @@ -78,16 +83,21 @@ export function dayFromDate(date: Date, gmt = false): DayValue { )! } +export function dayFromDateUTC(date: Date): DayValue { + return dayFromDate(date, true) +} + +/** @deprecated use dayFromDateUTC */ export function dayFromDateGMT(date: Date): DayValue { return dayFromDate(date, true) } -export function dayToTimestamp(day: DayValue, gmt = true): number { - return dayToDate(day, gmt).getTime() +export function dayToTimestamp(day: DayValue, utc = true): number { + return dayToDate(day, utc).getTime() } -export function dayFromTimestamp(ms: number, gmt = true): DayValue { - return dayFromDate(new Date(ms), gmt) +export function dayFromTimestamp(ms: number, utc = true): DayValue { + return dayFromDate(new Date(ms), utc) } export function dayToString(day: DayValue, sep = '-') { diff --git a/src/common/time.spec.ts b/src/common/time.spec.ts index d4d129c..db8ae24 100644 --- a/src/common/time.spec.ts +++ b/src/common/time.spec.ts @@ -1,5 +1,5 @@ import { sleep } from './exec' -import { duration, parseDate } from './time' +import { datetimeToLocal, datetimeToUTC, duration, parseDate } from './time' describe('time.spec', () => { it('should measure', async () => { @@ -27,4 +27,13 @@ describe('time.spec', () => { const date = parseDate(inputDate) expect(date).toBe(inputDate) }) + + it('should convert dates', () => { + const dateLocal = new Date('2022-01-01T12:00:00') + // expect(dateLocal?.toString()).toMatchInlineSnapshot(`"Sat Jan 01 2022 12:00:00 GMT+0100 (Central European Standard Time)"`) + // expect(dateLocal.toISOString()).toMatchInlineSnapshot(`"2022-01-01T11:00:00.000Z"`) + // expect(datetimeToUTC(dateLocal)).toMatchInlineSnapshot(`2022-01-01T12:00:00.000Z`) + // expect(datetimeToLocal(dateLocal)).toMatchInlineSnapshot(`2022-01-01T10:00:00.000Z`) + expect(datetimeToLocal(datetimeToUTC(dateLocal))).toEqual(dateLocal) + }) }) diff --git a/src/common/time.ts b/src/common/time.ts index 3b637ca..20c5004 100644 --- a/src/common/time.ts +++ b/src/common/time.ts @@ -69,3 +69,29 @@ export function duration() { // }) } } + +/** If you parsed a date without time zone, you may need to shift it to local time */ +export function datetimeToLocal(fromDate: Date): Date { + return new Date( + fromDate.getUTCFullYear(), + fromDate.getUTCMonth(), + fromDate.getUTCDate(), + fromDate.getUTCHours(), + fromDate.getUTCMinutes(), + fromDate.getUTCSeconds(), + fromDate.getUTCMilliseconds(), + ) +} + +/** If you parsed a date without time zone, you may need to shift it to UTC time */ +export function datetimeToUTC(fromDate: Date): Date { + return new Date(Date.UTC( + fromDate.getFullYear(), + fromDate.getMonth(), + fromDate.getDate(), + fromDate.getHours(), + fromDate.getMinutes(), + fromDate.getSeconds(), + fromDate.getMilliseconds(), + )) +}