diff --git a/packages/bolt-connection/src/packstream/packstream-utc.js b/packages/bolt-connection/src/packstream/packstream-utc.js index 50fcf6647..ba202ce3d 100644 --- a/packages/bolt-connection/src/packstream/packstream-utc.js +++ b/packages/bolt-connection/src/packstream/packstream-utc.js @@ -266,22 +266,17 @@ export function packDateTime (value, packer) { era: 'narrow' }) - const l = epochSecondAndNanoToLocalDateTime(epochSecond, nano) - const utc = Date.UTC( - int(l.year).toNumber(), - int(l.month).toNumber() - 1, - int(l.day).toNumber(), - int(l.hour).toNumber(), - int(l.minute).toNumber(), - int(l.second).toNumber() - ) + const utc = int(epochSecond) + .multiply(1000) + .add(int(nano).div(1_000_000)) + .toNumber() const formattedUtcParts = formatter.formatToParts(utc) const localDateTime = formattedUtcParts.reduce((obj, currentValue) => { if (currentValue.type === 'era') { obj.adjustEra = - currentValue.value.toLocaleUpperCase() === 'B' + currentValue.value.toUpperCase() === 'B' ? year => year.subtract(1).negate() // 1BC equals to year 0 in astronomical year numbering : year => year } else if (currentValue.type !== 'literal') { diff --git a/packages/bolt-connection/test/packstream/packstream-v2.test.js b/packages/bolt-connection/test/packstream/packstream-v2.test.js index 223f142a6..1bfa5ef35 100644 --- a/packages/bolt-connection/test/packstream/packstream-v2.test.js +++ b/packages/bolt-connection/test/packstream/packstream-v2.test.js @@ -288,6 +288,10 @@ describe('#unit PackStreamV2', () => { [ 'DateWithWithZoneId / Min Date', new DateTime(-99_999, 12, 31, 23, 59, 59, 999_999_999, undefined, 'Pacific/Samoa') + ], + [ + 'DateWithWithZoneId / Ambiguous date between 00 and 99', + new DateTime(50, 12, 31, 23, 59, 59, 999_999_999, undefined, 'Pacific/Samoa') ] ])('should pack and unpack DateTimeWithZoneId and without offset (%s)', (_, object) => { const unpacked = packAndUnpack(object, { disableLosslessIntegers: true, useUtc: true}) diff --git a/packages/neo4j-driver/test/temporal-types.test.js b/packages/neo4j-driver/test/temporal-types.test.js index 2146c72e3..13a18b518 100644 --- a/packages/neo4j-driver/test/temporal-types.test.js +++ b/packages/neo4j-driver/test/temporal-types.test.js @@ -1441,7 +1441,24 @@ describe('#integration temporal-types', () => { expect(records.length).toEqual(1) const value = records[0].get(0) - expect(value).toEqual(expectedValue) + + if ( + expectedValue.timeZoneId != null && + value.timeZoneOffsetSeconds != null && + neo4j.isDateTime(value) && + neo4j.isDateTime(expectedValue)) { + expect(value).toEqual(jasmine.objectContaining({ + year: expectedValue.year, + month: expectedValue.month, + day: expectedValue.day, + hour: expectedValue.hour, + second: expectedValue.second, + nanosecond: expectedValue.nanosecond, + timeZoneId: expectedValue.timeZoneId + })) + } else { + expect(value).toEqual(expectedValue) + } } finally { await session.close() } @@ -1457,7 +1474,25 @@ describe('#integration temporal-types', () => { expect(records.length).toEqual(1) const receivedValue = records[0].get(0) - expect(receivedValue).toEqual(value) + // Amend test to ignore timeZoneOffsetInSeconds returned by the + // new servers in ZonedDateTime with the utc fix + if ( + value.timeZoneId != null && + receivedValue.timeZoneOffsetSeconds != null && + neo4j.isDateTime(value) && + neo4j.isDateTime(receivedValue)) { + expect(receivedValue).toEqual(jasmine.objectContaining({ + year: value.year, + month: value.month, + day: value.day, + hour: value.hour, + second: value.second, + nanosecond: value.nanosecond, + timeZoneId: value.timeZoneId + })) + } else { + expect(receivedValue).toEqual(value) + } } async function testDurationToString (values) {