index.js
5.18 KB
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
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
import { MIN, MS } from '../../constant';
var typeToPos = {
year: 0,
month: 1,
day: 2,
hour: 3,
minute: 4,
second: 5
}; // Cache time-zone lookups from Intl.DateTimeFormat,
// as it is a *very* slow method.
var dtfCache = {};
var getDateTimeFormat = function getDateTimeFormat(timezone, options) {
if (options === void 0) {
options = {};
}
var timeZoneName = options.timeZoneName || 'short';
var key = timezone + "|" + timeZoneName;
var dtf = dtfCache[key];
if (!dtf) {
dtf = new Intl.DateTimeFormat('en-US', {
hour12: false,
timeZone: timezone,
year: 'numeric',
month: '2-digit',
day: '2-digit',
hour: '2-digit',
minute: '2-digit',
second: '2-digit',
timeZoneName: timeZoneName
});
dtfCache[key] = dtf;
}
return dtf;
};
export default (function (o, c, d) {
var defaultTimezone;
var localUtcOffset = d().utcOffset();
var makeFormatParts = function makeFormatParts(timestamp, timezone, options) {
if (options === void 0) {
options = {};
}
var date = new Date(timestamp);
var dtf = getDateTimeFormat(timezone, options);
return dtf.formatToParts(date);
};
var tzOffset = function tzOffset(timestamp, timezone) {
var formatResult = makeFormatParts(timestamp, timezone);
var filled = [];
for (var i = 0; i < formatResult.length; i += 1) {
var _formatResult$i = formatResult[i],
type = _formatResult$i.type,
value = _formatResult$i.value;
var pos = typeToPos[type];
if (pos >= 0) {
filled[pos] = parseInt(value, 10);
}
}
var hour = filled[3]; // Workaround for the same behavior in different node version
// https://github.com/nodejs/node/issues/33027
/* istanbul ignore next */
var fixedHour = hour === 24 ? 0 : hour;
var utcString = filled[0] + "-" + filled[1] + "-" + filled[2] + " " + fixedHour + ":" + filled[4] + ":" + filled[5] + ":000";
var utcTs = d.utc(utcString).valueOf();
var asTS = +timestamp;
var over = asTS % 1000;
asTS -= over;
return (utcTs - asTS) / (60 * 1000);
}; // find the right offset a given local time. The o input is our guess, which determines which
// offset we'll pick in ambiguous cases (e.g. there are two 3 AMs b/c Fallback DST)
// https://github.com/moment/luxon/blob/master/src/datetime.js#L76
var fixOffset = function fixOffset(localTS, o0, tz) {
// Our UTC time is just a guess because our offset is just a guess
var utcGuess = localTS - o0 * 60 * 1000; // Test whether the zone matches the offset for this ts
var o2 = tzOffset(utcGuess, tz); // If so, offset didn't change and we're done
if (o0 === o2) {
return [utcGuess, o0];
} // If not, change the ts by the difference in the offset
utcGuess -= (o2 - o0) * 60 * 1000; // If that gives us the local time we want, we're done
var o3 = tzOffset(utcGuess, tz);
if (o2 === o3) {
return [utcGuess, o2];
} // If it's different, we're in a hole time.
// The offset has changed, but the we don't adjust the time
return [localTS - Math.min(o2, o3) * 60 * 1000, Math.max(o2, o3)];
};
var proto = c.prototype;
proto.tz = function (timezone, keepLocalTime) {
if (timezone === void 0) {
timezone = defaultTimezone;
}
var oldOffset = this.utcOffset();
var target = this.toDate().toLocaleString('en-US', {
timeZone: timezone
});
var diff = Math.round((this.toDate() - new Date(target)) / 1000 / 60);
var ins = d(target).$set(MS, this.$ms).utcOffset(localUtcOffset - diff, true);
if (keepLocalTime) {
var newOffset = ins.utcOffset();
ins = ins.add(oldOffset - newOffset, MIN);
}
ins.$x.$timezone = timezone;
return ins;
};
proto.offsetName = function (type) {
// type: short(default) / long
var zone = this.$x.$timezone || d.tz.guess();
var result = makeFormatParts(this.valueOf(), zone, {
timeZoneName: type
}).find(function (m) {
return m.type.toLowerCase() === 'timezonename';
});
return result && result.value;
};
var oldStartOf = proto.startOf;
proto.startOf = function (units, startOf) {
if (!this.$x || !this.$x.$timezone) {
return oldStartOf.call(this, units, startOf);
}
var withoutTz = d(this.format('YYYY-MM-DD HH:mm:ss:SSS'));
var startOfWithoutTz = oldStartOf.call(withoutTz, units, startOf);
return startOfWithoutTz.tz(this.$x.$timezone, true);
};
d.tz = function (input, arg1, arg2) {
var parseFormat = arg2 && arg1;
var timezone = arg2 || arg1 || defaultTimezone;
var previousOffset = tzOffset(+d(), timezone);
if (typeof input !== 'string') {
// timestamp number || js Date || Day.js
return d(input).tz(timezone);
}
var localTs = d.utc(input, parseFormat).valueOf();
var _fixOffset = fixOffset(localTs, previousOffset, timezone),
targetTs = _fixOffset[0],
targetOffset = _fixOffset[1];
var ins = d(targetTs).utcOffset(targetOffset);
ins.$x.$timezone = timezone;
return ins;
};
d.tz.guess = function () {
return Intl.DateTimeFormat().resolvedOptions().timeZone;
};
d.tz.setDefault = function (timezone) {
defaultTimezone = timezone;
};
});