dce-reactkit 4.2.4-beta-timestamp.2 → 4.2.4-beta.heat-seek.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/index.js +100 -63
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/types/helpers/getTimestampFromTimeInfoInET.d.ts +1 -1
- package/dist/esm/index.js +100 -63
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/types/helpers/getTimestampFromTimeInfoInET.d.ts +1 -1
- package/dist/index.d.ts +1 -1
- package/package.json +1 -1
- package/src/helpers/getTimestampFromTimeInfoInET.ts +123 -69
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* @param opts.month Month (1-12)
|
|
8
8
|
* @param opts.day Day of the month (1-31)
|
|
9
9
|
* @param opts.hour Hour (0-23)
|
|
10
|
-
* @param opts.minute Minute (0-59)
|
|
10
|
+
* @param opts.minute Minute (0-59)
|
|
11
11
|
* @returns Timestamp in milliseconds since epoch
|
|
12
12
|
*/
|
|
13
13
|
declare const getTimestampFromTimeInfoInET: (opts: {
|
package/dist/index.d.ts
CHANGED
|
@@ -1574,7 +1574,7 @@ declare const cloneDeep: <T>(obj: T) => T;
|
|
|
1574
1574
|
* @param opts.month Month (1-12)
|
|
1575
1575
|
* @param opts.day Day of the month (1-31)
|
|
1576
1576
|
* @param opts.hour Hour (0-23)
|
|
1577
|
-
* @param opts.minute Minute (0-59)
|
|
1577
|
+
* @param opts.minute Minute (0-59)
|
|
1578
1578
|
* @returns Timestamp in milliseconds since epoch
|
|
1579
1579
|
*/
|
|
1580
1580
|
declare const getTimestampFromTimeInfoInET: (opts: {
|
package/package.json
CHANGED
|
@@ -6,6 +6,78 @@ import ReactKitErrorCode from '../types/ReactKitErrorCode';
|
|
|
6
6
|
import getTimeInfoInET from './getTimeInfoInET';
|
|
7
7
|
import padZerosLeft from './padZerosLeft';
|
|
8
8
|
|
|
9
|
+
/*----------------------------------------*/
|
|
10
|
+
/* --------------- Helpers -------------- */
|
|
11
|
+
/*----------------------------------------*/
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Check if a timestamp is valid
|
|
15
|
+
* @param opts object containing all arguments
|
|
16
|
+
* @param opts.timestamp Timestamp in milliseconds since epoch
|
|
17
|
+
* @param opts.expectedYear Expected year
|
|
18
|
+
* @param opts.expectedMonth Expected month
|
|
19
|
+
* @param opts.expectedDay Expected day
|
|
20
|
+
* @param opts.expectedHour Expected hour
|
|
21
|
+
* @param opts.expectedMinute Expected minute
|
|
22
|
+
* @returns 1 if the timestamp needs to be increased, -1 if it needs to be decreased, 0 if it is valid
|
|
23
|
+
*/
|
|
24
|
+
const checkTimestamp = (
|
|
25
|
+
opts: {
|
|
26
|
+
timestamp: number,
|
|
27
|
+
expectedYear: number,
|
|
28
|
+
expectedMonth: number,
|
|
29
|
+
expectedDay: number,
|
|
30
|
+
expectedHour: number,
|
|
31
|
+
expectedMinute: number,
|
|
32
|
+
},
|
|
33
|
+
): number => {
|
|
34
|
+
const {
|
|
35
|
+
timestamp,
|
|
36
|
+
expectedYear,
|
|
37
|
+
expectedMonth,
|
|
38
|
+
expectedDay,
|
|
39
|
+
expectedHour,
|
|
40
|
+
expectedMinute,
|
|
41
|
+
} = opts;
|
|
42
|
+
|
|
43
|
+
const timeInfoInET = getTimeInfoInET(timestamp);
|
|
44
|
+
if (timeInfoInET.year < expectedYear) {
|
|
45
|
+
return 1;
|
|
46
|
+
}
|
|
47
|
+
if (timeInfoInET.year > expectedYear) {
|
|
48
|
+
return -1;
|
|
49
|
+
}
|
|
50
|
+
if (timeInfoInET.month < expectedMonth) {
|
|
51
|
+
return 1;
|
|
52
|
+
}
|
|
53
|
+
if (timeInfoInET.month > expectedMonth) {
|
|
54
|
+
return -1;
|
|
55
|
+
}
|
|
56
|
+
if (timeInfoInET.day < expectedDay) {
|
|
57
|
+
return 1;
|
|
58
|
+
}
|
|
59
|
+
if (timeInfoInET.day > expectedDay) {
|
|
60
|
+
return -1;
|
|
61
|
+
}
|
|
62
|
+
if (timeInfoInET.hour < expectedHour) {
|
|
63
|
+
return 1;
|
|
64
|
+
}
|
|
65
|
+
if (timeInfoInET.hour > expectedHour) {
|
|
66
|
+
return -1;
|
|
67
|
+
}
|
|
68
|
+
if (timeInfoInET.minute < expectedMinute) {
|
|
69
|
+
return 1;
|
|
70
|
+
}
|
|
71
|
+
if (timeInfoInET.minute > expectedMinute) {
|
|
72
|
+
return -1;
|
|
73
|
+
}
|
|
74
|
+
return 0;
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
/*----------------------------------------*/
|
|
78
|
+
/* ---------------- Main ---------------- */
|
|
79
|
+
/*----------------------------------------*/
|
|
80
|
+
|
|
9
81
|
/**
|
|
10
82
|
* Get a timestamp (ms since epoch) from time info (year, month, day, hour, minute, etc.) in Eastern Time (ET)
|
|
11
83
|
* @author Gardenia Liu
|
|
@@ -15,7 +87,7 @@ import padZerosLeft from './padZerosLeft';
|
|
|
15
87
|
* @param opts.month Month (1-12)
|
|
16
88
|
* @param opts.day Day of the month (1-31)
|
|
17
89
|
* @param opts.hour Hour (0-23)
|
|
18
|
-
* @param opts.minute Minute (0-59)
|
|
90
|
+
* @param opts.minute Minute (0-59)
|
|
19
91
|
* @returns Timestamp in milliseconds since epoch
|
|
20
92
|
*/
|
|
21
93
|
const getTimestampFromTimeInfoInET = (
|
|
@@ -36,87 +108,69 @@ const getTimestampFromTimeInfoInET = (
|
|
|
36
108
|
minute,
|
|
37
109
|
} = opts;
|
|
38
110
|
|
|
111
|
+
// Determine if the date is in DST in Eastern Time
|
|
112
|
+
const tempDate = new Date(year, month - 1, day);
|
|
113
|
+
const janOffset = new Date(year, 0, 1).getTimezoneOffset();
|
|
114
|
+
const isDST = tempDate.getTimezoneOffset() < janOffset;
|
|
115
|
+
const etOffset = isDST ? '-04:00' : '-05:00';
|
|
116
|
+
|
|
39
117
|
// Format with leading zeroes
|
|
40
118
|
const mm = padZerosLeft(month, 2);
|
|
41
119
|
const dd = padZerosLeft(day, 2);
|
|
42
120
|
const hh = padZerosLeft(hour, 2);
|
|
43
121
|
const min = padZerosLeft(minute, 2);
|
|
44
122
|
|
|
45
|
-
//
|
|
46
|
-
const
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
return
|
|
64
|
-
})?.value;
|
|
65
|
-
const etDay: string | undefined = parts.find((p: Intl.DateTimeFormatPart) => {
|
|
66
|
-
return p.type === 'day';
|
|
67
|
-
})?.value;
|
|
68
|
-
const etHour: string | undefined = parts.find((p: Intl.DateTimeFormatPart) => {
|
|
69
|
-
return p.type === 'hour';
|
|
70
|
-
})?.value;
|
|
71
|
-
const etMinute: string | undefined = parts.find((p: Intl.DateTimeFormatPart) => {
|
|
72
|
-
return p.type === 'minute';
|
|
73
|
-
})?.value;
|
|
74
|
-
const etSecond: string | undefined = parts.find((p: Intl.DateTimeFormatPart) => {
|
|
75
|
-
return p.type === 'second';
|
|
76
|
-
})?.value;
|
|
77
|
-
const tzName: string | undefined = parts.find((p: Intl.DateTimeFormatPart) => {
|
|
78
|
-
return p.type === 'timeZoneName';
|
|
79
|
-
})?.value;
|
|
80
|
-
|
|
81
|
-
// Validate we got everything we need
|
|
82
|
-
if (!etYear || !etMonth || !etDay || !etHour || !etMinute || !etSecond || !tzName) {
|
|
83
|
-
throw new ErrorWithCode(
|
|
84
|
-
'Failed to parse date parts from Intl.DateTimeFormat',
|
|
85
|
-
ReactKitErrorCode.ETTimestampInvalid,
|
|
86
|
-
);
|
|
123
|
+
// Build ET ISO string and convert to UTC timestamp
|
|
124
|
+
const etISOString = `${year}-${mm}-${dd}T${hh}:${min}:00${etOffset}`;
|
|
125
|
+
let timestamp = (new Date(etISOString)).getTime();
|
|
126
|
+
|
|
127
|
+
// Heat seek to get the right timestamp
|
|
128
|
+
const maxOffset = 24 * 60; // 24 hours in minutes
|
|
129
|
+
let currentOffset = 0; // minutes
|
|
130
|
+
const offsetIncrement = 15; // minutes
|
|
131
|
+
const offsetDirection = checkTimestamp({
|
|
132
|
+
timestamp,
|
|
133
|
+
expectedYear: year,
|
|
134
|
+
expectedMonth: month,
|
|
135
|
+
expectedDay: day,
|
|
136
|
+
expectedHour: hour,
|
|
137
|
+
expectedMinute: minute,
|
|
138
|
+
});
|
|
139
|
+
if (offsetDirection === 0) {
|
|
140
|
+
// Valid! Return the timestamp
|
|
141
|
+
return timestamp;
|
|
87
142
|
}
|
|
88
143
|
|
|
89
|
-
//
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
144
|
+
// Heat seek
|
|
145
|
+
while (Math.abs(currentOffset) < maxOffset) {
|
|
146
|
+
// Update offset
|
|
147
|
+
currentOffset += (offsetDirection * offsetIncrement);
|
|
93
148
|
|
|
94
|
-
|
|
95
|
-
|
|
149
|
+
// Update timestamp
|
|
150
|
+
const offsetMs = currentOffset * 60 * 1000;
|
|
151
|
+
timestamp += offsetMs;
|
|
96
152
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
153
|
+
// Check timestamp again
|
|
154
|
+
const newDirection = checkTimestamp({
|
|
155
|
+
timestamp,
|
|
156
|
+
expectedYear: year,
|
|
157
|
+
expectedMonth: month,
|
|
158
|
+
expectedDay: day,
|
|
159
|
+
expectedHour: hour,
|
|
160
|
+
expectedMinute: minute,
|
|
161
|
+
});
|
|
162
|
+
if (newDirection === 0) {
|
|
163
|
+
// Valid! Return the timestamp
|
|
164
|
+
return timestamp;
|
|
165
|
+
}
|
|
100
166
|
|
|
101
|
-
|
|
102
|
-
const timeInfoInET = getTimeInfoInET(timestamp);
|
|
103
|
-
if (
|
|
104
|
-
timeInfoInET.year !== year
|
|
105
|
-
|| timeInfoInET.month !== month
|
|
106
|
-
|| timeInfoInET.day !== day
|
|
107
|
-
|| timeInfoInET.hour !== hour
|
|
108
|
-
|| timeInfoInET.minute !== minute
|
|
109
|
-
) {
|
|
110
|
-
throw new ErrorWithCode(
|
|
111
|
-
`Timestamp mismatch: expected ${year}-${mm}-${dd} ${hh}:${min}, `
|
|
112
|
-
+ `got ${timeInfoInET.year}-${padZerosLeft(timeInfoInET.month, 2)}-${padZerosLeft(timeInfoInET.day, 2)} `
|
|
113
|
-
+ `${padZerosLeft(timeInfoInET.hour, 2)}:${padZerosLeft(timeInfoInET.minute, 2)}`,
|
|
114
|
-
ReactKitErrorCode.ETTimestampInvalid,
|
|
115
|
-
);
|
|
167
|
+
// Invalid. Keep looping.
|
|
116
168
|
}
|
|
117
169
|
|
|
118
|
-
|
|
119
|
-
|
|
170
|
+
throw new ErrorWithCode(
|
|
171
|
+
`Timestamp mismatch: expected ${year}-${mm}-${dd} ${hh}:${min}, seeked to offset ${currentOffset} minutes but could not find a valid timestamp.`,
|
|
172
|
+
ReactKitErrorCode.ETTimestampInvalid,
|
|
173
|
+
);
|
|
120
174
|
};
|
|
121
175
|
|
|
122
176
|
export default getTimestampFromTimeInfoInET;
|