dce-reactkit 4.2.6 → 4.2.8-beta-timestamp.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.
@@ -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
@@ -1604,7 +1604,7 @@ declare const cloneDeep: <T>(obj: T) => T;
1604
1604
  * @param opts.month Month (1-12)
1605
1605
  * @param opts.day Day of the month (1-31)
1606
1606
  * @param opts.hour Hour (0-23)
1607
- * @param opts.minute Minute (0-59))
1607
+ * @param opts.minute Minute (0-59)
1608
1608
  * @returns Timestamp in milliseconds since epoch
1609
1609
  */
1610
1610
  declare const getTimestampFromTimeInfoInET: (opts: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dce-reactkit",
3
- "version": "4.2.6",
3
+ "version": "4.2.8-beta-timestamp.1",
4
4
  "description": "Shared components for Harvard DCE apps",
5
5
  "main": "dist/cjs/index.js",
6
6
  "module": "dist/esm/index.js",
@@ -6,6 +6,80 @@ 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
+ * @author Gabe Abrams
16
+ * @author Gardenia Liu
17
+ * @param opts object containing all arguments
18
+ * @param opts.timestamp Timestamp in milliseconds since epoch
19
+ * @param opts.expectedYear Expected year
20
+ * @param opts.expectedMonth Expected month
21
+ * @param opts.expectedDay Expected day
22
+ * @param opts.expectedHour Expected hour
23
+ * @param opts.expectedMinute Expected minute
24
+ * @returns 1 if the timestamp needs to be increased, -1 if it needs to be decreased, 0 if it is valid
25
+ */
26
+ const checkTimestamp = (
27
+ opts: {
28
+ timestamp: number,
29
+ expectedYear: number,
30
+ expectedMonth: number,
31
+ expectedDay: number,
32
+ expectedHour: number,
33
+ expectedMinute: number,
34
+ },
35
+ ): number => {
36
+ const {
37
+ timestamp,
38
+ expectedYear,
39
+ expectedMonth,
40
+ expectedDay,
41
+ expectedHour,
42
+ expectedMinute,
43
+ } = opts;
44
+
45
+ const timeInfoInET = getTimeInfoInET(timestamp);
46
+ if (timeInfoInET.year < expectedYear) {
47
+ return 1;
48
+ }
49
+ if (timeInfoInET.year > expectedYear) {
50
+ return -1;
51
+ }
52
+ if (timeInfoInET.month < expectedMonth) {
53
+ return 1;
54
+ }
55
+ if (timeInfoInET.month > expectedMonth) {
56
+ return -1;
57
+ }
58
+ if (timeInfoInET.day < expectedDay) {
59
+ return 1;
60
+ }
61
+ if (timeInfoInET.day > expectedDay) {
62
+ return -1;
63
+ }
64
+ if (timeInfoInET.hour < expectedHour) {
65
+ return 1;
66
+ }
67
+ if (timeInfoInET.hour > expectedHour) {
68
+ return -1;
69
+ }
70
+ if (timeInfoInET.minute < expectedMinute) {
71
+ return 1;
72
+ }
73
+ if (timeInfoInET.minute > expectedMinute) {
74
+ return -1;
75
+ }
76
+ return 0;
77
+ };
78
+
79
+ /*----------------------------------------*/
80
+ /* ---------------- Main ---------------- */
81
+ /*----------------------------------------*/
82
+
9
83
  /**
10
84
  * Get a timestamp (ms since epoch) from time info (year, month, day, hour, minute, etc.) in Eastern Time (ET)
11
85
  * @author Gardenia Liu
@@ -15,7 +89,7 @@ import padZerosLeft from './padZerosLeft';
15
89
  * @param opts.month Month (1-12)
16
90
  * @param opts.day Day of the month (1-31)
17
91
  * @param opts.hour Hour (0-23)
18
- * @param opts.minute Minute (0-59))
92
+ * @param opts.minute Minute (0-59)
19
93
  * @returns Timestamp in milliseconds since epoch
20
94
  */
21
95
  const getTimestampFromTimeInfoInET = (
@@ -50,25 +124,56 @@ const getTimestampFromTimeInfoInET = (
50
124
 
51
125
  // Build ET ISO string and convert to UTC timestamp
52
126
  const etISOString = `${year}-${mm}-${dd}T${hh}:${min}:00${etOffset}`;
53
- const timestamp = (new Date(etISOString)).getTime();
127
+ const baseTimestamp = (new Date(etISOString)).getTime();
128
+ let timestamp = baseTimestamp;
54
129
 
55
- // Verify that the timestamp is correct
56
- const timeInfoInET = getTimeInfoInET(timestamp);
57
- if (
58
- timeInfoInET.year !== year
59
- || timeInfoInET.month !== month
60
- || timeInfoInET.day !== day
61
- || timeInfoInET.hour !== hour
62
- || timeInfoInET.minute !== minute
63
- ) {
64
- throw new ErrorWithCode(
65
- `Timestamp mismatch: expected ${year}-${mm}-${dd} ${hh}:${min}, got ${timeInfoInET.year}-${padZerosLeft(timeInfoInET.month, 2)}-${padZerosLeft(timeInfoInET.day, 2)} ${padZerosLeft(timeInfoInET.hour, 2)}:${padZerosLeft(timeInfoInET.minute, 2)}`,
66
- ReactKitErrorCode.ETTimestampInvalid,
67
- );
130
+ // Heat seek to get the right timestamp
131
+ const maxOffset = 24 * 60; // 24 hours in minutes
132
+ let currentOffset = 0; // minutes
133
+ const offsetIncrement = 15; // minutes
134
+ const offsetDirection = checkTimestamp({
135
+ timestamp,
136
+ expectedYear: year,
137
+ expectedMonth: month,
138
+ expectedDay: day,
139
+ expectedHour: hour,
140
+ expectedMinute: minute,
141
+ });
142
+ if (offsetDirection === 0) {
143
+ // Valid! Return the timestamp
144
+ return timestamp;
145
+ }
146
+
147
+ // Heat seek
148
+ while (Math.abs(currentOffset) < maxOffset) {
149
+ // Update offset
150
+ currentOffset += (offsetDirection * offsetIncrement);
151
+
152
+ // Update timestamp
153
+ const offsetMs = currentOffset * 60 * 1000;
154
+ timestamp = baseTimestamp + offsetMs;
155
+
156
+ // Check timestamp again
157
+ const newDirection = checkTimestamp({
158
+ timestamp,
159
+ expectedYear: year,
160
+ expectedMonth: month,
161
+ expectedDay: day,
162
+ expectedHour: hour,
163
+ expectedMinute: minute,
164
+ });
165
+ if (newDirection === 0) {
166
+ // Valid! Return the timestamp
167
+ return timestamp;
168
+ }
169
+
170
+ // Invalid. Keep looping.
68
171
  }
69
172
 
70
- // Valid! Return the timestamp
71
- return timestamp;
173
+ throw new ErrorWithCode(
174
+ `Timestamp mismatch: expected ${year}-${mm}-${dd} ${hh}:${min}, seeked to offset ${currentOffset} minutes but could not find a valid timestamp.`,
175
+ ReactKitErrorCode.ETTimestampInvalid,
176
+ );
72
177
  };
73
178
 
74
179
  export default getTimestampFromTimeInfoInET;