@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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tim-code/my-util",
3
- "version": "0.0.5",
3
+ "version": "0.0.6",
4
4
  "description": "",
5
5
  "type": "module",
6
6
  "author": "",
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 {number} $1.days An offset in days to the current time
7
- * @param {boolean} $1.floorMinute If true, floors to the nearest minute. If false, floors to the nearest second.
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({ days = 0, floorMinute = false } = {}) {
11
- const now = new Date()
12
- if (days) {
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
- const timestamp = floorMinute
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("adds days offset", () => {
22
- const today = getEasternTime()
23
- const tomorrow = getEasternTime({ days: 1 })
24
- const [y, m, d] = today.date.split("-").map(Number)
25
- const [y2, m2, d2] = tomorrow.date.split("-").map(Number)
26
- expect(new Date(y2, m2 - 1, d2).getTime() - new Date(y, m - 1, d).getTime()).toBeCloseTo(
27
- 24 * 60 * 60 * 1000,
28
- -2
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({ days: 0, floorMinute: false })
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
+ })