From 80e42a10814ebfc1acab627666a2bbc0ddbf22bb Mon Sep 17 00:00:00 2001 From: MaxAake <61233757+MaxAake@users.noreply.github.com> Date: Fri, 22 Nov 2024 11:33:05 +0100 Subject: [PATCH 01/14] fixing minute offset issue in certain time zones --- packages/core/src/temporal-types.ts | 12 ++++++++++-- packages/core/test/temporal-types.test.ts | 14 +++++++++----- .../neo4j-driver-deno/lib/core/temporal-types.ts | 12 ++++++++++-- 3 files changed, 29 insertions(+), 9 deletions(-) diff --git a/packages/core/src/temporal-types.ts b/packages/core/src/temporal-types.ts index a9837d2d0..3616abb9a 100644 --- a/packages/core/src/temporal-types.ts +++ b/packages/core/src/temporal-types.ts @@ -375,7 +375,11 @@ export class Date { * @returns {StandardDate} Standard JavaScript `Date` at `00:00:00.000` UTC. */ toStandardDate (): StandardDate { - return util.isoStringToStandardDate(this.toString()) + const res = util.isoStringToStandardDate(this.toString()) + if (res.getTimezoneOffset() > 0 && res.getTimezoneOffset() % 60 !== 0) { // LESS THAN SHOULD MAYBE BE GREATER THAN + res.setMinutes(res.getMinutes() + res.getTimezoneOffset() % 60) + } + return res } /** @@ -665,7 +669,11 @@ export class DateTime { * @throws {Error} If the time zone offset is not defined in the object. */ toStandardDate (): StandardDate { - return util.toStandardDate(this._toUTC()) + const res = util.toStandardDate(this._toUTC()) + if (res.getTimezoneOffset() > 0 && res.getTimezoneOffset() % 60 !== 0) { // LESS THAN SHOULD MAYBE BE GREATER THAN + res.setMinutes(res.getMinutes() + res.getTimezoneOffset() % 60) + } + return res } /** diff --git a/packages/core/test/temporal-types.test.ts b/packages/core/test/temporal-types.test.ts index d51d0057d..e2bcb3e37 100644 --- a/packages/core/test/temporal-types.test.ts +++ b/packages/core/test/temporal-types.test.ts @@ -153,12 +153,16 @@ describe('DateTime', () => { it('should be the reverse operation of fromStandardDate', () => { fc.assert( - fc.property(fc.date(), (date) => { - const datetime = DateTime.fromStandardDate(date) - const receivedDate = datetime.toStandardDate() + fc.property( + fc.date({ + max: temporalUtil.newDate(MAX_UTC_IN_MS - ONE_DAY_IN_MS), + min: temporalUtil.newDate(MIN_UTC_IN_MS + ONE_DAY_IN_MS) + }), (date) => { + const datetime = DateTime.fromStandardDate(date) + const receivedDate = datetime.toStandardDate() - expect(receivedDate).toEqual(date) - }) + expect(receivedDate).toEqual(date) + }) ) }) }) diff --git a/packages/neo4j-driver-deno/lib/core/temporal-types.ts b/packages/neo4j-driver-deno/lib/core/temporal-types.ts index 2461e3d1d..84e81b0ce 100644 --- a/packages/neo4j-driver-deno/lib/core/temporal-types.ts +++ b/packages/neo4j-driver-deno/lib/core/temporal-types.ts @@ -375,7 +375,11 @@ export class Date { * @returns {StandardDate} Standard JavaScript `Date` at `00:00:00.000` UTC. */ toStandardDate (): StandardDate { - return util.isoStringToStandardDate(this.toString()) + var res = util.isoStringToStandardDate(this.toString()) + if(res.getTimezoneOffset() > 0 && res.getTimezoneOffset()%60 !== 0){ //LESS THAN SHOULD MAYBE BE GREATER THAN + res.setMinutes(res.getMinutes() + res.getTimezoneOffset()%60) + } + return res } /** @@ -665,7 +669,11 @@ export class DateTime { * @throws {Error} If the time zone offset is not defined in the object. */ toStandardDate (): StandardDate { - return util.toStandardDate(this._toUTC()) + var res = util.toStandardDate(this._toUTC()) + if(res.getTimezoneOffset() > 0 && res.getTimezoneOffset()%60 !== 0){ //LESS THAN SHOULD MAYBE BE GREATER THAN + res.setMinutes(res.getMinutes() + res.getTimezoneOffset()%60) + } + return res } /** From 022544ab4947c854bb4ceceb2cfb0d65826c4557 Mon Sep 17 00:00:00 2001 From: MaxAake <61233757+MaxAake@users.noreply.github.com> Date: Tue, 26 Nov 2024 09:08:52 +0000 Subject: [PATCH 02/14] improved solution for DateTime The date solution is still rather hacky, but functions --- packages/core/src/internal/temporal-util.ts | 13 +++++-------- packages/core/src/temporal-types.ts | 8 ++------ .../lib/core/internal/temporal-util.ts | 13 +++++-------- .../neo4j-driver-deno/lib/core/temporal-types.ts | 12 ++++-------- 4 files changed, 16 insertions(+), 30 deletions(-) diff --git a/packages/core/src/internal/temporal-util.ts b/packages/core/src/internal/temporal-util.ts index 2951d5ac5..46e0eb495 100644 --- a/packages/core/src/internal/temporal-util.ts +++ b/packages/core/src/internal/temporal-util.ts @@ -349,14 +349,11 @@ export function totalNanoseconds ( * @return {number} the time zone offset in seconds. */ export function timeZoneOffsetInSeconds (standardDate: Date): number { - const secondsPortion = standardDate.getSeconds() >= standardDate.getUTCSeconds() - ? standardDate.getSeconds() - standardDate.getUTCSeconds() - : standardDate.getSeconds() - standardDate.getUTCSeconds() + 60 - const offsetInMinutes = standardDate.getTimezoneOffset() - if (offsetInMinutes === 0) { - return 0 + secondsPortion - } - return -1 * offsetInMinutes * SECONDS_PER_MINUTE + secondsPortion + const secondsPortion = standardDate.getSeconds() - standardDate.getUTCSeconds() + const minutesPortion = standardDate.getMinutes() - standardDate.getUTCMinutes() + const hoursPortion = standardDate.getHours() - standardDate.getUTCHours() + const daysPortion = standardDate.getDay() - standardDate.getUTCDay() + return daysPortion * SECONDS_PER_DAY + hoursPortion * SECONDS_PER_HOUR + minutesPortion * SECONDS_PER_MINUTE + secondsPortion } /** diff --git a/packages/core/src/temporal-types.ts b/packages/core/src/temporal-types.ts index 3616abb9a..7412522e5 100644 --- a/packages/core/src/temporal-types.ts +++ b/packages/core/src/temporal-types.ts @@ -376,7 +376,7 @@ export class Date { */ toStandardDate (): StandardDate { const res = util.isoStringToStandardDate(this.toString()) - if (res.getTimezoneOffset() > 0 && res.getTimezoneOffset() % 60 !== 0) { // LESS THAN SHOULD MAYBE BE GREATER THAN + if (res.getTimezoneOffset() > 0 && res.getTimezoneOffset() % 60 !== 0) { res.setMinutes(res.getMinutes() + res.getTimezoneOffset() % 60) } return res @@ -669,11 +669,7 @@ export class DateTime { * @throws {Error} If the time zone offset is not defined in the object. */ toStandardDate (): StandardDate { - const res = util.toStandardDate(this._toUTC()) - if (res.getTimezoneOffset() > 0 && res.getTimezoneOffset() % 60 !== 0) { // LESS THAN SHOULD MAYBE BE GREATER THAN - res.setMinutes(res.getMinutes() + res.getTimezoneOffset() % 60) - } - return res + return util.toStandardDate(this._toUTC()) } /** diff --git a/packages/neo4j-driver-deno/lib/core/internal/temporal-util.ts b/packages/neo4j-driver-deno/lib/core/internal/temporal-util.ts index be1961ec8..86898ccf7 100644 --- a/packages/neo4j-driver-deno/lib/core/internal/temporal-util.ts +++ b/packages/neo4j-driver-deno/lib/core/internal/temporal-util.ts @@ -349,14 +349,11 @@ export function totalNanoseconds ( * @return {number} the time zone offset in seconds. */ export function timeZoneOffsetInSeconds (standardDate: Date): number { - const secondsPortion = standardDate.getSeconds() >= standardDate.getUTCSeconds() - ? standardDate.getSeconds() - standardDate.getUTCSeconds() - : standardDate.getSeconds() - standardDate.getUTCSeconds() + 60 - const offsetInMinutes = standardDate.getTimezoneOffset() - if (offsetInMinutes === 0) { - return 0 + secondsPortion - } - return -1 * offsetInMinutes * SECONDS_PER_MINUTE + secondsPortion + const secondsPortion = standardDate.getSeconds() - standardDate.getUTCSeconds() + const minutesPortion = standardDate.getMinutes() - standardDate.getUTCMinutes() + const hoursPortion = standardDate.getHours() - standardDate.getUTCHours() + const daysPortion = standardDate.getDay() - standardDate.getUTCDay() + return daysPortion * SECONDS_PER_DAY + hoursPortion * SECONDS_PER_HOUR + minutesPortion * SECONDS_PER_MINUTE + secondsPortion } /** diff --git a/packages/neo4j-driver-deno/lib/core/temporal-types.ts b/packages/neo4j-driver-deno/lib/core/temporal-types.ts index 84e81b0ce..bd7fd2359 100644 --- a/packages/neo4j-driver-deno/lib/core/temporal-types.ts +++ b/packages/neo4j-driver-deno/lib/core/temporal-types.ts @@ -375,9 +375,9 @@ export class Date { * @returns {StandardDate} Standard JavaScript `Date` at `00:00:00.000` UTC. */ toStandardDate (): StandardDate { - var res = util.isoStringToStandardDate(this.toString()) - if(res.getTimezoneOffset() > 0 && res.getTimezoneOffset()%60 !== 0){ //LESS THAN SHOULD MAYBE BE GREATER THAN - res.setMinutes(res.getMinutes() + res.getTimezoneOffset()%60) + const res = util.isoStringToStandardDate(this.toString()) + if (res.getTimezoneOffset() > 0 && res.getTimezoneOffset() % 60 !== 0) { + res.setMinutes(res.getMinutes() + res.getTimezoneOffset() % 60) } return res } @@ -669,11 +669,7 @@ export class DateTime { * @throws {Error} If the time zone offset is not defined in the object. */ toStandardDate (): StandardDate { - var res = util.toStandardDate(this._toUTC()) - if(res.getTimezoneOffset() > 0 && res.getTimezoneOffset()%60 !== 0){ //LESS THAN SHOULD MAYBE BE GREATER THAN - res.setMinutes(res.getMinutes() + res.getTimezoneOffset()%60) - } - return res + return util.toStandardDate(this._toUTC()) } /** From e94d83008072f2ca08e638cbecb46fc2b0435f20 Mon Sep 17 00:00:00 2001 From: MaxAake <61233757+MaxAake@users.noreply.github.com> Date: Wed, 27 Nov 2024 14:26:03 -0100 Subject: [PATCH 03/14] huge, bloaty, robust solution to datetimes --- packages/core/src/internal/temporal-util.ts | 37 +++++++++++++++- .../lib/core/internal/temporal-util.ts | 44 ++++++++++++++++++- 2 files changed, 77 insertions(+), 4 deletions(-) diff --git a/packages/core/src/internal/temporal-util.ts b/packages/core/src/internal/temporal-util.ts index 46e0eb495..f30562f91 100644 --- a/packages/core/src/internal/temporal-util.ts +++ b/packages/core/src/internal/temporal-util.ts @@ -352,8 +352,41 @@ export function timeZoneOffsetInSeconds (standardDate: Date): number { const secondsPortion = standardDate.getSeconds() - standardDate.getUTCSeconds() const minutesPortion = standardDate.getMinutes() - standardDate.getUTCMinutes() const hoursPortion = standardDate.getHours() - standardDate.getUTCHours() - const daysPortion = standardDate.getDay() - standardDate.getUTCDay() - return daysPortion * SECONDS_PER_DAY + hoursPortion * SECONDS_PER_HOUR + minutesPortion * SECONDS_PER_MINUTE + secondsPortion + const daysPortion = _getDayOffset(standardDate) + console.log('UTCDATE:', standardDate.getUTCDate(), standardDate.getDate()) + console.log(secondsPortion, minutesPortion, hoursPortion, daysPortion) + return hoursPortion * SECONDS_PER_HOUR + minutesPortion * SECONDS_PER_MINUTE + secondsPortion + daysPortion * SECONDS_PER_DAY +} + +function _getDayOffset (standardDate: Date): number { + if (standardDate.getMonth() === standardDate.getUTCMonth()) { + return standardDate.getDate() - standardDate.getUTCDate() + } else if ((standardDate.getFullYear() > standardDate.getUTCFullYear()) || (standardDate.getMonth() > standardDate.getUTCMonth() && standardDate.getFullYear() === standardDate.getUTCFullYear())) { + console.log('1', standardDate.getDate(), _daysUntilNextMonth(standardDate.getUTCMonth(), standardDate.getUTCFullYear()), standardDate.getUTCDate()) + return standardDate.getDate() + _daysUntilNextMonth(standardDate.getUTCMonth(), standardDate.getUTCFullYear()) - standardDate.getUTCDate() - 2 + } else { + console.log('2', standardDate.getUTCDate(), _daysUntilNextMonth(standardDate.getMonth(), standardDate.getFullYear()), standardDate.getDate()) + return standardDate.getUTCDate() + _daysUntilNextMonth(standardDate.getMonth(), standardDate.getFullYear()) - standardDate.getDate() - 2 + } +} + +function _daysUntilNextMonth (month: number, year: number): number { + console.log(month) + if (month === 1) { + if (year % 400 === 0) { + return 29 + } else if (year % 100 === 0) { + return 28 + } else if (year % 4 === 0) { + return 29 + } else { + return 28 + } + } else if ([0, 2, 4, 6, 7, 9, 11].includes(month)) { + return 31 + } else { + return 30 + } } /** diff --git a/packages/neo4j-driver-deno/lib/core/internal/temporal-util.ts b/packages/neo4j-driver-deno/lib/core/internal/temporal-util.ts index 86898ccf7..4ac56a8c2 100644 --- a/packages/neo4j-driver-deno/lib/core/internal/temporal-util.ts +++ b/packages/neo4j-driver-deno/lib/core/internal/temporal-util.ts @@ -352,8 +352,48 @@ export function timeZoneOffsetInSeconds (standardDate: Date): number { const secondsPortion = standardDate.getSeconds() - standardDate.getUTCSeconds() const minutesPortion = standardDate.getMinutes() - standardDate.getUTCMinutes() const hoursPortion = standardDate.getHours() - standardDate.getUTCHours() - const daysPortion = standardDate.getDay() - standardDate.getUTCDay() - return daysPortion * SECONDS_PER_DAY + hoursPortion * SECONDS_PER_HOUR + minutesPortion * SECONDS_PER_MINUTE + secondsPortion + const daysPortion = _getDayOffset(standardDate) + console.log("UTCDATE:", standardDate.getUTCDate(), standardDate.getDate()) + console.log(secondsPortion, minutesPortion, hoursPortion, daysPortion) + return hoursPortion * SECONDS_PER_HOUR + minutesPortion * SECONDS_PER_MINUTE + secondsPortion + daysPortion * SECONDS_PER_DAY +} + +function _getDayOffset(standardDate: Date): number { + if(standardDate.getMonth() === standardDate.getUTCMonth()) { + return standardDate.getDate() - standardDate.getUTCDate() + } + else if((standardDate.getFullYear() > standardDate.getUTCFullYear()) || (standardDate.getMonth() > standardDate.getUTCMonth() && standardDate.getFullYear() === standardDate.getUTCFullYear())) { + console.log("1", standardDate.getDate(), _daysUntilNextMonth(standardDate.getUTCMonth(), standardDate.getUTCFullYear()), standardDate.getUTCDate()) + return standardDate.getDate() + _daysUntilNextMonth(standardDate.getUTCMonth(), standardDate.getUTCFullYear()) - standardDate.getUTCDate() - 2 + } + else { + console.log("2", standardDate.getUTCDate(), _daysUntilNextMonth(standardDate.getMonth(), standardDate.getFullYear()), standardDate.getDate()) + return standardDate.getUTCDate() + _daysUntilNextMonth(standardDate.getMonth(), standardDate.getFullYear()) - standardDate.getDate() - 2 + } +} + +function _daysUntilNextMonth(month: number, year: number): number { + console.log(month) + if(month === 1) { + if (year%400 === 0){ + return 29 + } + else if(year%100 === 0){ + return 28 + } + else if(year%4 === 0){ + return 29 + } + else{ + return 28 + } + } + else if([0, 2, 4, 6, 7, 9, 11].includes(month)) { + return 31 + } + else { + return 30 + } } /** From 7e241f14029b9f04f15238327bd2ebd8de66aa53 Mon Sep 17 00:00:00 2001 From: MaxAake <61233757+MaxAake@users.noreply.github.com> Date: Thu, 28 Nov 2024 12:41:43 -0100 Subject: [PATCH 04/14] deno build and fix tests for date --- packages/core/src/temporal-types.ts | 6 +-- packages/core/test/temporal-types.test.ts | 9 +++-- .../lib/core/internal/temporal-util.ts | 37 ++++++++----------- .../lib/core/temporal-types.ts | 6 +-- 4 files changed, 22 insertions(+), 36 deletions(-) diff --git a/packages/core/src/temporal-types.ts b/packages/core/src/temporal-types.ts index 7412522e5..a9837d2d0 100644 --- a/packages/core/src/temporal-types.ts +++ b/packages/core/src/temporal-types.ts @@ -375,11 +375,7 @@ export class Date { * @returns {StandardDate} Standard JavaScript `Date` at `00:00:00.000` UTC. */ toStandardDate (): StandardDate { - const res = util.isoStringToStandardDate(this.toString()) - if (res.getTimezoneOffset() > 0 && res.getTimezoneOffset() % 60 !== 0) { - res.setMinutes(res.getMinutes() + res.getTimezoneOffset() % 60) - } - return res + return util.isoStringToStandardDate(this.toString()) } /** diff --git a/packages/core/test/temporal-types.test.ts b/packages/core/test/temporal-types.test.ts index e2bcb3e37..3e7c7ba28 100644 --- a/packages/core/test/temporal-types.test.ts +++ b/packages/core/test/temporal-types.test.ts @@ -19,6 +19,7 @@ import { StandardDate } from '../src/graph-types' import { LocalDateTime, Date, DateTime, Duration, isDuration, LocalTime, isLocalTime, Time, isTime, isDate, isLocalDateTime, isDateTime } from '../src/temporal-types' import { temporalUtil } from '../src/internal' import fc from 'fast-check' +import { timeZoneOffsetInSeconds } from '../src/internal/temporal-util' const MIN_UTC_IN_MS = -8_640_000_000_000_000 const MAX_UTC_IN_MS = 8_640_000_000_000_000 @@ -31,9 +32,9 @@ describe('Date', () => { const standardDate = localDatetime.toStandardDate() - expect(standardDate.getFullYear()).toEqual(localDatetime.year) - expect(standardDate.getMonth()).toEqual(localDatetime.month - 1) - expect(standardDate.getDate()).toEqual(localDatetime.day) + expect(standardDate.getUTCFullYear()).toEqual(localDatetime.year) + expect(standardDate.getUTCMonth()).toEqual(localDatetime.month - 1) + expect(standardDate.getUTCDate()).toEqual(localDatetime.day) }) it('should be the reverse operation of fromStandardDate but losing time information', () => { @@ -48,7 +49,7 @@ describe('Date', () => { const receivedDate = date.toStandardDate() const adjustedDateTime = temporalUtil.newDate(standardDate) - adjustedDateTime.setHours(0, offset(receivedDate)) + adjustedDateTime.setHours(0, 0, timeZoneOffsetInSeconds(standardDate)) expect(receivedDate.getFullYear()).toEqual(adjustedDateTime.getFullYear()) expect(receivedDate.getMonth()).toEqual(adjustedDateTime.getMonth()) diff --git a/packages/neo4j-driver-deno/lib/core/internal/temporal-util.ts b/packages/neo4j-driver-deno/lib/core/internal/temporal-util.ts index 4ac56a8c2..48ea7b465 100644 --- a/packages/neo4j-driver-deno/lib/core/internal/temporal-util.ts +++ b/packages/neo4j-driver-deno/lib/core/internal/temporal-util.ts @@ -353,45 +353,38 @@ export function timeZoneOffsetInSeconds (standardDate: Date): number { const minutesPortion = standardDate.getMinutes() - standardDate.getUTCMinutes() const hoursPortion = standardDate.getHours() - standardDate.getUTCHours() const daysPortion = _getDayOffset(standardDate) - console.log("UTCDATE:", standardDate.getUTCDate(), standardDate.getDate()) + console.log('UTCDATE:', standardDate.getUTCDate(), standardDate.getDate()) console.log(secondsPortion, minutesPortion, hoursPortion, daysPortion) return hoursPortion * SECONDS_PER_HOUR + minutesPortion * SECONDS_PER_MINUTE + secondsPortion + daysPortion * SECONDS_PER_DAY } -function _getDayOffset(standardDate: Date): number { - if(standardDate.getMonth() === standardDate.getUTCMonth()) { +function _getDayOffset (standardDate: Date): number { + if (standardDate.getMonth() === standardDate.getUTCMonth()) { return standardDate.getDate() - standardDate.getUTCDate() - } - else if((standardDate.getFullYear() > standardDate.getUTCFullYear()) || (standardDate.getMonth() > standardDate.getUTCMonth() && standardDate.getFullYear() === standardDate.getUTCFullYear())) { - console.log("1", standardDate.getDate(), _daysUntilNextMonth(standardDate.getUTCMonth(), standardDate.getUTCFullYear()), standardDate.getUTCDate()) + } else if ((standardDate.getFullYear() > standardDate.getUTCFullYear()) || (standardDate.getMonth() > standardDate.getUTCMonth() && standardDate.getFullYear() === standardDate.getUTCFullYear())) { + console.log('1', standardDate.getDate(), _daysUntilNextMonth(standardDate.getUTCMonth(), standardDate.getUTCFullYear()), standardDate.getUTCDate()) return standardDate.getDate() + _daysUntilNextMonth(standardDate.getUTCMonth(), standardDate.getUTCFullYear()) - standardDate.getUTCDate() - 2 - } - else { - console.log("2", standardDate.getUTCDate(), _daysUntilNextMonth(standardDate.getMonth(), standardDate.getFullYear()), standardDate.getDate()) + } else { + console.log('2', standardDate.getUTCDate(), _daysUntilNextMonth(standardDate.getMonth(), standardDate.getFullYear()), standardDate.getDate()) return standardDate.getUTCDate() + _daysUntilNextMonth(standardDate.getMonth(), standardDate.getFullYear()) - standardDate.getDate() - 2 } } -function _daysUntilNextMonth(month: number, year: number): number { +function _daysUntilNextMonth (month: number, year: number): number { console.log(month) - if(month === 1) { - if (year%400 === 0){ + if (month === 1) { + if (year % 400 === 0) { return 29 - } - else if(year%100 === 0){ + } else if (year % 100 === 0) { return 28 - } - else if(year%4 === 0){ + } else if (year % 4 === 0) { return 29 - } - else{ + } else { return 28 } - } - else if([0, 2, 4, 6, 7, 9, 11].includes(month)) { + } else if ([0, 2, 4, 6, 7, 9, 11].includes(month)) { return 31 - } - else { + } else { return 30 } } diff --git a/packages/neo4j-driver-deno/lib/core/temporal-types.ts b/packages/neo4j-driver-deno/lib/core/temporal-types.ts index bd7fd2359..2461e3d1d 100644 --- a/packages/neo4j-driver-deno/lib/core/temporal-types.ts +++ b/packages/neo4j-driver-deno/lib/core/temporal-types.ts @@ -375,11 +375,7 @@ export class Date { * @returns {StandardDate} Standard JavaScript `Date` at `00:00:00.000` UTC. */ toStandardDate (): StandardDate { - const res = util.isoStringToStandardDate(this.toString()) - if (res.getTimezoneOffset() > 0 && res.getTimezoneOffset() % 60 !== 0) { - res.setMinutes(res.getMinutes() + res.getTimezoneOffset() % 60) - } - return res + return util.isoStringToStandardDate(this.toString()) } /** From 71ff5fb7f329f96c4064c890dcd924308cc16dc5 Mon Sep 17 00:00:00 2001 From: MaxAake <61233757+MaxAake@users.noreply.github.com> Date: Fri, 29 Nov 2024 09:37:00 +0100 Subject: [PATCH 05/14] remove debug logging and small fixes --- packages/core/src/internal/temporal-util.ts | 9 ++------- packages/core/test/temporal-types.test.ts | 14 +++++--------- .../lib/core/internal/temporal-util.ts | 9 ++------- 3 files changed, 9 insertions(+), 23 deletions(-) diff --git a/packages/core/src/internal/temporal-util.ts b/packages/core/src/internal/temporal-util.ts index f30562f91..23c3b4d57 100644 --- a/packages/core/src/internal/temporal-util.ts +++ b/packages/core/src/internal/temporal-util.ts @@ -353,8 +353,6 @@ export function timeZoneOffsetInSeconds (standardDate: Date): number { const minutesPortion = standardDate.getMinutes() - standardDate.getUTCMinutes() const hoursPortion = standardDate.getHours() - standardDate.getUTCHours() const daysPortion = _getDayOffset(standardDate) - console.log('UTCDATE:', standardDate.getUTCDate(), standardDate.getDate()) - console.log(secondsPortion, minutesPortion, hoursPortion, daysPortion) return hoursPortion * SECONDS_PER_HOUR + minutesPortion * SECONDS_PER_MINUTE + secondsPortion + daysPortion * SECONDS_PER_DAY } @@ -362,16 +360,13 @@ function _getDayOffset (standardDate: Date): number { if (standardDate.getMonth() === standardDate.getUTCMonth()) { return standardDate.getDate() - standardDate.getUTCDate() } else if ((standardDate.getFullYear() > standardDate.getUTCFullYear()) || (standardDate.getMonth() > standardDate.getUTCMonth() && standardDate.getFullYear() === standardDate.getUTCFullYear())) { - console.log('1', standardDate.getDate(), _daysUntilNextMonth(standardDate.getUTCMonth(), standardDate.getUTCFullYear()), standardDate.getUTCDate()) - return standardDate.getDate() + _daysUntilNextMonth(standardDate.getUTCMonth(), standardDate.getUTCFullYear()) - standardDate.getUTCDate() - 2 + return standardDate.getDate() + _daysUntilNextMonth(standardDate.getUTCMonth(), standardDate.getUTCFullYear()) - standardDate.getUTCDate() } else { - console.log('2', standardDate.getUTCDate(), _daysUntilNextMonth(standardDate.getMonth(), standardDate.getFullYear()), standardDate.getDate()) - return standardDate.getUTCDate() + _daysUntilNextMonth(standardDate.getMonth(), standardDate.getFullYear()) - standardDate.getDate() - 2 + return standardDate.getDate() - (standardDate.getUTCDate() + _daysUntilNextMonth(standardDate.getMonth(), standardDate.getFullYear())) } } function _daysUntilNextMonth (month: number, year: number): number { - console.log(month) if (month === 1) { if (year % 400 === 0) { return 29 diff --git a/packages/core/test/temporal-types.test.ts b/packages/core/test/temporal-types.test.ts index 3e7c7ba28..339cbb8e9 100644 --- a/packages/core/test/temporal-types.test.ts +++ b/packages/core/test/temporal-types.test.ts @@ -19,7 +19,6 @@ import { StandardDate } from '../src/graph-types' import { LocalDateTime, Date, DateTime, Duration, isDuration, LocalTime, isLocalTime, Time, isTime, isDate, isLocalDateTime, isDateTime } from '../src/temporal-types' import { temporalUtil } from '../src/internal' import fc from 'fast-check' -import { timeZoneOffsetInSeconds } from '../src/internal/temporal-util' const MIN_UTC_IN_MS = -8_640_000_000_000_000 const MAX_UTC_IN_MS = 8_640_000_000_000_000 @@ -48,14 +47,11 @@ describe('Date', () => { const date = Date.fromStandardDate(standardDate) const receivedDate = date.toStandardDate() - const adjustedDateTime = temporalUtil.newDate(standardDate) - adjustedDateTime.setHours(0, 0, timeZoneOffsetInSeconds(standardDate)) - - expect(receivedDate.getFullYear()).toEqual(adjustedDateTime.getFullYear()) - expect(receivedDate.getMonth()).toEqual(adjustedDateTime.getMonth()) - expect(receivedDate.getDate()).toEqual(adjustedDateTime.getDate()) - expect(receivedDate.getHours()).toEqual(adjustedDateTime.getHours()) - expect(receivedDate.getMinutes()).toEqual(adjustedDateTime.getMinutes()) + expect(receivedDate.getUTCFullYear()).toEqual(standardDate.getFullYear()) + expect(receivedDate.getUTCMonth()).toEqual(standardDate.getMonth()) + expect(receivedDate.getUTCDate()).toEqual(standardDate.getDate()) + expect(receivedDate.getUTCHours()).toEqual(0) + expect(receivedDate.getUTCMinutes()).toEqual(0) }) ) }) diff --git a/packages/neo4j-driver-deno/lib/core/internal/temporal-util.ts b/packages/neo4j-driver-deno/lib/core/internal/temporal-util.ts index 48ea7b465..4d072f0e7 100644 --- a/packages/neo4j-driver-deno/lib/core/internal/temporal-util.ts +++ b/packages/neo4j-driver-deno/lib/core/internal/temporal-util.ts @@ -353,8 +353,6 @@ export function timeZoneOffsetInSeconds (standardDate: Date): number { const minutesPortion = standardDate.getMinutes() - standardDate.getUTCMinutes() const hoursPortion = standardDate.getHours() - standardDate.getUTCHours() const daysPortion = _getDayOffset(standardDate) - console.log('UTCDATE:', standardDate.getUTCDate(), standardDate.getDate()) - console.log(secondsPortion, minutesPortion, hoursPortion, daysPortion) return hoursPortion * SECONDS_PER_HOUR + minutesPortion * SECONDS_PER_MINUTE + secondsPortion + daysPortion * SECONDS_PER_DAY } @@ -362,16 +360,13 @@ function _getDayOffset (standardDate: Date): number { if (standardDate.getMonth() === standardDate.getUTCMonth()) { return standardDate.getDate() - standardDate.getUTCDate() } else if ((standardDate.getFullYear() > standardDate.getUTCFullYear()) || (standardDate.getMonth() > standardDate.getUTCMonth() && standardDate.getFullYear() === standardDate.getUTCFullYear())) { - console.log('1', standardDate.getDate(), _daysUntilNextMonth(standardDate.getUTCMonth(), standardDate.getUTCFullYear()), standardDate.getUTCDate()) - return standardDate.getDate() + _daysUntilNextMonth(standardDate.getUTCMonth(), standardDate.getUTCFullYear()) - standardDate.getUTCDate() - 2 + return standardDate.getDate() + _daysUntilNextMonth(standardDate.getUTCMonth(), standardDate.getUTCFullYear()) - standardDate.getUTCDate() } else { - console.log('2', standardDate.getUTCDate(), _daysUntilNextMonth(standardDate.getMonth(), standardDate.getFullYear()), standardDate.getDate()) - return standardDate.getUTCDate() + _daysUntilNextMonth(standardDate.getMonth(), standardDate.getFullYear()) - standardDate.getDate() - 2 + return standardDate.getDate() - (standardDate.getUTCDate() + _daysUntilNextMonth(standardDate.getMonth(), standardDate.getFullYear())) } } function _daysUntilNextMonth (month: number, year: number): number { - console.log(month) if (month === 1) { if (year % 400 === 0) { return 29 From dcbeaac6b720fc328339b72af190dfe9bdf8e433 Mon Sep 17 00:00:00 2001 From: MaxAake <61233757+MaxAake@users.noreply.github.com> Date: Fri, 29 Nov 2024 15:35:22 +0100 Subject: [PATCH 06/14] remove broken mocked date and tests that test nothing --- packages/bolt-connection/test/test-utils.js | 7 --- .../test/internal/temporal-util.test.js | 22 ------- .../neo4j-driver/test/internal/test-utils.js | 7 --- .../neo4j-driver/test/temporal-types.test.js | 57 ------------------- 4 files changed, 93 deletions(-) diff --git a/packages/bolt-connection/test/test-utils.js b/packages/bolt-connection/test/test-utils.js index 9fd6c03a8..c0d225199 100644 --- a/packages/bolt-connection/test/test-utils.js +++ b/packages/bolt-connection/test/test-utils.js @@ -31,12 +31,6 @@ function isServer () { return !isClient() } -function fakeStandardDateWithOffset (offsetMinutes) { - const date = new Date() - date.getTimezoneOffset = () => offsetMinutes - return date -} - const matchers = { toBeElementOf: function (actual, expected) { if (expected === undefined) { @@ -161,7 +155,6 @@ function arbitraryTimeZoneId () { export default { isClient, isServer, - fakeStandardDateWithOffset, matchers, MessageRecordingConnection, spyProtocolWrite, diff --git a/packages/neo4j-driver/test/internal/temporal-util.test.js b/packages/neo4j-driver/test/internal/temporal-util.test.js index 7e768eb4a..6bf8427af 100644 --- a/packages/neo4j-driver/test/internal/temporal-util.test.js +++ b/packages/neo4j-driver/test/internal/temporal-util.test.js @@ -16,7 +16,6 @@ */ import { int, internal } from 'neo4j-driver-core' -import testUtils from './test-utils' const { temporalUtil: util } = internal @@ -261,27 +260,6 @@ describe('#unit temporal-util', () => { ).toEqual(BigInt(999000111)) }) - it('should get timezone offset in seconds from standard date', () => { - expect( - util.timeZoneOffsetInSeconds(testUtils.fakeStandardDateWithOffset(0)) - ).toBe(0) - expect( - util.timeZoneOffsetInSeconds(testUtils.fakeStandardDateWithOffset(2)) - ).toBe(-120) - expect( - util.timeZoneOffsetInSeconds(testUtils.fakeStandardDateWithOffset(10)) - ).toBe(-600) - expect( - util.timeZoneOffsetInSeconds(testUtils.fakeStandardDateWithOffset(101)) - ).toBe(-6060) - expect( - util.timeZoneOffsetInSeconds(testUtils.fakeStandardDateWithOffset(-180)) - ).toBe(10800) - expect( - util.timeZoneOffsetInSeconds(testUtils.fakeStandardDateWithOffset(-600)) - ).toBe(36000) - }) - it('should verify year', () => { expect(util.assertValidYear(-1)).toEqual(-1) expect(util.assertValidYear(-2010)).toEqual(-2010) diff --git a/packages/neo4j-driver/test/internal/test-utils.js b/packages/neo4j-driver/test/internal/test-utils.js index a244c48e0..689ecddd7 100644 --- a/packages/neo4j-driver/test/internal/test-utils.js +++ b/packages/neo4j-driver/test/internal/test-utils.js @@ -24,12 +24,6 @@ function isServer () { return !isClient() } -function fakeStandardDateWithOffset (offsetMinutes) { - const date = new Date() - date.getTimezoneOffset = () => offsetMinutes - return date -} - const matchers = { toBeElementOf: function (util, customEqualityTesters) { return { @@ -138,7 +132,6 @@ function spyProtocolWrite (protocol, callRealMethod = false) { export default { isClient, isServer, - fakeStandardDateWithOffset, matchers, MessageRecordingConnection, spyProtocolWrite diff --git a/packages/neo4j-driver/test/temporal-types.test.js b/packages/neo4j-driver/test/temporal-types.test.js index 67adc9fa0..3007397ea 100644 --- a/packages/neo4j-driver/test/temporal-types.test.js +++ b/packages/neo4j-driver/test/temporal-types.test.js @@ -18,7 +18,6 @@ import neo4j from '../src' import sharedNeo4j from './internal/shared-neo4j' import { toNumber, internal } from 'neo4j-driver-core' -import testUtils from './internal/test-utils' const { temporalUtil: { timeZoneOffsetInSeconds, totalNanoseconds } @@ -1350,50 +1349,6 @@ describe('#integration temporal-types', () => { ).toThrow() }, 90000) - it('should convert standard Date with offset to neo4j Time', () => { - const standardDate1 = testUtils.fakeStandardDateWithOffset(0) - const neo4jTime1 = neo4j.types.Time.fromStandardDate(standardDate1) - verifyTimeZoneOffset(neo4jTime1, 0, 'Z') - - const standardDate2 = testUtils.fakeStandardDateWithOffset(-600) - const neo4jTime2 = neo4j.types.Time.fromStandardDate(standardDate2) - verifyTimeZoneOffset(neo4jTime2, 600 * 60, '+10:00') - - const standardDate3 = testUtils.fakeStandardDateWithOffset(480) - const neo4jTime3 = neo4j.types.Time.fromStandardDate(standardDate3) - verifyTimeZoneOffset(neo4jTime3, -1 * 480 * 60, '-08:00') - - const standardDate4 = testUtils.fakeStandardDateWithOffset(-180) - const neo4jTime4 = neo4j.types.Time.fromStandardDate(standardDate4) - verifyTimeZoneOffset(neo4jTime4, 180 * 60, '+03:00') - - const standardDate5 = testUtils.fakeStandardDateWithOffset(150) - const neo4jTime5 = neo4j.types.Time.fromStandardDate(standardDate5) - verifyTimeZoneOffset(neo4jTime5, -1 * 150 * 60, '-02:30') - }, 90000) - - it('should convert standard Date with offset to neo4j DateTime', () => { - const standardDate1 = testUtils.fakeStandardDateWithOffset(0) - const neo4jDateTime1 = neo4j.types.DateTime.fromStandardDate(standardDate1) - verifyTimeZoneOffset(neo4jDateTime1, 0, 'Z') - - const standardDate2 = testUtils.fakeStandardDateWithOffset(-600) - const neo4jDateTime2 = neo4j.types.DateTime.fromStandardDate(standardDate2) - verifyTimeZoneOffset(neo4jDateTime2, 600 * 60, '+10:00') - - const standardDate3 = testUtils.fakeStandardDateWithOffset(480) - const neo4jDateTime3 = neo4j.types.DateTime.fromStandardDate(standardDate3) - verifyTimeZoneOffset(neo4jDateTime3, -1 * 480 * 60, '-08:00') - - const standardDate4 = testUtils.fakeStandardDateWithOffset(-180) - const neo4jDateTime4 = neo4j.types.DateTime.fromStandardDate(standardDate4) - verifyTimeZoneOffset(neo4jDateTime4, 180 * 60, '+03:00') - - const standardDate5 = testUtils.fakeStandardDateWithOffset(150) - const neo4jDateTime5 = neo4j.types.DateTime.fromStandardDate(standardDate5) - verifyTimeZoneOffset(neo4jDateTime5, -1 * 150 * 60, '-02:30') - }, 90000) - it('should not create DateTime with invalid ZoneId', () => { expect(() => dateTimeWithZoneId(1999, 10, 1, 10, 15, 0, 0, 'Europe/Neo4j')).toThrowError( 'Time zone ID is expected to be a valid ZoneId but was: "Europe/Neo4j"' @@ -1803,16 +1758,4 @@ describe('#integration temporal-types', () => { ) expect(converted).toEqual(expected) } - - function verifyTimeZoneOffset (temporal, expectedValue, expectedStringValue) { - expect(temporal.timeZoneOffsetSeconds).toEqual(expectedValue) - const isoString = temporal.toString() - // assert ISO string ends with the expected suffix - expect( - isoString.indexOf( - expectedStringValue, - isoString.length - expectedStringValue.length - ) - ).toBeGreaterThan(0) - } }) From 695101e697644b709f7fb462a679749ef50c5c39 Mon Sep 17 00:00:00 2001 From: MaxAake <61233757+MaxAake@users.noreply.github.com> Date: Wed, 4 Dec 2024 13:51:22 +0100 Subject: [PATCH 07/14] add note to Date functions --- packages/core/src/temporal-types.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/packages/core/src/temporal-types.ts b/packages/core/src/temporal-types.ts index a9837d2d0..d6e666c02 100644 --- a/packages/core/src/temporal-types.ts +++ b/packages/core/src/temporal-types.ts @@ -353,6 +353,9 @@ export class Date { /** * Create a {@link Date} object from the given standard JavaScript `Date`. * Hour, minute, second, millisecond and time zone offset components of the given date are ignored. + * + * NOTE: the function {@link toStandardDate} and {@link fromStandardDate} are not inverses of one another. {@link fromStandardDate} takes the Day, Month and Year in local time from the supplies JavaScript Date object, while {@link toStandardDate} creates a new JavaScript Date object at midnight UTC. + * * @param {global.Date} standardDate - The standard JavaScript date to convert. * @return {Date} New Date. */ @@ -372,6 +375,8 @@ export class Date { * The time component of the returned `Date` is set to midnight * and the time zone is set to UTC. * + * NOTE: the function {@link toStandardDate} and {@link fromStandardDate} are not inverses of one another. {@link fromStandardDate} takes the Day, Month and Year in local time from the supplies JavaScript Date object, while {@link toStandardDate} creates a new JavaScript Date object at midnight UTC. + * * @returns {StandardDate} Standard JavaScript `Date` at `00:00:00.000` UTC. */ toStandardDate (): StandardDate { From 1885ca24746adbffd1ead51087e4b9802d3938d1 Mon Sep 17 00:00:00 2001 From: MaxAake <61233757+MaxAake@users.noreply.github.com> Date: Wed, 4 Dec 2024 14:40:02 +0100 Subject: [PATCH 08/14] Update temporal-types.ts --- packages/core/src/temporal-types.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/core/src/temporal-types.ts b/packages/core/src/temporal-types.ts index d6e666c02..521ba7668 100644 --- a/packages/core/src/temporal-types.ts +++ b/packages/core/src/temporal-types.ts @@ -355,6 +355,7 @@ export class Date { * Hour, minute, second, millisecond and time zone offset components of the given date are ignored. * * NOTE: the function {@link toStandardDate} and {@link fromStandardDate} are not inverses of one another. {@link fromStandardDate} takes the Day, Month and Year in local time from the supplies JavaScript Date object, while {@link toStandardDate} creates a new JavaScript Date object at midnight UTC. + * If your timezone has a negative offset from UTC, creating a JavaScript Date at midnight UTC and converting it with {@link fromStandardDate} will result in a Date for the day before. * * @param {global.Date} standardDate - The standard JavaScript date to convert. * @return {Date} New Date. From df151a672ba86ec229fb80b34d19c6822aceddad Mon Sep 17 00:00:00 2001 From: MaxAake <61233757+MaxAake@users.noreply.github.com> Date: Wed, 4 Dec 2024 14:59:00 +0100 Subject: [PATCH 09/14] deno --- packages/neo4j-driver-deno/lib/core/temporal-types.ts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/packages/neo4j-driver-deno/lib/core/temporal-types.ts b/packages/neo4j-driver-deno/lib/core/temporal-types.ts index 2461e3d1d..d9b377e71 100644 --- a/packages/neo4j-driver-deno/lib/core/temporal-types.ts +++ b/packages/neo4j-driver-deno/lib/core/temporal-types.ts @@ -353,6 +353,10 @@ export class Date { /** * Create a {@link Date} object from the given standard JavaScript `Date`. * Hour, minute, second, millisecond and time zone offset components of the given date are ignored. + * + * NOTE: the function {@link toStandardDate} and {@link fromStandardDate} are not inverses of one another. {@link fromStandardDate} takes the Day, Month and Year in local time from the supplies JavaScript Date object, while {@link toStandardDate} creates a new JavaScript Date object at midnight UTC. + * If your timezone has a negative offset from UTC, creating a JavaScript Date at midnight UTC and converting it with {@link fromStandardDate} will result in a Date for the day before. + * * @param {global.Date} standardDate - The standard JavaScript date to convert. * @return {Date} New Date. */ @@ -372,6 +376,8 @@ export class Date { * The time component of the returned `Date` is set to midnight * and the time zone is set to UTC. * + * NOTE: the function {@link toStandardDate} and {@link fromStandardDate} are not inverses of one another. {@link fromStandardDate} takes the Day, Month and Year in local time from the supplies JavaScript Date object, while {@link toStandardDate} creates a new JavaScript Date object at midnight UTC. + * * @returns {StandardDate} Standard JavaScript `Date` at `00:00:00.000` UTC. */ toStandardDate (): StandardDate { From 9295f8cb43e1d3a467a2c684ab5877ec05bb71b5 Mon Sep 17 00:00:00 2001 From: MaxAake <61233757+MaxAake@users.noreply.github.com> Date: Thu, 5 Dec 2024 19:12:12 +0545 Subject: [PATCH 10/14] DateTime tests fixed to check UTC values Tests using UTC values are far more reliable, as we otherwise need to take the runtime conversion of utc time to local time into consideration. The UTC value is what is actually stored in the JS date object. --- packages/core/test/temporal-types.test.ts | 51 ++++++++--------------- 1 file changed, 18 insertions(+), 33 deletions(-) diff --git a/packages/core/test/temporal-types.test.ts b/packages/core/test/temporal-types.test.ts index 339cbb8e9..d7281d87b 100644 --- a/packages/core/test/temporal-types.test.ts +++ b/packages/core/test/temporal-types.test.ts @@ -15,7 +15,6 @@ * limitations under the License. */ -import { StandardDate } from '../src/graph-types' import { LocalDateTime, Date, DateTime, Duration, isDuration, LocalTime, isLocalTime, Time, isTime, isDate, isLocalDateTime, isDateTime } from '../src/temporal-types' import { temporalUtil } from '../src/internal' import fc from 'fast-check' @@ -110,17 +109,16 @@ describe('DateTime', () => { const standardDate = datetime.toStandardDate() - expect(standardDate.getFullYear()).toEqual(datetime.year) - expect(standardDate.getMonth()).toEqual(datetime.month - 1) - expect(standardDate.getDate()).toEqual(datetime.day) - const offsetInMinutes = offset(standardDate) - const offsetAdjust = offsetInMinutes - (datetime.timeZoneOffsetSeconds ?? 0) / 60 - const hourDiff = Math.abs(offsetAdjust / 60) + expect(standardDate.getUTCFullYear()).toEqual(datetime.year) + expect(standardDate.getUTCMonth()).toEqual(datetime.month - 1) + expect(standardDate.getUTCDate()).toEqual(datetime.day) + const offsetAdjust = (datetime.timeZoneOffsetSeconds ?? 0) / 60 + const hourDiff = Math.abs((offsetAdjust - offsetAdjust % 60) / 60) const minuteDiff = Math.abs(offsetAdjust % 60) - expect(standardDate.getHours()).toBe(datetime.hour - hourDiff) - expect(standardDate.getMinutes()).toBe(datetime.minute - minuteDiff) - expect(standardDate.getSeconds()).toBe(datetime.second) - expect(standardDate.getMilliseconds()).toBe(Math.round(datetime.nanosecond / 1000000)) + expect(standardDate.getUTCHours()).toBe(datetime.hour - hourDiff) + expect(standardDate.getUTCMinutes()).toBe(datetime.minute - minuteDiff) + expect(standardDate.getUTCSeconds()).toBe(datetime.second) + expect(standardDate.getUTCMilliseconds()).toBe(Math.round(datetime.nanosecond / 1000000)) }) it('should convert to a standard date (offset)', () => { @@ -128,17 +126,16 @@ describe('DateTime', () => { const standardDate = datetime.toStandardDate() - expect(standardDate.getFullYear()).toEqual(datetime.year) - expect(standardDate.getMonth()).toEqual(datetime.month - 1) - expect(standardDate.getDate()).toEqual(datetime.day) - const offsetInMinutes = offset(standardDate) - const offsetAdjust = offsetInMinutes - (datetime.timeZoneOffsetSeconds ?? 0) / 60 - const hourDiff = Math.abs(offsetAdjust / 60) + expect(standardDate.getUTCFullYear()).toEqual(datetime.year) + expect(standardDate.getUTCMonth()).toEqual(datetime.month - 1) + expect(standardDate.getUTCDate()).toEqual(datetime.day) + const offsetAdjust = (datetime.timeZoneOffsetSeconds ?? 0) / 60 + const hourDiff = Math.abs((offsetAdjust - offsetAdjust % 60) / 60) const minuteDiff = Math.abs(offsetAdjust % 60) - expect(standardDate.getHours()).toBe(datetime.hour - hourDiff) - expect(standardDate.getMinutes()).toBe(datetime.minute - minuteDiff) - expect(standardDate.getSeconds()).toBe(datetime.second) - expect(standardDate.getMilliseconds()).toBe(Math.round(datetime.nanosecond / 1000000)) + expect(standardDate.getUTCHours()).toBe(datetime.hour - hourDiff) + expect(standardDate.getUTCMinutes()).toBe(datetime.minute - minuteDiff) + expect(standardDate.getUTCSeconds()).toBe(datetime.second) + expect(standardDate.getUTCMilliseconds()).toBe(Math.round(datetime.nanosecond / 1000000)) }) it('should not convert to a standard date (zoneid)', () => { @@ -285,15 +282,3 @@ describe('isDateTime', () => { } }) }) - -/** - * The offset in StandardDate is the number of minutes - * to sum to the date and time to get the UTC time. - * - * This function change the sign of the offset, - * this way using the most common meaning. - * The time to add to UTC to get the local time. - */ -function offset (date: StandardDate): number { - return date.getTimezoneOffset() * -1 -} From b60fafd0d9d292606d4fbf4e548809547335af58 Mon Sep 17 00:00:00 2001 From: MaxAake <61233757+MaxAake@users.noreply.github.com> Date: Thu, 5 Dec 2024 15:25:26 +0100 Subject: [PATCH 11/14] simplify leap logic --- packages/core/src/internal/temporal-util.ts | 6 +----- .../neo4j-driver-deno/lib/core/internal/temporal-util.ts | 9 +++------ 2 files changed, 4 insertions(+), 11 deletions(-) diff --git a/packages/core/src/internal/temporal-util.ts b/packages/core/src/internal/temporal-util.ts index 23c3b4d57..b75da7d4a 100644 --- a/packages/core/src/internal/temporal-util.ts +++ b/packages/core/src/internal/temporal-util.ts @@ -368,11 +368,7 @@ function _getDayOffset (standardDate: Date): number { function _daysUntilNextMonth (month: number, year: number): number { if (month === 1) { - if (year % 400 === 0) { - return 29 - } else if (year % 100 === 0) { - return 28 - } else if (year % 4 === 0) { + if (year % 400 === 0 || (year % 4 === 0 && year % 100 !== 0)) { return 29 } else { return 28 diff --git a/packages/neo4j-driver-deno/lib/core/internal/temporal-util.ts b/packages/neo4j-driver-deno/lib/core/internal/temporal-util.ts index 4d072f0e7..dc2252de6 100644 --- a/packages/neo4j-driver-deno/lib/core/internal/temporal-util.ts +++ b/packages/neo4j-driver-deno/lib/core/internal/temporal-util.ts @@ -368,13 +368,10 @@ function _getDayOffset (standardDate: Date): number { function _daysUntilNextMonth (month: number, year: number): number { if (month === 1) { - if (year % 400 === 0) { + if (year % 400 === 0|| (year % 4 === 0 && year % 100 !== 0)) { return 29 - } else if (year % 100 === 0) { - return 28 - } else if (year % 4 === 0) { - return 29 - } else { + } + else { return 28 } } else if ([0, 2, 4, 6, 7, 9, 11].includes(month)) { From b904982687b9e02f35317cf74ee52e3b5db40e93 Mon Sep 17 00:00:00 2001 From: MaxAake <61233757+MaxAake@users.noreply.github.com> Date: Mon, 9 Dec 2024 08:08:52 +0100 Subject: [PATCH 12/14] deno --- .../neo4j-driver-deno/lib/core/internal/temporal-util.ts | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/packages/neo4j-driver-deno/lib/core/internal/temporal-util.ts b/packages/neo4j-driver-deno/lib/core/internal/temporal-util.ts index dc2252de6..261b5c11f 100644 --- a/packages/neo4j-driver-deno/lib/core/internal/temporal-util.ts +++ b/packages/neo4j-driver-deno/lib/core/internal/temporal-util.ts @@ -368,10 +368,9 @@ function _getDayOffset (standardDate: Date): number { function _daysUntilNextMonth (month: number, year: number): number { if (month === 1) { - if (year % 400 === 0|| (year % 4 === 0 && year % 100 !== 0)) { + if (year % 400 === 0 || (year % 4 === 0 && year % 100 !== 0)) { return 29 - } - else { + } else { return 28 } } else if ([0, 2, 4, 6, 7, 9, 11].includes(month)) { From d74edd584f03b6654fe283a5bae68ee0c08cad5f Mon Sep 17 00:00:00 2001 From: MaxAake <61233757+MaxAake@users.noreply.github.com> Date: Tue, 10 Dec 2024 09:53:47 +0100 Subject: [PATCH 13/14] Improved documentation --- packages/core/src/internal/temporal-util.ts | 21 ++++++++++++----- packages/core/src/temporal-types.ts | 4 ++-- packages/core/test/temporal-types.test.ts | 4 ++-- .../lib/core/internal/temporal-util.ts | 23 ++++++++++++++----- .../lib/core/temporal-types.ts | 4 ++-- 5 files changed, 38 insertions(+), 18 deletions(-) diff --git a/packages/core/src/internal/temporal-util.ts b/packages/core/src/internal/temporal-util.ts index b75da7d4a..ece38c424 100644 --- a/packages/core/src/internal/temporal-util.ts +++ b/packages/core/src/internal/temporal-util.ts @@ -339,12 +339,6 @@ export function totalNanoseconds ( /** * Get the time zone offset in seconds from the given standard JavaScript date. * - * Implementation note: - * Time zone offset returned by the standard JavaScript date is the difference, in minutes, from local time to UTC. - * So positive value means offset is behind UTC and negative value means it is ahead. - * For Neo4j temporal types, like `Time` or `DateTime` offset is in seconds and represents difference from UTC to local time. - * This is different from standard JavaScript dates and that's why implementation negates the returned value. - * * @param {global.Date} standardDate the standard JavaScript date. * @return {number} the time zone offset in seconds. */ @@ -356,6 +350,13 @@ export function timeZoneOffsetInSeconds (standardDate: Date): number { return hoursPortion * SECONDS_PER_HOUR + minutesPortion * SECONDS_PER_MINUTE + secondsPortion + daysPortion * SECONDS_PER_DAY } +/** + * Get the difference in days from the given JavaScript date in local time and UTC. + * + * @private + * @param {global.Date} standardDate the date to evaluate + * @returns {number} the difference in days between date local time and UTC + */ function _getDayOffset (standardDate: Date): number { if (standardDate.getMonth() === standardDate.getUTCMonth()) { return standardDate.getDate() - standardDate.getUTCDate() @@ -366,6 +367,14 @@ function _getDayOffset (standardDate: Date): number { } } +/** + * Get the number of days in a month, including a check for leap years. + * + * @private + * @param {number} month the month of the date to evalutate + * @param {number} year the month of the date to evalutate + * @returns {number} the total number of days in the month evaluated + */ function _daysUntilNextMonth (month: number, year: number): number { if (month === 1) { if (year % 400 === 0 || (year % 4 === 0 && year % 100 !== 0)) { diff --git a/packages/core/src/temporal-types.ts b/packages/core/src/temporal-types.ts index 521ba7668..7ea533506 100644 --- a/packages/core/src/temporal-types.ts +++ b/packages/core/src/temporal-types.ts @@ -354,7 +354,7 @@ export class Date { * Create a {@link Date} object from the given standard JavaScript `Date`. * Hour, minute, second, millisecond and time zone offset components of the given date are ignored. * - * NOTE: the function {@link toStandardDate} and {@link fromStandardDate} are not inverses of one another. {@link fromStandardDate} takes the Day, Month and Year in local time from the supplies JavaScript Date object, while {@link toStandardDate} creates a new JavaScript Date object at midnight UTC. + * NOTE: the function {@link toStandardDate} and {@link fromStandardDate} are not inverses of one another. {@link fromStandardDate} takes the Day, Month and Year in local time from the supplies JavaScript Date object, while {@link toStandardDate} creates a new JavaScript Date object at midnight UTC. This incongruity will be rectified in 6.0 * If your timezone has a negative offset from UTC, creating a JavaScript Date at midnight UTC and converting it with {@link fromStandardDate} will result in a Date for the day before. * * @param {global.Date} standardDate - The standard JavaScript date to convert. @@ -376,7 +376,7 @@ export class Date { * The time component of the returned `Date` is set to midnight * and the time zone is set to UTC. * - * NOTE: the function {@link toStandardDate} and {@link fromStandardDate} are not inverses of one another. {@link fromStandardDate} takes the Day, Month and Year in local time from the supplies JavaScript Date object, while {@link toStandardDate} creates a new JavaScript Date object at midnight UTC. + * NOTE: the function {@link toStandardDate} and {@link fromStandardDate} are not inverses of one another. {@link fromStandardDate} takes the Day, Month and Year in local time from the supplies JavaScript Date object, while {@link toStandardDate} creates a new JavaScript Date object at midnight UTC. This incongruity will be rectified in 6.0 * * @returns {StandardDate} Standard JavaScript `Date` at `00:00:00.000` UTC. */ diff --git a/packages/core/test/temporal-types.test.ts b/packages/core/test/temporal-types.test.ts index d7281d87b..4341be584 100644 --- a/packages/core/test/temporal-types.test.ts +++ b/packages/core/test/temporal-types.test.ts @@ -46,7 +46,7 @@ describe('Date', () => { const date = Date.fromStandardDate(standardDate) const receivedDate = date.toStandardDate() - expect(receivedDate.getUTCFullYear()).toEqual(standardDate.getFullYear()) + expect(receivedDate.getUTCFullYear()).toEqual(standardDate.getFullYear()) // Date converts from local time but to UTC expect(receivedDate.getUTCMonth()).toEqual(standardDate.getMonth()) expect(receivedDate.getUTCDate()).toEqual(standardDate.getDate()) expect(receivedDate.getUTCHours()).toEqual(0) @@ -111,7 +111,7 @@ describe('DateTime', () => { expect(standardDate.getUTCFullYear()).toEqual(datetime.year) expect(standardDate.getUTCMonth()).toEqual(datetime.month - 1) - expect(standardDate.getUTCDate()).toEqual(datetime.day) + expect(standardDate.getUTCDate()).toEqual(datetime.day) // The datetime in this test will never cross the date line in conversion, it is therefore safe to use UTC here to avoid machine timezone from altering the result of the test. const offsetAdjust = (datetime.timeZoneOffsetSeconds ?? 0) / 60 const hourDiff = Math.abs((offsetAdjust - offsetAdjust % 60) / 60) const minuteDiff = Math.abs(offsetAdjust % 60) diff --git a/packages/neo4j-driver-deno/lib/core/internal/temporal-util.ts b/packages/neo4j-driver-deno/lib/core/internal/temporal-util.ts index 261b5c11f..af5a1e675 100644 --- a/packages/neo4j-driver-deno/lib/core/internal/temporal-util.ts +++ b/packages/neo4j-driver-deno/lib/core/internal/temporal-util.ts @@ -339,12 +339,6 @@ export function totalNanoseconds ( /** * Get the time zone offset in seconds from the given standard JavaScript date. * - * Implementation note: - * Time zone offset returned by the standard JavaScript date is the difference, in minutes, from local time to UTC. - * So positive value means offset is behind UTC and negative value means it is ahead. - * For Neo4j temporal types, like `Time` or `DateTime` offset is in seconds and represents difference from UTC to local time. - * This is different from standard JavaScript dates and that's why implementation negates the returned value. - * * @param {global.Date} standardDate the standard JavaScript date. * @return {number} the time zone offset in seconds. */ @@ -356,6 +350,14 @@ export function timeZoneOffsetInSeconds (standardDate: Date): number { return hoursPortion * SECONDS_PER_HOUR + minutesPortion * SECONDS_PER_MINUTE + secondsPortion + daysPortion * SECONDS_PER_DAY } + +/** + * Get the difference in days from the given JavaScript date in local time and UTC. + * + * @private + * @param {global.Date} standardDate the date to evaluate + * @returns {number} the difference in days between date local time and UTC + */ function _getDayOffset (standardDate: Date): number { if (standardDate.getMonth() === standardDate.getUTCMonth()) { return standardDate.getDate() - standardDate.getUTCDate() @@ -366,6 +368,15 @@ function _getDayOffset (standardDate: Date): number { } } + +/** + * Get the number of days in a month, including a check for leap years. + * + * @private + * @param {number} month the month of the date to evalutate + * @param {number} year the month of the date to evalutate + * @returns {number} the total number of days in the month evaluated + */ function _daysUntilNextMonth (month: number, year: number): number { if (month === 1) { if (year % 400 === 0 || (year % 4 === 0 && year % 100 !== 0)) { diff --git a/packages/neo4j-driver-deno/lib/core/temporal-types.ts b/packages/neo4j-driver-deno/lib/core/temporal-types.ts index d9b377e71..fbc48dd35 100644 --- a/packages/neo4j-driver-deno/lib/core/temporal-types.ts +++ b/packages/neo4j-driver-deno/lib/core/temporal-types.ts @@ -354,7 +354,7 @@ export class Date { * Create a {@link Date} object from the given standard JavaScript `Date`. * Hour, minute, second, millisecond and time zone offset components of the given date are ignored. * - * NOTE: the function {@link toStandardDate} and {@link fromStandardDate} are not inverses of one another. {@link fromStandardDate} takes the Day, Month and Year in local time from the supplies JavaScript Date object, while {@link toStandardDate} creates a new JavaScript Date object at midnight UTC. + * NOTE: the function {@link toStandardDate} and {@link fromStandardDate} are not inverses of one another. {@link fromStandardDate} takes the Day, Month and Year in local time from the supplies JavaScript Date object, while {@link toStandardDate} creates a new JavaScript Date object at midnight UTC. This incongruity will be rectified in 6.0 * If your timezone has a negative offset from UTC, creating a JavaScript Date at midnight UTC and converting it with {@link fromStandardDate} will result in a Date for the day before. * * @param {global.Date} standardDate - The standard JavaScript date to convert. @@ -376,7 +376,7 @@ export class Date { * The time component of the returned `Date` is set to midnight * and the time zone is set to UTC. * - * NOTE: the function {@link toStandardDate} and {@link fromStandardDate} are not inverses of one another. {@link fromStandardDate} takes the Day, Month and Year in local time from the supplies JavaScript Date object, while {@link toStandardDate} creates a new JavaScript Date object at midnight UTC. + * NOTE: the function {@link toStandardDate} and {@link fromStandardDate} are not inverses of one another. {@link fromStandardDate} takes the Day, Month and Year in local time from the supplies JavaScript Date object, while {@link toStandardDate} creates a new JavaScript Date object at midnight UTC. This incongruity will be rectified in 6.0 * * @returns {StandardDate} Standard JavaScript `Date` at `00:00:00.000` UTC. */ From 07b3304abf7dc4fd41a888c493d19c0d32cf6d9d Mon Sep 17 00:00:00 2001 From: MaxAake <61233757+MaxAake@users.noreply.github.com> Date: Tue, 10 Dec 2024 09:54:14 +0100 Subject: [PATCH 14/14] deno --- .../neo4j-driver-deno/lib/core/internal/temporal-util.ts | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/packages/neo4j-driver-deno/lib/core/internal/temporal-util.ts b/packages/neo4j-driver-deno/lib/core/internal/temporal-util.ts index af5a1e675..52e4d2655 100644 --- a/packages/neo4j-driver-deno/lib/core/internal/temporal-util.ts +++ b/packages/neo4j-driver-deno/lib/core/internal/temporal-util.ts @@ -350,10 +350,9 @@ export function timeZoneOffsetInSeconds (standardDate: Date): number { return hoursPortion * SECONDS_PER_HOUR + minutesPortion * SECONDS_PER_MINUTE + secondsPortion + daysPortion * SECONDS_PER_DAY } - /** * Get the difference in days from the given JavaScript date in local time and UTC. - * + * * @private * @param {global.Date} standardDate the date to evaluate * @returns {number} the difference in days between date local time and UTC @@ -368,10 +367,9 @@ function _getDayOffset (standardDate: Date): number { } } - /** * Get the number of days in a month, including a check for leap years. - * + * * @private * @param {number} month the month of the date to evalutate * @param {number} year the month of the date to evalutate