Skip to content

Commit 8a2e864

Browse files
committed
Merge pull request brianc#238 from cdauth/master
Store timezone-less dates in local time instead of UTC
2 parents c8c4a6d + 3aedebb commit 8a2e864

File tree

3 files changed

+64
-4
lines changed

3 files changed

+64
-4
lines changed

lib/types/binaryParsers.js

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -141,13 +141,17 @@ var parseNumeric = function(value) {
141141
return ((sign === 0) ? 1 : -1) * Math.round(result * scale) / scale;
142142
};
143143

144-
var parseDate = function(value) {
144+
var parseDate = function(isUTC, value) {
145145
var sign = parseBits(value, 1);
146146
var rawValue = parseBits(value, 63, 1);
147147

148148
// discard usecs and shift from 2000 to 1970
149149
var result = new Date((((sign === 0) ? 1 : -1) * rawValue / 1000) + 946684800000);
150150

151+
if (!isUTC) {
152+
result.setTime(result.getTime() + result.getTimezoneOffset() * 60000);
153+
}
154+
151155
// add microseconds to the date
152156
result.usec = rawValue % 1000;
153157
result.getMicroSeconds = function() {
@@ -247,8 +251,8 @@ var init = function(register) {
247251
register(700, parseFloat32);
248252
register(701, parseFloat64);
249253
register(16, parseBool);
250-
register(1114, parseDate);
251-
register(1184, parseDate);
254+
register(1114, parseDate.bind(null, false));
255+
register(1184, parseDate.bind(null, true));
252256
register(1007, parseArray);
253257
register(1016, parseArray);
254258
register(1008, parseArray);

lib/utils.js

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ function arrayString(val) {
4747
//for complex types, etc...
4848
var prepareValue = function(val) {
4949
if(val instanceof Date) {
50-
return JSON.stringify(val);
50+
return dateToString(val);
5151
}
5252
if(typeof val === 'undefined') {
5353
return null;
@@ -58,6 +58,33 @@ var prepareValue = function(val) {
5858
return val === null ? null : val.toString();
5959
};
6060

61+
function dateToString(date) {
62+
function pad(number, digits) {
63+
number = ""+number;
64+
while(number.length < digits)
65+
number = "0"+number;
66+
return number;
67+
}
68+
69+
var offset = -date.getTimezoneOffset();
70+
var ret = pad(date.getFullYear(), 4) + '-' +
71+
pad(date.getMonth() + 1, 2) + '-' +
72+
pad(date.getDate(), 2) + 'T' +
73+
pad(date.getHours(), 2) + ':' +
74+
pad(date.getMinutes(), 2) + ':' +
75+
pad(date.getSeconds(), 2) + '.' +
76+
pad(date.getMilliseconds(), 3);
77+
78+
if(offset < 0) {
79+
ret += "-";
80+
offset *= -1;
81+
}
82+
else
83+
ret += "+";
84+
85+
return ret + pad(Math.floor(offset/60), 2) + ":" + pad(offset%60, 2);
86+
}
87+
6188
function normalizeQueryConfig (config, values, callback) {
6289
//can take in strings or config objects
6390
config = (typeof(config) == 'string') ? { text: config } : config;
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
var helper = require(__dirname + '/../test-helper');
2+
var exec = require('child_process').exec;
3+
4+
var oldTz = process.env.TZ;
5+
process.env.TZ = 'Europe/Berlin';
6+
7+
var date = new Date();
8+
9+
helper.pg.connect(helper.config, function(err, client, done) {
10+
assert.isNull(err);
11+
12+
test('timestamp without time zone', function() {
13+
client.query("SELECT CAST($1 AS TIMESTAMP WITHOUT TIME ZONE) AS \"val\"", [ date ], function(err, result) {
14+
assert.isNull(err);
15+
assert.equal(result.rows[0].val.getTime(), date.getTime());
16+
17+
test('timestamp with time zone', function() {
18+
client.query("SELECT CAST($1 AS TIMESTAMP WITH TIME ZONE) AS \"val\"", [ date ], function(err, result) {
19+
assert.isNull(err);
20+
assert.equal(result.rows[0].val.getTime(), date.getTime());
21+
22+
done();
23+
helper.pg.end();
24+
process.env.TZ = oldTz;
25+
});
26+
});
27+
});
28+
});
29+
});

0 commit comments

Comments
 (0)