Skip to content
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

Client returns wrong date, when the date in Postgres is declared as date-type #818

Closed
vheinitz opened this issue Jul 24, 2015 · 8 comments
Closed

Comments

@vheinitz
Copy link

I have declared a date column in Postgres as date.
When I write the value with node's pg module, the Postgres Tool pgAdmin displays it correctly.
When I read the value back using pg, Instead of plain date, a date-time string comes with wrong day.
e.g.:

Date inserted: 1975-05-11
Date displayed by pgAdmin: 1975-05-11
Date returned by node's pg: 1975-05-10T23:00:00.000Z

The error seems to be due to the different handling of time-zone during parsing from string and converting the Date-object back to string.

I hope this post may help: SO

@brianc
Copy link
Owner

brianc commented Jul 24, 2015

The node-postgres team decided long ago to convert dates and datetimes
without timezones to local time when pulling them out. This is consistent
with some documentation we've dug up in the past. If you root around
through old issues here you'll find the discussions.

The good news is its trivially easy to over-ride this behavior and return
dates however you see fit.

There's documentation on how to do this here:
https://github.com/brianc/node-pg-types

There's probably even a module somewhere that will convert dates from
postgres into whatever timezone you want (utc I'm guessing). And if
there's not...that's a good opportunity to write one & share with everyone!

On Fri, Jul 24, 2015 at 6:36 AM, Valentin Heinitz notifications@github.com
wrote:

I have declared a date column in Postgres as date.
When I write the value with node's pg module, the Postgres Tool pgAdmin
displays it correctly.
When I read the value back using pg, Instead of plain date, a date-time
string comes with wrong day.
e.g.:

Date inserted: 1975-05-11
Date displayed by pgAdmin: 1975-05-11
Date returned by node's pg: 1975-05-10T23:00:00.000Z

The error seems to be due to the different handling of time-zone during
parsing from string and converting the Date-object back to string.

I hope this post may help: SO
http://stackoverflow.com/questions/31608368/nodes-postgres-module-pg-returns-wrong-date


Reply to this email directly or view it on GitHub
#818.

@vheinitz
Copy link
Author

I'm affraid, trying to convert date objects to timestamps doesn't work wll in all use-cases.

There are dates like birth-dates or historical events, which have no time-relevance. If one client writes let's say 1973-09-11 and another reads 1973-09-10 it is bad.

The date 1973-09-11 is a historical event. May be, that from Australian point of view it happened a day before or a day after, but even in their historical books the date is provided as 1973-09-11.

@brianc
Copy link
Owner

brianc commented Jul 24, 2015

Yeah you're totally right about that if you're storing them for that
reason. Definitely suggest you over-write the type parser to return them
as a custom data type or maybe even just a string?

On Fri, Jul 24, 2015 at 12:19 PM, Valentin Heinitz <notifications@github.com

wrote:

I'm affraid, trying to convert date objects to timestamps doesn't work wll
in all use-cases.

There are dates like birth-dates or historical events, which have no
time-relevance. If one client writes let's say 1973-09-11 and another reads
1973-09-10 it is bad.

The date 1973-09-11 is a historical event. May be, that from Australian
point of view it happened a day before or a day after, but even in their
historical books the date is provided as 1973-09-11.


Reply to this email directly or view it on GitHub
#818 (comment)
.

@vheinitz
Copy link
Author

Thank you very much, Brian for you quick response and suggestions! I'll check the opportunities you've mentioned.

@indreek
Copy link

indreek commented Jul 30, 2015

This is workaround what i did:

/* Node postgres date fix /
var Moment = require('moment');
var parseDate = function parseDate(val) {
return val === null ? null : Moment(val).format('YYYY-MM-DD')
};
var types = pg.types;
var DATATYPE_DATE = 1082;
types.setTypeParser(DATATYPE_DATE, function(val) {
return val === null ? null : parseDate(val)
});
/
Node postgres date fix - end */

StefanHoutzager added a commit to StefanHoutzager/deno-postgres that referenced this issue Oct 7, 2020
…ateStr + 'T00:00:00Z')

/* text of issue denodrivers#181 copied */
Currently I get my dates (defined with datatype DATE) back as f.e. "2021-03-02T23:00:00.000Z" while pgadmin gives 2021-03-03. So I get the wrong date back (and a timestamp was added).
You can find the same issue in node-postgres brianc/node-postgres#818 where someone suggests a workaround in the end (that I just tested, it works). brianc/node-postgres#818 , see a paste of the snippet below. Can this be fixed in deno-postgres? My proposal would be to change decodeDate in decode.ts to simply

function decodeDate(dateStr: string): Date {
    return new Date(dateStr + 'T00:00:00Z');
}
of course that works for year 0001 too. ;-) For null values in the postgress date the function decodeDate is not executed.

/* Node postgres date fix /
var Moment = require('moment');
var parseDate = function parseDate(val) {
return val === null ? null : Moment(val).format('YYYY-MM-DD')
};
var types = pg.types;
var DATATYPE_DATE = 1082;
types.setTypeParser(DATATYPE_DATE, function(val) {
return val === null ? null : parseDate(val)
});
/ Node postgres date fix - end */
@ashconnell
Copy link

This behaviour is crazy to me.

In almost all cases you should be using timestamptz EXCEPT when you need to store future dates at wall-time. This is where timestamp comes in.

Storing without timezone for future dates protects againsts changes to DST that can and do happen before the future date arrives.

Since pg is parsing timestamp into UTC, things get really weird at the application layer.

I think the main problem here is that pg coerces both of these types into a Date. It would be super weird if timestamptz was a Date and timestamp was a String, so this is probably the reasoning.

For anyone running into similar issues, I ended up bypassing the parser for timestamp completely and just use a String:

import pg from 'pg'
pg.types.setTypeParser(1114, function (value) {
  return value
})

@alexandreec
Copy link

@ashconnell thank you!

You have to bypass the date parser also:

pg.types.setTypeParser(1082, function(value) { //date
  return value;
});

@gilles-crealp
Copy link

There are built-in constants for date (1082), timestamp (1114) and timestamptz (1184) :

pg.types.setTypeParser(pg.types.builtins.DATE, value => value)

pg.types.setTypeParser(pg.types.builtins.TIMESTAMP, value => value)

pg.types.setTypeParser(pg.types.builtins.TIMESTAMPTZ, value => value)

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

6 participants