diff --git a/src/v1/internal/temporal-util.js b/src/v1/internal/temporal-util.js
index ca6a63bfa..291878ae2 100644
--- a/src/v1/internal/temporal-util.js
+++ b/src/v1/internal/temporal-util.js
@@ -17,7 +17,7 @@
* limitations under the License.
*/
-import {int} from '../integer';
+import {int, isInt} from '../integer';
import {Date, LocalDateTime, LocalTime} from '../temporal-types';
/*
@@ -35,6 +35,7 @@ const MINUTES_PER_HOUR = 60;
const SECONDS_PER_MINUTE = 60;
const SECONDS_PER_HOUR = SECONDS_PER_MINUTE * MINUTES_PER_HOUR;
const NANOS_PER_SECOND = 1000000000;
+const NANOS_PER_MILLISECOND = 1000000;
const NANOS_PER_MINUTE = NANOS_PER_SECOND * SECONDS_PER_MINUTE;
const NANOS_PER_HOUR = NANOS_PER_MINUTE * MINUTES_PER_HOUR;
const DAYS_0000_TO_1970 = 719528;
@@ -264,6 +265,27 @@ export function dateToIsoString(year, month, day) {
return `${yearString}-${monthString}-${dayString}`;
}
+/**
+ * Get the total number of nanoseconds from the milliseconds of the given standard JavaScript date and optional nanosecond part.
+ * @param {global.Date} standardDate the standard JavaScript date.
+ * @param {Integer|number|undefined} nanoseconds the optional number of nanoseconds.
+ * @return {Integer|number} the total amount of nanoseconds.
+ */
+export function totalNanoseconds(standardDate, nanoseconds) {
+ nanoseconds = (nanoseconds || 0);
+ const nanosFromMillis = standardDate.getMilliseconds() * NANOS_PER_MILLISECOND;
+ return isInt(nanoseconds) ? nanoseconds.add(nanosFromMillis) : nanoseconds + nanosFromMillis;
+}
+
+/**
+ * Get the time zone offset in seconds from the given standard JavaScript date.
+ * @param {global.Date} standardDate the standard JavaScript date.
+ * @return {number} the time zone offset in seconds.
+ */
+export function timeZoneOffsetInSeconds(standardDate) {
+ return standardDate.getTimezoneOffset() * SECONDS_PER_MINUTE;
+}
+
/**
* Converts given local time into a single integer representing this same time in seconds of the day. Nanoseconds are skipped.
* @param {Integer|number|string} hour the hour of the local time.
diff --git a/src/v1/internal/util.js b/src/v1/internal/util.js
index 437be20be..aa858f87c 100644
--- a/src/v1/internal/util.js
+++ b/src/v1/internal/util.js
@@ -87,6 +87,16 @@ function assertNumberOrInteger(obj, objName) {
return obj;
}
+function assertValidDate(obj, objName) {
+ if (Object.prototype.toString.call(obj) !== '[object Date]') {
+ throw new TypeError(objName + ' expected to be a standard JavaScript Date but was: ' + JSON.stringify(obj));
+ }
+ if (Number.isNaN(obj.getTime())) {
+ throw new TypeError(objName + ' expected to be valid JavaScript Date but its time was NaN: ' + JSON.stringify(obj));
+ }
+ return obj;
+}
+
function assertCypherStatement(obj) {
assertString(obj, 'Cypher statement');
if (obj.trim().length === 0) {
@@ -112,6 +122,7 @@ export {
assertString,
assertNumber,
assertNumberOrInteger,
+ assertValidDate,
validateStatementAndParameters,
ENCRYPTION_ON,
ENCRYPTION_OFF
diff --git a/src/v1/temporal-types.js b/src/v1/temporal-types.js
index 0ca11b7df..7f77deb15 100644
--- a/src/v1/temporal-types.js
+++ b/src/v1/temporal-types.js
@@ -18,7 +18,7 @@
*/
import * as util from './internal/temporal-util';
-import {assertNumberOrInteger, assertString} from './internal/util';
+import {assertNumberOrInteger, assertString, assertValidDate} from './internal/util';
import {newError} from './error';
const IDENTIFIER_PROPERTY_ATTRIBUTES = {
@@ -94,6 +94,23 @@ export class LocalTime {
Object.freeze(this);
}
+ /**
+ * Create a local time object from the given standard JavaScript Date
and optional nanoseconds.
+ * Year, month, day and time zone offset components of the given date are ignored.
+ * @param {global.Date} standardDate the standard JavaScript date to convert.
+ * @param {Integer|number|undefined} nanosecond the optional amount of nanoseconds.
+ * @return {LocalTime} new local time.
+ */
+ static fromStandardDate(standardDate, nanosecond) {
+ verifyStandardDateAndNanos(standardDate, nanosecond);
+
+ return new LocalTime(
+ standardDate.getHours(),
+ standardDate.getMinutes(),
+ standardDate.getSeconds(),
+ util.totalNanoseconds(standardDate, nanosecond));
+ }
+
toString() {
return util.timeToIsoString(this.hour, this.minute, this.second, this.nanosecond);
}
@@ -133,6 +150,24 @@ export class Time {
Object.freeze(this);
}
+ /**
+ * Create a time object from the given standard JavaScript Date
and optional nanoseconds.
+ * Year, month and day components of the given date are ignored.
+ * @param {global.Date} standardDate the standard JavaScript date to convert.
+ * @param {Integer|number|undefined} nanosecond the optional amount of nanoseconds.
+ * @return {Time} new time.
+ */
+ static fromStandardDate(standardDate, nanosecond) {
+ verifyStandardDateAndNanos(standardDate, nanosecond);
+
+ return new Time(
+ standardDate.getHours(),
+ standardDate.getMinutes(),
+ standardDate.getSeconds(),
+ util.totalNanoseconds(standardDate, nanosecond),
+ util.timeZoneOffsetInSeconds(standardDate));
+ }
+
toString() {
return util.timeToIsoString(this.hour, this.minute, this.second, this.nanosecond) + util.timeZoneOffsetToIsoString(this.timeZoneOffsetSeconds);
}
@@ -168,6 +203,21 @@ export class Date {
Object.freeze(this);
}
+ /**
+ * Create a date object from the given standard JavaScript Date
.
+ * Hour, minute, second, millisecond and time zone offset components of the given date are ignored.
+ * @param {global.Date} standardDate the standard JavaScript date to convert.
+ * @return {Date} new date.
+ */
+ static fromStandardDate(standardDate) {
+ verifyStandardDateAndNanos(standardDate, null);
+
+ return new Date(
+ standardDate.getFullYear(),
+ standardDate.getMonth() + 1,
+ standardDate.getDate());
+ }
+
toString() {
return util.dateToIsoString(this.year, this.month, this.day);
}
@@ -211,6 +261,26 @@ export class LocalDateTime {
Object.freeze(this);
}
+ /**
+ * Create a local date-time object from the given standard JavaScript Date
and optional nanoseconds.
+ * Time zone offset component of the given date is ignored.
+ * @param {global.Date} standardDate the standard JavaScript date to convert.
+ * @param {Integer|number|undefined} nanosecond the optional amount of nanoseconds.
+ * @return {LocalDateTime} new local date-time.
+ */
+ static fromStandardDate(standardDate, nanosecond) {
+ verifyStandardDateAndNanos(standardDate, nanosecond);
+
+ return new LocalDateTime(
+ standardDate.getFullYear(),
+ standardDate.getMonth() + 1,
+ standardDate.getDate(),
+ standardDate.getHours(),
+ standardDate.getMinutes(),
+ standardDate.getSeconds(),
+ util.totalNanoseconds(standardDate, nanosecond));
+ }
+
toString() {
return localDateTimeToString(this.year, this.month, this.day, this.hour, this.minute, this.second, this.nanosecond);
}
@@ -261,6 +331,27 @@ export class DateTime {
Object.freeze(this);
}
+ /**
+ * Create a date-time object from the given standard JavaScript Date
and optional nanoseconds.
+ * @param {global.Date} standardDate the standard JavaScript date to convert.
+ * @param {Integer|number|undefined} nanosecond the optional amount of nanoseconds.
+ * @return {DateTime} new date-time.
+ */
+ static fromStandardDate(standardDate, nanosecond) {
+ verifyStandardDateAndNanos(standardDate, nanosecond);
+
+ return new DateTime(
+ standardDate.getFullYear(),
+ standardDate.getMonth() + 1,
+ standardDate.getDate(),
+ standardDate.getHours(),
+ standardDate.getMinutes(),
+ standardDate.getSeconds(),
+ util.totalNanoseconds(standardDate, nanosecond),
+ util.timeZoneOffsetInSeconds(standardDate),
+ null /* no time zone id */);
+ }
+
toString() {
const localDateTimeStr = localDateTimeToString(this.year, this.month, this.day, this.hour, this.minute, this.second, this.nanosecond);
const timeZoneStr = this.timeZoneId ? `[${this.timeZoneId}]` : util.timeZoneOffsetToIsoString(this.timeZoneOffsetSeconds);
@@ -303,3 +394,10 @@ function verifyTimeZoneArguments(timeZoneOffsetSeconds, timeZoneId) {
throw newError(`Unable to create DateTime without either time zone offset or id. Please specify either of them. Given offset: ${timeZoneOffsetSeconds} and id: ${timeZoneId}`);
}
}
+
+function verifyStandardDateAndNanos(standardDate, nanosecond) {
+ assertValidDate(standardDate, 'Standard date');
+ if (nanosecond !== null && nanosecond !== undefined) {
+ assertNumberOrInteger(nanosecond, 'Nanosecond');
+ }
+}
diff --git a/test/internal/temporal-util.test.js b/test/internal/temporal-util.test.js
index c9108cee1..f0d05c387 100644
--- a/test/internal/temporal-util.test.js
+++ b/test/internal/temporal-util.test.js
@@ -169,6 +169,32 @@ describe('temporal-util', () => {
expect(util.localTimeToNanoOfDay(12, 51, 17, 808080)).toEqual(int(46277000808080));
});
+ it('should get total nanoseconds from standard date', () => {
+ expect(util.totalNanoseconds(new Date(2000, 1, 1, 1, 1, 1, 0))).toEqual(0);
+ expect(util.totalNanoseconds(new Date(2000, 1, 1, 1, 1, 1, 1))).toEqual(1000000);
+ expect(util.totalNanoseconds(new Date(2000, 1, 1, 1, 1, 1, 23))).toEqual(23000000);
+ expect(util.totalNanoseconds(new Date(2000, 1, 1, 1, 1, 1, 999))).toEqual(999000000);
+
+ expect(util.totalNanoseconds(new Date(2000, 1, 1, 1, 1, 1, 0), 0)).toEqual(0);
+ expect(util.totalNanoseconds(new Date(2000, 1, 1, 1, 1, 1, 0), 1)).toEqual(1);
+ expect(util.totalNanoseconds(new Date(2000, 1, 1, 1, 1, 1, 0), 999)).toEqual(999);
+ expect(util.totalNanoseconds(new Date(2000, 1, 1, 1, 1, 1, 1), 999)).toEqual(1000999);
+ expect(util.totalNanoseconds(new Date(2000, 1, 1, 1, 1, 1, 999), 111)).toEqual(999000111);
+
+ expect(util.totalNanoseconds(new Date(2000, 1, 1, 1, 1, 1, 0), int(0))).toEqual(int(0));
+ expect(util.totalNanoseconds(new Date(2000, 1, 1, 1, 1, 1, 0), int(1))).toEqual(int(1));
+ expect(util.totalNanoseconds(new Date(2000, 1, 1, 1, 1, 1, 0), int(999))).toEqual(int(999));
+ expect(util.totalNanoseconds(new Date(2000, 1, 1, 1, 1, 1, 1), int(999))).toEqual(int(1000999));
+ expect(util.totalNanoseconds(new Date(2000, 1, 1, 1, 1, 1, 999), int(111))).toEqual(int(999000111));
+ });
+
+ it('should get timezone offset in seconds from standard date', () => {
+ expect(util.timeZoneOffsetInSeconds(fakeStandardDateWithOffset(0))).toEqual(0);
+ expect(util.timeZoneOffsetInSeconds(fakeStandardDateWithOffset(2))).toEqual(120);
+ expect(util.timeZoneOffsetInSeconds(fakeStandardDateWithOffset(10))).toEqual(600);
+ expect(util.timeZoneOffsetInSeconds(fakeStandardDateWithOffset(101))).toEqual(6060);
+ });
+
});
function date(year, month, day) {
@@ -182,3 +208,9 @@ function localTime(hour, minute, second, nanosecond) {
function localDateTime(year, month, day, hour, minute, second, nanosecond) {
return new types.LocalDateTime(int(year), int(month), int(day), int(hour), int(minute), int(second), int(nanosecond));
}
+
+function fakeStandardDateWithOffset(offsetMinutes) {
+ const date = new Date();
+ date.getTimezoneOffset = () => offsetMinutes;
+ return date;
+}
diff --git a/test/internal/util.test.js b/test/internal/util.test.js
index 58cc873d6..6fc420ca9 100644
--- a/test/internal/util.test.js
+++ b/test/internal/util.test.js
@@ -135,6 +135,23 @@ describe('util', () => {
verifyInvalidNumberOrInteger({value: 42});
});
+ it('should check dates', () => {
+ verifyValidDate(new Date());
+ verifyValidDate(new Date(0));
+ verifyValidDate(new Date(-1));
+ verifyValidDate(new Date(2000, 10, 10));
+ verifyValidDate(new Date(2000, 10, 10, 10, 10, 10, 10));
+
+ verifyInvalidDate(new Date('not a valid date'));
+ verifyInvalidDate(new Date({}));
+ verifyInvalidDate(new Date([]));
+
+ verifyInvalidDate({});
+ verifyInvalidDate([]);
+ verifyInvalidDate('2007-04-05T12:30-02:00');
+ verifyInvalidDate(2019);
+ });
+
function verifyValidString(str) {
expect(util.assertString(str, 'Test string')).toBe(str);
}
@@ -171,4 +188,12 @@ describe('util', () => {
expect(() => util.validateStatementAndParameters('RETURN 1', obj)).toThrowError(TypeError);
}
+ function verifyValidDate(obj) {
+ expect(util.assertValidDate(obj, 'Test date')).toBe(obj);
+ }
+
+ function verifyInvalidDate(obj) {
+ expect(() => util.assertValidDate(obj, 'Test date')).toThrowError(TypeError);
+ }
+
});
diff --git a/test/types/v1/temporal-types.test.ts b/test/types/v1/temporal-types.test.ts
index 996b73208..30e000b8c 100644
--- a/test/types/v1/temporal-types.test.ts
+++ b/test/types/v1/temporal-types.test.ts
@@ -32,6 +32,7 @@ import {
Time
} from "../../../types/v1/temporal-types";
import Integer, {int} from "../../../types/v1/integer";
+import {StandardDate} from "../../../types/v1/graph-types";
const duration1: Duration = new Duration(int(1), int(1), int(1), int(1));
const months1: Integer = duration1.months;
@@ -149,3 +150,15 @@ const isTimeValue: boolean = isTime(time1);
const isDateValue: boolean = isDate(date1);
const isLocalDateTimeValue: boolean = isLocalDateTime(localDateTime1);
const isDateTimeValue: boolean = isDateTime(dateTime1);
+
+const dummy: any = null;
+const standardDate: StandardDate = dummy;
+const localTime3: LocalTime = LocalTime.fromStandardDate(standardDate);
+const localTime4: LocalTime = LocalTime.fromStandardDate(standardDate, 42);
+const time3: Time = Time.fromStandardDate(standardDate);
+const time4: Time = Time.fromStandardDate(standardDate, 42);
+const date3: Date = Date.fromStandardDate(standardDate);
+const localDateTime3: LocalDateTime = LocalDateTime.fromStandardDate(standardDate);
+const localDateTime4: LocalDateTime = LocalDateTime.fromStandardDate(standardDate, 42);
+const dateTime5: DateTime = DateTime.fromStandardDate(standardDate);
+const dateTime6: DateTime = DateTime.fromStandardDate(standardDate, 42);
diff --git a/test/v1/temporal-types.test.js b/test/v1/temporal-types.test.js
index cbc926f12..eea25e741 100644
--- a/test/v1/temporal-types.test.js
+++ b/test/v1/temporal-types.test.js
@@ -19,6 +19,7 @@
import neo4j from '../../src';
import sharedNeo4j from '../internal/shared-neo4j';
+import {totalNanoseconds} from '../../src/v1/internal/temporal-util';
import {ServerVersion, VERSION_3_4_0} from '../../src/v1/internal/server-version';
import timesSeries from 'async/timesSeries';
import _ from 'lodash';
@@ -658,6 +659,194 @@ describe('temporal-types', () => {
expect(() => new neo4j.types.DateTime(1, 2, 3, 4, 5, 6, 7, 8, 'UK')).toThrow();
});
+ it('should convert standard Date to neo4j LocalTime', () => {
+ testStandardDateToLocalTimeConversion(new Date(2000, 1, 1, 0, 0, 0, 0));
+ testStandardDateToLocalTimeConversion(new Date(1456, 7, 12, 12, 0, 0, 0));
+ testStandardDateToLocalTimeConversion(new Date(2121, 11, 27, 21, 56, 0, 0));
+ testStandardDateToLocalTimeConversion(new Date(1392, 2, 2, 3, 14, 59, 0));
+ testStandardDateToLocalTimeConversion(new Date(1102, 6, 5, 17, 12, 32, 99));
+ testStandardDateToLocalTimeConversion(new Date(2019, 2, 7, 0, 0, 0, 1));
+
+ testStandardDateToLocalTimeConversion(new Date(1351, 4, 7, 0, 0, 0, 0), neo4j.int(1));
+ testStandardDateToLocalTimeConversion(new Date(3841, 1, 19, 0, 0, 0, 0), neo4j.int(99));
+ testStandardDateToLocalTimeConversion(new Date(2222, 3, 29, 0, 0, 0, 0), neo4j.int(999999999));
+ });
+
+ it('should fail to convert invalid standard Date to neo4j LocalTime', () => {
+ const LocalTime = neo4j.types.LocalTime;
+
+ expect(() => LocalTime.fromStandardDate()).toThrowError(TypeError);
+ expect(() => LocalTime.fromStandardDate('2007-04-05T12:30-02:00')).toThrowError(TypeError);
+ expect(() => LocalTime.fromStandardDate({})).toThrowError(TypeError);
+
+ expect(() => LocalTime.fromStandardDate(new Date({}))).toThrowError(TypeError);
+ expect(() => LocalTime.fromStandardDate(new Date([]))).toThrowError(TypeError);
+ expect(() => LocalTime.fromStandardDate(new Date(NaN))).toThrowError(TypeError);
+
+ expect(() => LocalTime.fromStandardDate(new Date(), '1')).toThrowError(TypeError);
+ expect(() => LocalTime.fromStandardDate(new Date(), {nanosecond: 1})).toThrowError(TypeError);
+ expect(() => LocalTime.fromStandardDate(new Date(), [1])).toThrowError(TypeError);
+ });
+
+ it('should convert standard Date to neo4j Time', () => {
+ testStandardDateToTimeConversion(new Date(2000, 1, 1, 0, 0, 0, 0));
+ testStandardDateToTimeConversion(new Date(1456, 7, 12, 12, 0, 0, 0));
+ testStandardDateToTimeConversion(new Date(2121, 11, 27, 21, 56, 0, 0));
+ testStandardDateToTimeConversion(new Date(1392, 2, 2, 3, 14, 59, 0));
+ testStandardDateToTimeConversion(new Date(1102, 6, 5, 17, 12, 32, 99));
+ testStandardDateToTimeConversion(new Date(2019, 2, 7, 0, 0, 0, 1));
+
+ testStandardDateToTimeConversion(new Date(1351, 4, 7, 0, 0, 0, 0), neo4j.int(1));
+ testStandardDateToTimeConversion(new Date(3841, 1, 19, 0, 0, 0, 0), neo4j.int(99));
+ testStandardDateToTimeConversion(new Date(2222, 3, 29, 0, 0, 0, 0), neo4j.int(999999999));
+ });
+
+ it('should fail to convert invalid standard Date to neo4j Time', () => {
+ const Time = neo4j.types.Time;
+
+ expect(() => Time.fromStandardDate()).toThrowError(TypeError);
+ expect(() => Time.fromStandardDate('2007-04-05T12:30-02:00')).toThrowError(TypeError);
+ expect(() => Time.fromStandardDate({})).toThrowError(TypeError);
+
+ expect(() => Time.fromStandardDate(new Date({}))).toThrowError(TypeError);
+ expect(() => Time.fromStandardDate(new Date([]))).toThrowError(TypeError);
+ expect(() => Time.fromStandardDate(new Date(NaN))).toThrowError(TypeError);
+
+ expect(() => Time.fromStandardDate(new Date(), '1')).toThrowError(TypeError);
+ expect(() => Time.fromStandardDate(new Date(), {nanosecond: 1})).toThrowError(TypeError);
+ expect(() => Time.fromStandardDate(new Date(), [1])).toThrowError(TypeError);
+ });
+
+ it('should convert standard Date to neo4j Date', () => {
+ testStandardDateToNeo4jDateConversion(new Date(2000, 1, 1));
+ testStandardDateToNeo4jDateConversion(new Date(1456, 7, 12));
+ testStandardDateToNeo4jDateConversion(new Date(2121, 11, 27));
+ testStandardDateToNeo4jDateConversion(new Date(1392, 2, 2));
+ testStandardDateToNeo4jDateConversion(new Date(1102, 6, 5));
+ testStandardDateToNeo4jDateConversion(new Date(2019, 2, 7));
+
+ testStandardDateToNeo4jDateConversion(new Date(1351, 4, 7));
+ testStandardDateToNeo4jDateConversion(new Date(3841, 1, 19));
+ testStandardDateToNeo4jDateConversion(new Date(2222, 3, 29));
+
+ testStandardDateToNeo4jDateConversion(new Date(1567, 0, 29));
+ });
+
+ it('should fail to convert invalid standard Date to neo4j Date', () => {
+ const Neo4jDate = neo4j.types.Date;
+
+ expect(() => Neo4jDate.fromStandardDate()).toThrowError(TypeError);
+ expect(() => Neo4jDate.fromStandardDate('2007-04-05T12:30-02:00')).toThrowError(TypeError);
+ expect(() => Neo4jDate.fromStandardDate({})).toThrowError(TypeError);
+
+ expect(() => Neo4jDate.fromStandardDate(new Date({}))).toThrowError(TypeError);
+ expect(() => Neo4jDate.fromStandardDate(new Date([]))).toThrowError(TypeError);
+ expect(() => Neo4jDate.fromStandardDate(new Date(NaN))).toThrowError(TypeError);
+ });
+
+ it('should convert standard Date to neo4j LocalDateTime', () => {
+ testStandardDateToLocalDateTimeConversion(new Date(2011, 9, 18));
+ testStandardDateToLocalDateTimeConversion(new Date(1455, 0, 1));
+ testStandardDateToLocalDateTimeConversion(new Date(0));
+ testStandardDateToLocalDateTimeConversion(new Date(2056, 5, 22, 21, 59, 12, 999));
+
+ testStandardDateToLocalDateTimeConversion(new Date(0), 1);
+ testStandardDateToLocalDateTimeConversion(new Date(0), 999999999);
+ testStandardDateToLocalDateTimeConversion(new Date(1922, 1, 22, 23, 23, 45, 123), 456789);
+
+ testStandardDateToLocalDateTimeConversion(new Date(1999, 1, 1, 10, 10, 10), neo4j.int(999));
+
+ testStandardDateToLocalDateTimeConversion(new Date(2192, 0, 17, 20, 30, 40));
+ testStandardDateToLocalDateTimeConversion(new Date(2239, 0, 9, 1, 2, 3), 4);
+ });
+
+ it('should fail to convert invalid standard Date to neo4j LocalDateTime', () => {
+ const LocalDateTime = neo4j.types.LocalDateTime;
+
+ expect(() => LocalDateTime.fromStandardDate()).toThrowError(TypeError);
+ expect(() => LocalDateTime.fromStandardDate('2007-04-05T12:30-02:00')).toThrowError(TypeError);
+ expect(() => LocalDateTime.fromStandardDate({})).toThrowError(TypeError);
+
+ expect(() => LocalDateTime.fromStandardDate(new Date({}))).toThrowError(TypeError);
+ expect(() => LocalDateTime.fromStandardDate(new Date([]))).toThrowError(TypeError);
+ expect(() => LocalDateTime.fromStandardDate(new Date(NaN))).toThrowError(TypeError);
+
+ expect(() => LocalDateTime.fromStandardDate(new Date(), '1')).toThrowError(TypeError);
+ expect(() => LocalDateTime.fromStandardDate(new Date(), {nanosecond: 1})).toThrowError(TypeError);
+ expect(() => LocalDateTime.fromStandardDate(new Date(), [1])).toThrowError(TypeError);
+ });
+
+ it('should convert standard Date to neo4j DateTime', () => {
+ testStandardDateToDateTimeConversion(new Date(2011, 9, 18));
+ testStandardDateToDateTimeConversion(new Date(1455, 0, 1));
+ testStandardDateToDateTimeConversion(new Date(0));
+ testStandardDateToDateTimeConversion(new Date(2056, 5, 22, 21, 59, 12, 999));
+
+ testStandardDateToDateTimeConversion(new Date(0), 1);
+ testStandardDateToDateTimeConversion(new Date(0), 999999999);
+
+ testStandardDateToDateTimeConversion(new Date(1922, 1, 22, 23, 23, 45, 123), 456789);
+ testStandardDateToDateTimeConversion(new Date(1999, 1, 1, 10, 10, 10), neo4j.int(999));
+
+ testStandardDateToDateTimeConversion(new Date(1899, 0, 7, 7, 7, 7, 7));
+ testStandardDateToDateTimeConversion(new Date(2005, 0, 1, 2, 3, 4, 5), 100);
+ });
+
+ it('should fail to convert invalid standard Date to neo4j DateTime', () => {
+ const DateTime = neo4j.types.DateTime;
+
+ expect(() => DateTime.fromStandardDate()).toThrowError(TypeError);
+ expect(() => DateTime.fromStandardDate('2007-04-05T12:30-02:00')).toThrowError(TypeError);
+ expect(() => DateTime.fromStandardDate({})).toThrowError(TypeError);
+
+ expect(() => DateTime.fromStandardDate(new Date({}))).toThrowError(TypeError);
+ expect(() => DateTime.fromStandardDate(new Date([]))).toThrowError(TypeError);
+ expect(() => DateTime.fromStandardDate(new Date(NaN))).toThrowError(TypeError);
+
+ expect(() => DateTime.fromStandardDate(new Date(), '1')).toThrowError(TypeError);
+ expect(() => DateTime.fromStandardDate(new Date(), {nanosecond: 1})).toThrowError(TypeError);
+ expect(() => DateTime.fromStandardDate(new Date(), [1])).toThrowError(TypeError);
+ });
+
+ it('should send and receive neo4j Date created from standard Date with zero month', done => {
+ if (neo4jDoesNotSupportTemporalTypes(done)) {
+ return;
+ }
+
+ // return numbers and not integers to simplify the equality comparison
+ session = driverWithNativeNumbers.session();
+
+ const standardDate = new Date(2000, 0, 1);
+ const neo4jDate = neo4j.types.Date.fromStandardDate(standardDate);
+ testSendReceiveTemporalValue(neo4jDate, done);
+ });
+
+ it('should send and receive neo4j LocalDateTime created from standard Date with zero month', done => {
+ if (neo4jDoesNotSupportTemporalTypes(done)) {
+ return;
+ }
+
+ // return numbers and not integers to simplify the equality comparison
+ session = driverWithNativeNumbers.session();
+
+ const standardDate = new Date(2121, 0, 7, 10, 20, 30, 40);
+ const neo4jLocalDateTime = neo4j.types.LocalDateTime.fromStandardDate(standardDate);
+ testSendReceiveTemporalValue(neo4jLocalDateTime, done);
+ });
+
+ it('should send and receive neo4j DateTime created from standard Date with zero month', done => {
+ if (neo4jDoesNotSupportTemporalTypes(done)) {
+ return;
+ }
+
+ // return numbers and not integers to simplify the equality comparison
+ session = driverWithNativeNumbers.session();
+
+ const standardDate = new Date(1756, 0, 29, 23, 15, 59, 12);
+ const neo4jDateTime = neo4j.types.DateTime.fromStandardDate(standardDate);
+ testSendReceiveTemporalValue(neo4jDateTime, done);
+ });
+
function testSendAndReceiveRandomTemporalValues(valueGenerator, done) {
const asyncFunction = (index, callback) => {
const next = () => callback();
@@ -844,4 +1033,37 @@ describe('temporal-types', () => {
function randomInt(lower, upper) {
return neo4j.int(_.random(lower, upper));
}
+
+ function testStandardDateToLocalTimeConversion(date, nanosecond) {
+ const converted = neo4j.types.LocalTime.fromStandardDate(date, nanosecond);
+ const expected = new neo4j.types.LocalTime(date.getHours(), date.getMinutes(), date.getSeconds(), totalNanoseconds(date, nanosecond));
+ expect(converted).toEqual(expected);
+ }
+
+ function testStandardDateToTimeConversion(date, nanosecond) {
+ const converted = neo4j.types.Time.fromStandardDate(date, nanosecond);
+ const expected = new neo4j.types.Time(date.getHours(), date.getMinutes(), date.getSeconds(), totalNanoseconds(date, nanosecond),
+ date.getTimezoneOffset() * 60);
+ expect(converted).toEqual(expected);
+ }
+
+ function testStandardDateToNeo4jDateConversion(date) {
+ const converted = neo4j.types.Date.fromStandardDate(date);
+ const expected = new neo4j.types.Date(date.getFullYear(), date.getMonth() + 1, date.getDate());
+ expect(converted).toEqual(expected);
+ }
+
+ function testStandardDateToLocalDateTimeConversion(date, nanosecond) {
+ const converted = neo4j.types.LocalDateTime.fromStandardDate(date, nanosecond);
+ const expected = new neo4j.types.LocalDateTime(date.getFullYear(), date.getMonth() + 1, date.getDate(), date.getHours(), date.getMinutes(),
+ date.getSeconds(), totalNanoseconds(date, nanosecond));
+ expect(converted).toEqual(expected);
+ }
+
+ function testStandardDateToDateTimeConversion(date, nanosecond) {
+ const converted = neo4j.types.DateTime.fromStandardDate(date, nanosecond);
+ const expected = new neo4j.types.DateTime(date.getFullYear(), date.getMonth() + 1, date.getDate(), date.getHours(), date.getMinutes(), date.getSeconds(),
+ totalNanoseconds(date, nanosecond), date.getTimezoneOffset() * 60);
+ expect(converted).toEqual(expected);
+ }
});
diff --git a/types/v1/graph-types.d.ts b/types/v1/graph-types.d.ts
index 333f5044b..58f2f5792 100644
--- a/types/v1/graph-types.d.ts
+++ b/types/v1/graph-types.d.ts
@@ -19,6 +19,7 @@
import Integer from "./integer";
+declare type StandardDate = Date;
declare type NumberOrInteger = number | Integer;
declare class Node {
@@ -90,5 +91,6 @@ export {
UnboundRelationship,
Path,
PathSegment,
- NumberOrInteger
+ NumberOrInteger,
+ StandardDate
}
diff --git a/types/v1/temporal-types.d.ts b/types/v1/temporal-types.d.ts
index f8760f965..c9af663f1 100644
--- a/types/v1/temporal-types.d.ts
+++ b/types/v1/temporal-types.d.ts
@@ -17,7 +17,7 @@
* limitations under the License.
*/
-import {NumberOrInteger} from './graph-types';
+import {NumberOrInteger, StandardDate} from './graph-types';
import Integer from "./integer";
declare class Duration {
@@ -38,6 +38,8 @@ declare class LocalTime {
readonly nanosecond: T;
constructor(hour: T, minute: T, second: T, nanosecond: T);
+
+ static fromStandardDate(standardDate: StandardDate, nanosecond?: number): LocalTime;
}
declare class Time {
@@ -49,6 +51,8 @@ declare class Time {
readonly timeZoneOffsetSeconds: T;
constructor(hour: T, minute: T, second: T, nanosecond: T, timeZoneOffsetSeconds: T);
+
+ static fromStandardDate(standardDate: StandardDate, nanosecond?: number): Time;
}
declare class Date {
@@ -58,6 +62,8 @@ declare class Date {
readonly day: T;
constructor(year: T, month: T, day: T);
+
+ static fromStandardDate(standardDate: StandardDate): Date;
}
declare class LocalDateTime {
@@ -71,6 +77,8 @@ declare class LocalDateTime {
readonly nanosecond: T;
constructor(year: T, month: T, day: T, hour: T, minute: T, second: T, nanosecond: T);
+
+ static fromStandardDate(standardDate: StandardDate, nanosecond?: number): LocalDateTime;
}
declare class DateTime {
@@ -86,6 +94,8 @@ declare class DateTime {
readonly timeZoneId?: string;
constructor(year: T, month: T, day: T, hour: T, minute: T, second: T, nanosecond: T, timeZoneOffsetSeconds?: T, timeZoneId?: string);
+
+ static fromStandardDate(standardDate: StandardDate, nanosecond?: number): DateTime;
}
declare function isDuration(obj: object): boolean;