Skip to content

DateTime and temporal usage #394

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
noumaans opened this issue Jun 23, 2018 · 4 comments
Closed

DateTime and temporal usage #394

noumaans opened this issue Jun 23, 2018 · 4 comments

Comments

@noumaans
Copy link

Trying to use temporal types, and running into few issues.

The following code is trying to convert parameter which needs to be passed onto session.run:

    const value = new Date();
    const newValue = new neo4j.DateTime( // also tried neo4j.v1.DateTime, neo4j.temporal.DateTime
      value.getFullYear(),
      value.getMonth(),
      value.getDay(),
      value.getHours(),
      value.getMinutes(),
      value.getSeconds(),
      value.getMilliseconds() * 1000000,  // nanoseconds
      value.getTimezoneOffset() * 60      // seconds
    );

   session.run(cypher, {updated: newValue}) // store current date on save

I've tried the following approaches to import neo4j driver:

import {v1 as neo4j} from 'neo4j-driver';
import neo4j from 'neo4j-driver';

The errors raised on the conversion are of these types:
_neo4jDriver2.default.temporal.DateTime is not a constructor
Cannot read property 'temporal' of undefined
Cannot read property 'DateTime' of undefined
_neo4jDriver.v1.DateTime is not a constructor

I can access other methods such as .isInt() without any issues.

Version Info:

 $ grep 'resolved.*neo4j-driver' package-lock.json 
      "resolved": "https://registry.npmjs.org/neo4j-driver/-/neo4j-driver-1.6.1.tgz",
@lutovich
Copy link
Contributor

lutovich commented Jun 23, 2018

Hi @noumaans,

All types defined by the driver can be accessed via neo4j.types static variable. API doc for it is here.

Example:

const neo4j = require('neo4j-driver').v1;
const value = new Date();
const newValue = new neo4j.types.DateTime(
    value.getFullYear(),
    value.getMonth(),
    value.getDay(),
    value.getHours(),
    value.getMinutes(),
    value.getSeconds(),
    value.getMilliseconds() * 1000000,
    value.getTimezoneOffset() * 60
);
console.log(newValue.toString());
// outputs '2018-05-06T18:22:00.078000000-02:00'

For the 1.6.2 version of the driver we will most likely add helper functions to create temporal types from a standard JavaScript date. See #390. This might be useful for you.

Hope this helps!

@noumaans
Copy link
Author

390 contains functions to create DateTime from JS Standard Date which is great.

May I please request utility functions which will convert neo4j DateTime objects back to JS Standard Date as well?

Additionally, I'm noticing that Date members unlike numbers are not converted to standard JS objects when calling .properties on node.

e.g.: given (n: SomeNode {name: 'Foo'}) SET n.int_property = 4, SET n.date_property = ...

console.log('foo properties: ' + node.properties);

returns:

{"int_property":4,"name":"Foo","date_property":{"year":{"low":2018,"high":0},"month":{"low":6,"high":0},"day":{"low":27,"high":0},"hour":{"low":18,"high":0},"minute":{"low":27,"high":0},"second":{"low":19,"high":0},"nanosecond":{"low":177000000,"high":0},"timeZoneOffsetSeconds":{"low":0,"high":0},"timeZoneId":null}}

Is the implicit conversion for numbers (call to .toNumber) limited in driver by design when node.properties is called?
or are you planning to add something like:

if (neo4j.temporal.isDateTime(value)) {
  value = new Date(value.toString()); // or something faster
}

@lutovich
Copy link
Contributor

@noumaans does the suggested way of using date-time types work for you?

We will probably add conversion functions from driver types to standard JS date in future. Right now it should be possible to convert as well because toString() of all temporal types returns ISO strings. They can be parsed by the Date constructor. Something like this should work:

const neo4jDate = new neo4j.types.Date(2010, 10, 10);
const standardDate = new Date(neo4jDate.toString());

It will only not work for neo4j.type.DateTime objects which contain time zone name (like "Europe/London") because standard JS date only supports time zone offsets. Driver does not contain a time zone name -> offset mapping table and can't perform the conversion.

Driver does not automatically convert Integer objects to standard numbers. This is true for all integers sent from the database to the driver. Such integers might be nested in lists, maps, temporal or spatial objects. This is done to avoid loosing precission, since database can store integers wider than the standard JS number. You can configure driver to only return native numbers. More information about integer handling is here.

@noumaans
Copy link
Author

Thank you so much @lutovich. Your suggestion works.
I'm closing this issue since 390 will take care of most of the other concerns.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants