Skip to content

Inserting Date values into Spanner date column fails #2097

Closed

Description

@jgeewax

What I want to do:

myTable.insert({id: 1, start_date: new Date(1976, 4, 1)}).then(function (data) {
  console.log(data);
});

What I have to do instead :(

myTable.insert({id: 1, start_date: '1976-04-01'},).then(function (data) {
  console.log(data);
});

Can we make dates do "the right thing" ? Or is that not possible?

Activity

  1. stephenplusplus commented on Mar 17, 2017

    @stephenplusplus
    Contributor

    It is honored as a TIMESTAMP currently. We also have spanner.date('08-08-08') for DATE.

  2. jgeewax commented on Mar 17, 2017

    @jgeewax
    ContributorAuthor

    What about spanner.date() that takes the same constructor as new Date() ? Or even a date?

    I imagine that I get a date as an actual JS date somehow, and want to put that into Spanner in a DATE column. In this world I'd have to... call spanner.date(dateformat(mydateval, ...)) which makes me sad.

    At the very least I'd like to be able to do spanner.date(mydateval) and have it do the right thing. Can we do that?

  3. vkedia commented on Mar 20, 2017

    @vkedia
    Contributor

    Yeah I agree it would be nice to have a constructor on spanner.Date which takes the individual fields.

  4. lukesneeringer commented on Mar 21, 2017

    @lukesneeringer
    Contributor

    According to the documentation and the code, spanner.date() already coerces a Date properly (in fact, it coerces strings to dates, not vice versa).

  5. lukesneeringer commented on Mar 21, 2017

    @lukesneeringer
    Contributor

    It also looks like dates are encoded if sent directly. Does a spanner.date work and a Date not work? If so, we could fix it by changing line 156 to value = new SpannerDate(value).value.

  6. jgeewax commented on Mar 22, 2017

    @jgeewax
    ContributorAuthor

    The code linked here leads me to believe that the string representation (or the date representation) will work, but it won't handle the same parameters that new Date does.. but this may be for the best.

    In code...

    // Copy and paste in the definition (spanner.date is promisified weirdly)
    > function SpannerDate(value) {
    ...   if (is.undefined(value)) {
    .....     value = new Date();
    .....   }
    ... 
    ...   this.value = new Date(value).toJSON().replace(/T.+/, '');
    ... }
    undefined
    > new SpannerDate('2016-01-01').value
    '2016-01-01'
    
    // But, the you can't use the same arguments, since it only looks at the first:
    > new SpannerDate(2016, 1, 1).value
    '1970-01-01'
    > new SpannerDate(2016).value
    '1970-01-01'
    
    // But then... it seems that Javascript is pretty stupid with the Date constructor...
    > new Date(2016, 1, 1).toJSON()   // Months are zero-indexed, but days are not...
    '2016-02-01T05:00:00.000Z'
    
    // And I guess it's crazy to expect JS to say "nah you can't put in garbage crazy dates".
    // In true JS style, it treats the second argument as "add (val) months" (zero-indexed)
    // and the third as "add (val-1) days" (one-indexed)
    > new Date(2016, 99, 99).toJSON()
    '2024-07-08T04:00:00.000Z'
    > new Date(2016, 99, 98).toJSON()
    '2024-07-07T04:00:00.000Z'
    
    > new SpannerDate(new Date(2016, 1, 1)).value
    '2016-02-01'

    So: I now retract my request to support the same arguments because new Date is ... certifiably insane.

    My new request is that we throw an error when you do spanner.date(year, month, day). Is that doable?

  7. lukesneeringer commented on Mar 22, 2017

    @lukesneeringer
    Contributor

    So: I now retract my request to support the same arguments because new Date is ... certifiably insane.

    I was considering pointing out to you that the two lines you had in your original post were not equivalent because JavaScript uses zero-indexing for months (why? why? whyyyyyy?) :-)

    My new request is that we throw an error when you do spanner.date(year, month, day). Is that doable?

    Yes, except what we will actually do is throw an error if you send a Number to year. that is less than or equal to, say, 0 < x <= 9,999. (Anything above that will be treated as a timestamp.) <-- Nevermind, new Date(timestamp) does not do what any normal person would expect, either.

    I can also do a thing where if we get three ints, we subtract one from the month and forward them to new Date. That would get you what you originally wanted. I would probably be reticent to it just because of the whole zero-indexed months confusion.

  8. added a commit that references this issue on Mar 22, 2017
    96704fd
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

api: spannerIssues related to the Spanner API.

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions