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
|
// SERVER-9406: Allow ObjectId type to be treated as a date in date related expressions
(function() {
"use strict";
load('jstests/libs/dateutil.js');
const coll = db.server9406;
let testOpCount = 0;
coll.drop();
// Seed collection so that the pipeline will execute.
assert.commandWorked(coll.insert({}));
function makeObjectIdFromDate(dt) {
try {
return new ObjectId((dt.getTime() / 1000).toString(16) + "f000000000000000");
} catch (e) {
assert("Invalid date for conversion to Object Id: " + dt);
}
}
/**
* Helper for testing that 'op' on 'value' is the same for dates as equivalent ObjectIds
* 'value' is either a date value, or an object containing field 'date'.
*/
function testOp(op, value) {
testOpCount++;
let pipeline = [{$project: {_id: 0, result: {}}}];
pipeline[0].$project.result[op] = value;
let res1 = coll.aggregate(pipeline).toArray()[0];
if (value.date) {
value.date = makeObjectIdFromDate(value.date);
} else {
value = makeObjectIdFromDate(value);
}
pipeline[0].$project.result[op] = value;
let res2 = coll.aggregate(pipeline).toArray()[0];
assert.eq(res2.result, res1.result, tojson(pipeline));
}
testOp('$dateToString', {date: new Date("1980-12-31T23:59:59Z"), format: "%V-%G"});
testOp('$dateToString', {date: new Date("1980-12-31T23:59:59Z"), format: "%G-%V"});
const years = [
2002, // Starting and ending on Tuesday.
2014, // Starting and ending on Wednesday.
2015, // Starting and ending on Thursday.
2010, // Starting and ending on Friday.
2011, // Starting and ending on Saturday.
2006, // Starting and ending on Sunday.
1996, // Starting on Monday, ending on Tuesday.
2008, // Starting on Tuesday, ending on Wednesday.
1992, // Starting on Wednesday, ending on Thursday.
2004, // Starting on Thursday, ending on Friday.
2016, // Starting on Friday, ending on Saturday.
2000, // Starting on Saturday, ending on Sunday (special).
2012 // Starting on Sunday, ending on Monday.
];
const day = 1;
years.forEach(function(year) {
// forEach starts indexing at zero but weekdays start with Monday on 1 so we add +1.
let newYear = DateUtil.getNewYear(year);
let endOfFirstWeekInYear = DateUtil.getEndOfFirstWeekInYear(year, day);
let startOfSecondWeekInYear = DateUtil.getStartOfSecondWeekInYear(year, day);
let birthday = DateUtil.getBirthday(year);
let newYearsEve = DateUtil.getNewYearsEve(year);
let now = new Date();
now.setYear(year);
now.setMilliseconds(0);
testOp('$isoDayOfWeek', newYear);
testOp('$isoDayOfWeek', endOfFirstWeekInYear);
testOp('$isoDayOfWeek', startOfSecondWeekInYear);
testOp('$isoWeekYear', birthday);
testOp('$isoWeek', newYear);
testOp('$isoWeek', now);
testOp('$isoWeekYear', newYear);
testOp('$isoWeek', endOfFirstWeekInYear);
testOp('$dateToString', {format: '%G-W%V-%u', date: newYear});
testOp('$isoWeek', endOfFirstWeekInYear);
testOp('$year', endOfFirstWeekInYear);
testOp('$month', endOfFirstWeekInYear);
testOp('$dayOfMonth', endOfFirstWeekInYear);
testOp('$dayOfWeek', birthday);
testOp('$dayOfWeek', newYearsEve);
testOp('$minute', newYearsEve);
testOp('$second', now);
testOp('$millisecond', newYear);
});
assert.eq(testOpCount, 236, 'Expected 236 tests to run');
})();
|