-
Notifications
You must be signed in to change notification settings - Fork 7k
/
start-end-of.js
135 lines (123 loc) · 4.2 KB
/
start-end-of.js
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
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
import { normalizeUnits } from '../units/aliases';
export function startOf (units) {
var initialDate = this.date(),
checkForDST = true,
hour, clone;
units = normalizeUnits(units);
// in week/isoWeek operations, jump to noon to make sure that we do not hit DST bugs when
// switching the weekday/isoWeekday and can collect a valid initialDate to use for comparison
// after the time is adjusted
if (units === 'week' || units === 'isoWeek') {
this.hours(12);
}
// the following switch intentionally omits break keywords
// to utilize falling through the cases.
switch (units) {
case 'year':
this.month(0);
/* falls through */
case 'quarter':
// quarters is a special case
if (units === 'quarter') {
this.month(Math.floor(this.month() / 3) * 3);
}
/* falls through */
case 'month':
this.date(1);
// for month/quarter/year changes, no DST can interfere so we do not check for it
checkForDST = false;
/* falls through */
case 'week':
case 'isoWeek':
// weeks are a special case
if (units === 'week') {
this.weekday(0);
initialDate = this.date();
}
if (units === 'isoWeek') {
this.isoWeekday(1);
initialDate = this.date();
}
/* falls through */
case 'day':
case 'date':
this.hours(0);
/* falls through */
case 'hour':
this.minutes(0);
/* falls through */
case 'minute':
this.seconds(0);
/* falls through */
case 'second':
this.milliseconds(0);
}
// check if day of month changed when setting the time
if (checkForDST && this.date() !== initialDate) {
// note: DST adjustments are assumed to occur in multiples of 1 hour (this is almost always the case)
// refer to http://www.timeanddate.com/time/aboutdst.html for the (rare) exceptions to this rule
// depending on JS implementations, the time can jump 1day ahead or be in the past
if (this.date() > initialDate) {
this.date(initialDate);
} else {
// increment hour until cloned date == current date
hour = 1;
do {
clone = this.clone().add(hour++, 'hour');
} while (clone.date() < initialDate);
this.date(initialDate);
this.hours(clone.hours());
}
}
return this;
}
export function endOf (units) {
units = normalizeUnits(units);
if (units === undefined || units === 'millisecond') {
return this;
}
// in week/isoWeek operations, jump to noon to make sure that we do not hit DST bugs when
// switching the weekday/isoWeekday
if (units === 'week' || units === 'isoWeek') {
this.hours(12);
}
// the following switch intentionally omits break keywords
// to utilize falling through the cases.
switch (units) {
case 'year':
this.month(11);
/* falls through */
case 'quarter':
// quarters is a special case
if (units === 'quarter') {
this.month((Math.floor(this.month() / 3) * 3) + 2);
}
/* falls through */
case 'month':
this.date(this.month() === 1 ? 28 : ([0, 2, 4, 6, 7, 9, 11].indexOf(this.month()) === -1 ? 30 : 31));
/* falls through */
case 'week':
case 'isoWeek':
// weeks are a special case
if (units === 'week') {
this.weekday(6);
}
if (units === 'isoWeek') {
this.isoWeekday(7);
}
/* falls through */
case 'day':
case 'date':
this.hours(23);
/* falls through */
case 'hour':
this.minutes(59);
/* falls through */
case 'minute':
this.seconds(59);
/* falls through */
case 'second':
this.milliseconds(999);
}
return this;
}