@tim-code/my-util 0.0.5 → 0.0.6
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/package.json +1 -1
- package/src/time.js +19 -9
- package/src/time.test.js +104 -19
package/package.json
CHANGED
package/src/time.js
CHANGED
|
@@ -3,18 +3,15 @@ import { mod } from "./math.js"
|
|
|
3
3
|
/**
|
|
4
4
|
* Gets various ways of representing the current time in EDT. Floors to nearest second by default.
|
|
5
5
|
* @param {Object} $1
|
|
6
|
-
* @param {
|
|
7
|
-
* @param {
|
|
6
|
+
* @param {boolean=} $1.floorMinute If true, floors to the nearest minute. If false, floors to the nearest second.
|
|
7
|
+
* @param {number=} $1.timestamp Unix timestamp to use instead of current time.
|
|
8
8
|
* @returns {Object} { timestamp, date, time, minute, datetime }
|
|
9
9
|
*/
|
|
10
|
-
export function getEasternTime({
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
now.setDate(now.getDate() + days)
|
|
10
|
+
export function getEasternTime({ floorMinute = false, timestamp = undefined } = {}) {
|
|
11
|
+
if (!timestamp) {
|
|
12
|
+
timestamp = new Date().getTime() / 1000
|
|
14
13
|
}
|
|
15
|
-
|
|
16
|
-
? Math.floor(now.getTime() / 1000 / 60) * 60
|
|
17
|
-
: Math.floor(now.getTime() / 1000)
|
|
14
|
+
timestamp = floorMinute ? Math.floor(timestamp / 60) * 60 : Math.floor(timestamp)
|
|
18
15
|
const string = new Date(timestamp * 1000).toLocaleString("en-US", {
|
|
19
16
|
timeZone: "America/New_York",
|
|
20
17
|
hour12: false,
|
|
@@ -99,3 +96,16 @@ export function addTime(timeString, { minutes = 0, hours = 0 }) {
|
|
|
99
96
|
.join(":")
|
|
100
97
|
return newTime
|
|
101
98
|
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Adds a number of days to a date string.
|
|
102
|
+
* @param {string} dateString
|
|
103
|
+
* @param {number} days
|
|
104
|
+
* @returns {string}
|
|
105
|
+
*/
|
|
106
|
+
export function addDays(dateString, days = 0) {
|
|
107
|
+
const [year, month, day] = dateString.split("-").map(Number)
|
|
108
|
+
const date = new Date(Date.UTC(year, month - 1, day))
|
|
109
|
+
date.setUTCDate(date.getUTCDate() + days)
|
|
110
|
+
return date.toISOString().slice(0, 10)
|
|
111
|
+
}
|
package/src/time.test.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { describe, expect, test } from "@jest/globals"
|
|
2
|
-
import { addTime, getEasternTime, isDate, isTime, isUnixTimestamp } from "./time.js"
|
|
2
|
+
import { addDays, addTime, getEasternTime, isDate, isTime, isUnixTimestamp } from "./time.js"
|
|
3
3
|
|
|
4
|
+
// getEasternTime changed: removed "days" param, added "timestamp" param
|
|
4
5
|
describe("getEasternTime", () => {
|
|
5
6
|
test("returns correct structure and types", () => {
|
|
6
7
|
const result = getEasternTime()
|
|
@@ -18,33 +19,66 @@ describe("getEasternTime", () => {
|
|
|
18
19
|
expect(r2.timestamp).toBeLessThanOrEqual(r1.timestamp)
|
|
19
20
|
})
|
|
20
21
|
|
|
21
|
-
test("
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
const
|
|
25
|
-
const
|
|
26
|
-
expect(
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
)
|
|
22
|
+
test("uses provided timestamp and floors correctly", () => {
|
|
23
|
+
// 2024-06-01T12:34:56Z (UTC) = 1717245296
|
|
24
|
+
// EDT is UTC-4, so local time should be 08:34:56
|
|
25
|
+
const ts = 1717245296
|
|
26
|
+
const result = getEasternTime({ timestamp: ts })
|
|
27
|
+
expect(result.timestamp).toBe(ts)
|
|
28
|
+
expect(result.time.startsWith("08:34")).toBe(true)
|
|
29
|
+
// floorMinute should zero out seconds
|
|
30
|
+
const floored = getEasternTime({ timestamp: ts, floorMinute: true })
|
|
31
|
+
expect(floored.timestamp % 60).toBe(0)
|
|
32
|
+
expect(floored.time.endsWith(":00")).toBe(true)
|
|
30
33
|
})
|
|
31
34
|
|
|
32
|
-
test("returns correct format for different days and floorMinute", () => {
|
|
33
|
-
const base = getEasternTime()
|
|
34
|
-
const plus2 = getEasternTime({ days: 2, floorMinute: true })
|
|
35
|
-
expect(plus2.date).not.toEqual(base.date)
|
|
36
|
-
expect(plus2.timestamp % 60).toBe(0)
|
|
37
|
-
})
|
|
38
|
-
|
|
39
|
-
// The following test ensures all code paths are covered, including when days=0 and floorMinute=false (the defaults).
|
|
40
35
|
test("default parameters yield consistent output", () => {
|
|
41
36
|
const def = getEasternTime()
|
|
42
|
-
const explicit = getEasternTime({
|
|
37
|
+
const explicit = getEasternTime({ floorMinute: false })
|
|
43
38
|
expect(def.date).toEqual(explicit.date)
|
|
44
39
|
expect(def.time).toEqual(explicit.time)
|
|
45
40
|
expect(def.timestamp).toEqual(explicit.timestamp)
|
|
46
41
|
expect(def.datetime).toEqual(explicit.datetime)
|
|
47
42
|
})
|
|
43
|
+
|
|
44
|
+
// DST boundary tests
|
|
45
|
+
test("handles DST start (spring forward) correctly", () => {
|
|
46
|
+
// In 2024, DST starts in US/Eastern at 2024-03-10 02:00:00 local time (clocks jump to 03:00:00)
|
|
47
|
+
// 2024-03-10T06:59:59Z = 1:59:59 EST (should be 01:59:59)
|
|
48
|
+
let ts = Date.UTC(2024, 2, 10, 6, 59, 59) / 1000
|
|
49
|
+
let r = getEasternTime({ timestamp: ts })
|
|
50
|
+
expect(r.date).toBe("2024-03-10")
|
|
51
|
+
expect(r.time).toBe("01:59:59")
|
|
52
|
+
// 2024-03-10T07:00:00Z = 3:00:00 EDT (should be 03:00:00)
|
|
53
|
+
ts = Date.UTC(2024, 2, 10, 7, 0, 0) / 1000
|
|
54
|
+
r = getEasternTime({ timestamp: ts })
|
|
55
|
+
expect(r.date).toBe("2024-03-10")
|
|
56
|
+
expect(r.time).toBe("03:00:00")
|
|
57
|
+
})
|
|
58
|
+
|
|
59
|
+
test("handles DST end (fall back) correctly", () => {
|
|
60
|
+
// In 2024, DST ends in US/Eastern at 2024-11-03 02:00:00 local time (clocks go back to 01:00:00)
|
|
61
|
+
// 2024-11-03T05:59:59Z = 01:59:59 EDT (should be 01:59:59)
|
|
62
|
+
let ts = Date.UTC(2024, 10, 3, 5, 59, 59) / 1000
|
|
63
|
+
let r = getEasternTime({ timestamp: ts })
|
|
64
|
+
expect(r.date).toBe("2024-11-03")
|
|
65
|
+
expect(r.time).toBe("01:59:59")
|
|
66
|
+
// 2024-11-03T06:00:00Z = 01:00:00 EST (should be 01:00:00)
|
|
67
|
+
ts = Date.UTC(2024, 10, 3, 6, 0, 0) / 1000
|
|
68
|
+
r = getEasternTime({ timestamp: ts })
|
|
69
|
+
expect(r.date).toBe("2024-11-03")
|
|
70
|
+
expect(r.time).toBe("01:00:00")
|
|
71
|
+
// 2024-11-03T06:59:59Z = 01:59:59 EST (should be 01:59:59)
|
|
72
|
+
ts = Date.UTC(2024, 10, 3, 6, 59, 59) / 1000
|
|
73
|
+
r = getEasternTime({ timestamp: ts })
|
|
74
|
+
expect(r.date).toBe("2024-11-03")
|
|
75
|
+
expect(r.time).toBe("01:59:59")
|
|
76
|
+
// 2024-11-03T07:00:00Z = 02:00:00 EST (should be 02:00:00)
|
|
77
|
+
ts = Date.UTC(2024, 10, 3, 7, 0, 0) / 1000
|
|
78
|
+
r = getEasternTime({ timestamp: ts })
|
|
79
|
+
expect(r.date).toBe("2024-11-03")
|
|
80
|
+
expect(r.time).toBe("02:00:00")
|
|
81
|
+
})
|
|
48
82
|
})
|
|
49
83
|
|
|
50
84
|
describe("isDate", () => {
|
|
@@ -179,3 +213,54 @@ describe("addTime", () => {
|
|
|
179
213
|
expect(addTime("00:00:00", { hours: 0, minutes: 0 })).toBe("00:00:00")
|
|
180
214
|
})
|
|
181
215
|
})
|
|
216
|
+
|
|
217
|
+
describe("addDays", () => {
|
|
218
|
+
test("adds days within the same month", () => {
|
|
219
|
+
expect(addDays("2024-06-01", 5)).toBe("2024-06-06")
|
|
220
|
+
expect(addDays("2024-06-10", 0)).toBe("2024-06-10")
|
|
221
|
+
})
|
|
222
|
+
|
|
223
|
+
test("adds days with month rollover", () => {
|
|
224
|
+
expect(addDays("2024-06-28", 5)).toBe("2024-07-03")
|
|
225
|
+
})
|
|
226
|
+
|
|
227
|
+
test("adds days with year rollover", () => {
|
|
228
|
+
expect(addDays("2024-12-30", 5)).toBe("2025-01-04")
|
|
229
|
+
})
|
|
230
|
+
|
|
231
|
+
test("subtracts days", () => {
|
|
232
|
+
expect(addDays("2024-06-10", -10)).toBe("2024-05-31")
|
|
233
|
+
})
|
|
234
|
+
|
|
235
|
+
test("handles leap years", () => {
|
|
236
|
+
expect(addDays("2024-02-28", 1)).toBe("2024-02-29")
|
|
237
|
+
expect(addDays("2024-02-28", 2)).toBe("2024-03-01")
|
|
238
|
+
expect(addDays("2023-02-28", 1)).toBe("2023-03-01")
|
|
239
|
+
})
|
|
240
|
+
|
|
241
|
+
test("handles negative result across year boundary", () => {
|
|
242
|
+
expect(addDays("2024-01-01", -1)).toBe("2023-12-31")
|
|
243
|
+
})
|
|
244
|
+
|
|
245
|
+
// DST boundary: adding days across US DST start (spring forward)
|
|
246
|
+
test("adds days across DST start (spring forward)", () => {
|
|
247
|
+
// DST starts in US/Eastern on 2024-03-10
|
|
248
|
+
// Adding 1 day to 2024-03-09 should yield 2024-03-10
|
|
249
|
+
expect(addDays("2024-03-09", 1)).toBe("2024-03-10")
|
|
250
|
+
// Adding 2 days to 2024-03-09 should yield 2024-03-11
|
|
251
|
+
expect(addDays("2024-03-09", 2)).toBe("2024-03-11")
|
|
252
|
+
// Subtracting 1 day from 2024-03-10 should yield 2024-03-09
|
|
253
|
+
expect(addDays("2024-03-10", -1)).toBe("2024-03-09")
|
|
254
|
+
})
|
|
255
|
+
|
|
256
|
+
// DST boundary: adding days across US DST end (fall back)
|
|
257
|
+
test("adds days across DST end (fall back)", () => {
|
|
258
|
+
// DST ends in US/Eastern on 2024-11-03
|
|
259
|
+
// Adding 1 day to 2024-11-02 should yield 2024-11-03
|
|
260
|
+
expect(addDays("2024-11-02", 1)).toBe("2024-11-03")
|
|
261
|
+
// Adding 2 days to 2024-11-02 should yield 2024-11-04
|
|
262
|
+
expect(addDays("2024-11-02", 2)).toBe("2024-11-04")
|
|
263
|
+
// Subtracting 1 day from 2024-11-03 should yield 2024-11-02
|
|
264
|
+
expect(addDays("2024-11-03", -1)).toBe("2024-11-02")
|
|
265
|
+
})
|
|
266
|
+
})
|