Skip to content
This repository has been archived by the owner on Jul 5, 2023. It is now read-only.

Commit

Permalink
Don’t trust JavaScript with your dates.
Browse files Browse the repository at this point in the history
Thirteen years past y2k, and JavaScript is still dumb about years less than 100 :-/

See #130
  • Loading branch information
bobthecow committed Aug 11, 2013
1 parent 4c164cb commit 936b6de
Show file tree
Hide file tree
Showing 4 changed files with 34 additions and 48 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG.markdown
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
## v2.3.8

* [Fix #130][i130] — Resolve bug creating or editing `ISODate` instances with years between 1 and 99.

[i130]: https://github.com/bobthecow/genghis/issues/130


## v2.3.7

* [Fix #126][i126] — Resolve bug editing non-ObjectId `_id` in Ruby 1.8.7.
Expand Down
4 changes: 2 additions & 2 deletions genghis.php

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion genghis.rb

Large diffs are not rendered by default.

69 changes: 24 additions & 45 deletions src/js/genghis/json.js
Original file line number Diff line number Diff line change
Expand Up @@ -59,16 +59,31 @@ Genghis.JSON = {
};
}

function GenghisDate(date) {
function ISODateString(d){
function pad(n){return n < 10 ? '0' + n : n}
function ISODate(date) {
function ISODateString(d) {
function pad(n, l) {
l = l || 2;
return (new Array(l + 1).join('0') + n).substr(0 - l);
}

function msString(ms) {
return ms ? ('.' + pad(ms, 3)) : '';
}

d = new Date(d);
return d.getUTCFullYear()+'-'
+ pad(d.getUTCMonth()+1)+'-'
+ pad(d.getUTCDate())+'T'
+ pad(d.getUTCHours())+':'
+ pad(d.getUTCMinutes())+':'
+ pad(d.getUTCSeconds())+'Z'

if (typeof d.toISOString === 'function') {
// Cheat code for ES5
return d.toISOString();
} else {
return pad(d.getUTCFullYear(), 4)+'-'
+ pad(d.getUTCMonth()+1)+'-'
+ pad(d.getUTCDate())+'T'
+ pad(d.getUTCHours())+':'
+ pad(d.getUTCMinutes())+':'
+ pad(d.getUTCSeconds())
+ msString(d.getUTCMilliseconds())+'Z';
}
}

return {
Expand All @@ -77,42 +92,6 @@ Genghis.JSON = {
};
}

function ISODate(date) {
if (!date) {
return new GenghisDate();
}

var pattern = /(\d{4})-?(\d{2})-?(\d{2})([T ](\d{2})(:?(\d{2})(:?(\d{2}(\.\d+)?))?)?(Z|([+\-])(\d{2}):?(\d{2})?)?)?/;
var matches = pattern.exec(date);

if (!matches) {
throw 'Invalid ISO date';
}

var year = parseInt(matches[1], 10) || 1970;
var month = (parseInt(matches[2], 10) || 1) - 1;
var day = parseInt(matches[3], 10) || 0;
var hour = parseInt(matches[5], 10) || 0;
var min = parseInt(matches[7], 10) || 0;
var sec = parseFloat(matches[9]) || 0;
var ms = Math.round((sec % 1) * 1000);
sec -= ms / 1000;

var timestamp = Date.UTC(year, month, day, hour, min, sec, ms);

if (matches[11] && matches[11] != 'Z') {
var offset = 0;
offset += (parseInt(matches[13], 10) || 0) * 60*60*1000; // hours
offset += (parseInt(matches[14], 10) || 0) * 60*1000; // mins
if (matches[12] == '+') // if ahead subtract
offset *= -1;

timestamp += offset;
}

return new GenghisDate(timestamp);
}

// DBRef isn't so much a custom type as it is a hash factory...
// we won't bother using a $genghisType for this one.
function DBRef(ref, id) {
Expand Down

0 comments on commit 936b6de

Please sign in to comment.