Skip to content

Commit 3fa5306

Browse files
author
Kevin Delisle
authored
Merge pull request #271 from bbito/bb-fresh-master
Remove String manipulations of Date objects
2 parents ea33f55 + 31a7728 commit 3fa5306

File tree

2 files changed

+108
-18
lines changed

2 files changed

+108
-18
lines changed

lib/mysql.js

+13-18
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,13 @@ function generateOptions(settings) {
152152
options[p] = s[p];
153153
}
154154
}
155+
// Legacy UTC Date Processing fallback - SHOULD BE TRANSITIONAL
156+
if (s.legacyUtcDateProcessing === undefined) {
157+
s.legacyUtcDateProcessing = true;
158+
}
159+
if (s.legacyUtcDateProcessing) {
160+
options.timezone = 'Z';
161+
}
155162
}
156163
return options;
157164
}
@@ -307,19 +314,6 @@ MySQL.prototype.updateOrCreate = function(model, data, options, cb) {
307314
this._modifyOrCreate(model, data, options, fields, cb);
308315
};
309316

310-
function dateToMysql(val) {
311-
return val.getUTCFullYear() + '-' +
312-
fillZeros(val.getUTCMonth() + 1) + '-' +
313-
fillZeros(val.getUTCDate()) + ' ' +
314-
fillZeros(val.getUTCHours()) + ':' +
315-
fillZeros(val.getUTCMinutes()) + ':' +
316-
fillZeros(val.getUTCSeconds());
317-
318-
function fillZeros(v) {
319-
return v < 10 ? '0' + v : v;
320-
}
321-
}
322-
323317
MySQL.prototype.getInsertedId = function(model, info) {
324318
var insertedId = info && typeof info.insertId === 'number' ?
325319
info.insertId : undefined;
@@ -356,7 +350,10 @@ MySQL.prototype.toColumnValue = function(prop, val) {
356350
if (!val.toUTCString) {
357351
val = new Date(val);
358352
}
359-
return dateToMysql(val);
353+
return val;
354+
}
355+
if (prop.type.name === 'DateString') {
356+
return val.when;
360357
}
361358
if (prop.type === Boolean) {
362359
return !!val;
@@ -411,14 +408,12 @@ MySQL.prototype.fromColumnValue = function(prop, val) {
411408
val = String(val);
412409
break;
413410
case 'Date':
414-
411+
case 'DateString':
415412
// MySQL allows, unless NO_ZERO_DATE is set, dummy date/time entries
416413
// new Date() will return Invalid Date for those, so we need to handle
417414
// those separate.
418-
if (val == '0000-00-00 00:00:00') {
415+
if (!val || val == '0000-00-00 00:00:00' || val == '0000-00-00') {
419416
val = null;
420-
} else {
421-
val = new Date(val.toString().replace(/GMT.*$/, 'GMT'));
422417
}
423418
break;
424419
case 'Boolean':

test/datetime.test.js

+95
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
// Copyright IBM Corp. 2012,2017. All Rights Reserved.
2+
// Node module: loopback-connector-mysql
3+
// This file is licensed under the MIT License.
4+
// License text available at https://opensource.org/licenses/MIT
5+
6+
'use strict';
7+
8+
var DateString = require('../node_modules/loopback-datasource-juggler/lib/date-string');
9+
var fmt = require('util').format;
10+
var should = require('./init.js');
11+
12+
var db, Person;
13+
describe('MySQL datetime handling', function() {
14+
var personDefinition = {
15+
name: String,
16+
gender: String,
17+
married: Boolean,
18+
dob: {type: 'DateString'},
19+
createdAt: {type: Date, default: Date},
20+
};
21+
22+
// Modifying the connection timezones mid-flight is a pain,
23+
// but closing the existing connection requires more effort.
24+
function setConnectionTimezones(tz) {
25+
db.connector.client._allConnections.forEach(function(con) {
26+
con.config.timezone = tz;
27+
});
28+
}
29+
before(function(done) {
30+
db = getSchema({
31+
dateStrings: true,
32+
});
33+
Person = db.define('Person', personDefinition, {forceId: true, strict: true});
34+
db.automigrate(['Person'], done);
35+
});
36+
37+
beforeEach(function() {
38+
setConnectionTimezones('Z');
39+
});
40+
after(function(done) {
41+
Person.destroyAll(function(err) {
42+
db.disconnect(function() {
43+
return done(err);
44+
});
45+
});
46+
});
47+
48+
it('should allow use of DateStrings', function(done) {
49+
var d = new DateString('1971-06-22');
50+
return Person.create({
51+
name: 'Mr. Pink',
52+
gender: 'M',
53+
dob: d,
54+
createdAt: new Date(),
55+
}).then(function(inst) {
56+
return Person.findById(inst.id);
57+
}).then(function(inst) {
58+
inst.should.not.eql(null);
59+
inst.dob.toString().should.eql(d.toString());
60+
return done();
61+
}).catch(function(err) {
62+
return done(err);
63+
});
64+
});
65+
66+
describe('should allow use of alternate timezone settings', function() {
67+
var d = new Date('1971-06-22T00:00:00.000Z');
68+
testDateTime(d, '+04:00', '1971-06-22 04:00:00');
69+
testDateTime(d, '-04:00', '1971-06-21 20:00:00');
70+
testDateTime(d, '-11:00', '1971-06-21 13:00:00');
71+
testDateTime(d, '+12:00', '1971-06-22 12:00:00');
72+
73+
function testDateTime(date, tz, expected) {
74+
it(tz, function(done) {
75+
setConnectionTimezones(tz);
76+
db.settings.legacyUtcDateProcessing = false;
77+
db.settings.timezone = tz;
78+
var dt = new Date(date);
79+
return Person.create({
80+
name: 'Mr. Pink',
81+
gender: 'M',
82+
createdAt: dt,
83+
}).then(function(inst) {
84+
return Person.findById(inst.id);
85+
}).then(function(inst) {
86+
inst.should.not.eql(null);
87+
inst.createdAt.toString().should.eql(expected);
88+
return done();
89+
}).catch(function(err) {
90+
return done(err);
91+
});
92+
});
93+
}
94+
});
95+
});

0 commit comments

Comments
 (0)