1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113
|
// server6189 - Support date operators with dates before 1970
c = db.c;
function test(date, testSynthetics) {
print("testing " + date);
c.drop();
c.save({date: date});
var ISOfmt = (date.getUTCMilliseconds() == 0) ? 'ISODate("%Y-%m-%dT%H:%M:%SZ")'
: 'ISODate("%Y-%m-%dT%H:%M:%S.%LZ")';
// Can't use aggregate helper or assertErrorCode because we need to handle multiple error types
var res = c.runCommand('aggregate',
{
pipeline: [{
$project: {
_id: 0,
year: {$year: '$date'},
month: {$month: '$date'},
dayOfMonth: {$dayOfMonth: '$date'},
hour: {$hour: '$date'},
minute: {$minute: '$date'},
second: {$second: '$date'}
// server-6666
,
millisecond: {$millisecond: '$date'}
// server-9289
,
millisecondPlusTen: {$millisecond: {$add: ['$date', 10]}}
// $substr will call coerceToString
,
string: {$substr: ['$date', 0, 1000]}
// server-11118
,
format: {$dateToString: {format: ISOfmt, date: '$date'}}
}
}]
});
if (date.valueOf() < 0 && _isWindows() && res.code == 16422) {
// some versions of windows (but not all) fail with dates before 1970
print("skipping test of " + date.tojson() + " because system doesn't support old dates");
return;
}
if (date.valueOf() / 1000 < -2 * 1024 * 1024 * 1024 && res.code == 16421) {
// we correctly detected that we are outside of the range of a 32-bit time_t
print("skipping test of " + date.tojson() + " because it is outside of time_t range");
return;
}
assert.commandWorked(res);
assert.eq(res.result[0],
{
year: date.getUTCFullYear(),
month: date.getUTCMonth() + 1 // jan == 1
,
dayOfMonth: date.getUTCDate(),
hour: date.getUTCHours(),
minute: date.getUTCMinutes(),
second: date.getUTCSeconds(),
millisecond: date.getUTCMilliseconds(),
millisecondPlusTen: ((date.getUTCMilliseconds() + 10) % 1000),
string: date.tojson().slice(9, 28),
format: date.tojson()
});
if (testSynthetics) {
// Tests with this set all have the same value for these fields
res = c.aggregate({
$project: {
_id: 0,
week: {$week: '$date'},
dayOfWeek: {$dayOfWeek: '$date'},
dayOfYear: {$dayOfYear: '$date'},
format: {$dateToString: {format: '%U-%w-%j', date: '$date'}}
}
});
assert.eq(res.toArray()[0], {week: 0, dayOfWeek: 7, dayOfYear: 2, format: '00-7-002'});
}
}
// Basic test
test(ISODate('1960-01-02 03:04:05.006Z'), true);
// Testing special rounding rules for seconds
test(ISODate('1960-01-02 03:04:04.999Z'), false); // second = 4
test(ISODate('1960-01-02 03:04:05.000Z'), true); // second = 5
test(ISODate('1960-01-02 03:04:05.001Z'), true); // second = 5
test(ISODate('1960-01-02 03:04:05.999Z'), true); // second = 5
// Test date before 1900 (negative tm_year values from gmtime)
test(ISODate('1860-01-02 03:04:05.006Z'), false);
// Test with time_t == -1 and 0
test(new Date(-1000), false);
test(new Date(0), false);
// Testing dates between 1970 and 2000
test(ISODate('1970-01-01 00:00:00.000Z'), false);
test(ISODate('1970-01-01 00:00:00.999Z'), false);
test(ISODate('1980-05-20 12:53:64.834Z'), false);
test(ISODate('1999-12-31 00:00:00.000Z'), false);
test(ISODate('1999-12-31 23:59:59.999Z'), false);
// Test date > 2000 for completeness (using now)
test(new Date(), false);
|