-
Notifications
You must be signed in to change notification settings - Fork 29
Expand file tree
/
Copy pathconvert.js
More file actions
114 lines (104 loc) · 3.53 KB
/
convert.js
File metadata and controls
114 lines (104 loc) · 3.53 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
import { getUnixTimeFromUTC, getDateFromTime, getUTCTime, getLocalTime, getDateTime } from './utc-date'
function findTransitionIndex (unixTime, timeZone) {
const { untils } = timeZone
for (let i = 0, length = untils.length; i < length; ++i) {
if (unixTime < untils[i]) {
return i
}
}
}
function getTransition (unixTime, timeZone) {
const transitionIndex = findTransitionIndex(unixTime, timeZone)
const abbreviation = timeZone.abbreviations[transitionIndex]
const offset = timeZone.offsets[transitionIndex]
return { abbreviation, offset }
}
function attachEpoch (time, unixTime) {
Object.defineProperty(time, 'epoch', { value: unixTime })
}
function getUTCOffset (date, timeZone) {
const unixTime = typeof date === 'number' ? date : date.getTime()
const { abbreviation, offset } = getTransition(unixTime, timeZone)
return { abbreviation, offset }
}
function getZonedTime (date, timeZone) {
const gotUnixTime = typeof date === 'number'
const unixTime = gotUnixTime ? date : date.getTime()
const { abbreviation, offset } = getTransition(unixTime, timeZone)
if (gotUnixTime || offset) {
date = new Date(unixTime - offset * 60000)
}
const time = getUTCTime(date)
time.zone = { abbreviation, offset }
attachEpoch(time, unixTime)
return time
}
function getUnixTime (time, timeZone) {
let { zone, epoch } = time
if (epoch) {
if (timeZone) {
throw new Error('Both epoch and other time zone specified. Omit the other one.')
}
return epoch
}
const unixTime = getUnixTimeFromUTC(time)
let convertedUnixTime;
if (zone) {
if (timeZone) {
throw new Error('Both own and other time zones specified. Omit the other one.')
}
convertedUnixTime = unixTime + zone.offset * 60000
} else {
if (!timeZone) {
throw new Error('Missing other time zone.')
}
zone = getTransition(unixTime, timeZone)
convertedUnixTime = unixTime + zone.offset * 60000
const convertedZoneOffset = getTransition(convertedUnixTime, timeZone).offset
// check if the converted date may have moved to a different offset (probably because of a DST switch)
if (convertedZoneOffset !== zone.offset) {
convertedUnixTime = unixTime + convertedZoneOffset * 60000
}
}
return convertedUnixTime
}
function setTimeZone (time, timeZone, options) {
if (time instanceof Date) {
time = getDateTime(time, options)
} else {
const { year, month, day, hours, minutes, seconds = 0, milliseconds = 0 } = time
time = { year, month, day, hours, minutes, seconds, milliseconds }
}
const unixTime = getUnixTimeFromUTC(time)
const utcDate = new Date(unixTime)
time.dayOfWeek = utcDate.getUTCDay()
const { abbreviation, offset } = getTransition(unixTime, timeZone)
time.zone = { abbreviation, offset }
attachEpoch(time, unixTime + offset * 60000)
return time
}
function convertTimeToDate (time) {
const { epoch } = time
if (epoch !== undefined) {
return new Date(epoch)
}
const { offset } = time.zone || {}
if (offset === undefined) {
return getDateFromTime(time)
}
const unixTime = getUnixTimeFromUTC(time)
return new Date(unixTime + offset * 60000)
}
function convertDateToTime (date) {
const time = getLocalTime(date)
const match = /\(([^)]+)\)$/.exec(date.toTimeString())
time.zone = {
abbreviation: match ? match[1]
// istanbul ignore next
: '???',
offset: date.getTimezoneOffset()
}
attachEpoch(time, date.getTime())
return time
}
export { getUTCOffset, getZonedTime, getUnixTime, setTimeZone, convertTimeToDate, convertDateToTime }