@nxtedition/lib 23.2.0 → 23.2.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.
Files changed (3) hide show
  1. package/app.js +4 -2
  2. package/package.json +1 -1
  3. package/time.js +71 -16
package/app.js CHANGED
@@ -7,6 +7,7 @@ import cluster from 'node:cluster'
7
7
  import stream from 'node:stream'
8
8
  import { Buffer } from 'node:buffer'
9
9
  import { getDockerSecretsSync } from './docker-secrets.js'
10
+ import { getUTCRangeForLocalTime } from './time.js'
10
11
  import fp from 'lodash/fp.js'
11
12
  import {
12
13
  isMainThread,
@@ -135,11 +136,12 @@ export function makeApp(appConfig, onTerminate) {
135
136
  } (module:${serviceModule}; instance:${serviceInstanceId}) worker:${serviceWorkerId} Node/${process.version}`) ??
136
137
  null)
137
138
 
138
- const dailyOffpeakTime = config.dailyOffpeakTime ?? '00:00-04:00'
139
+ const dailyOffpeakTime = config.dailyOffpeakTime ?? getUTCRangeForLocalTime('00:00-04:00')
139
140
 
140
141
  if (dailyOffpeakTime) {
141
- const [start, end] = dailyOffpeakTime.split('-')
142
+ // TODO (fix): This is ugly...
142
143
 
144
+ const [start, end] = dailyOffpeakTime.split('-')
143
145
  let wasOffpeak = null
144
146
  setInterval(() => {
145
147
  if (isTimeBetween(new Date(), start, end)) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nxtedition/lib",
3
- "version": "23.2.0",
3
+ "version": "23.2.1",
4
4
  "license": "MIT",
5
5
  "author": "Robert Nagy <robert.nagy@boffins.se>",
6
6
  "type": "module",
package/time.js CHANGED
@@ -2,31 +2,86 @@ export function isTimeBetween(date, startTime, endTime) {
2
2
  const currentHours = date.getHours()
3
3
  const currentMinutes = date.getMinutes()
4
4
 
5
- let [startHours, startMinutes] = startTime?.split(':').map(Number) ?? [null, 0]
6
- let [endHours, endMinutes] = endTime?.split(':').map(Number) ?? [null, 0]
5
+ // Validate and parse start and end times
6
+ if (!startTime) startTime = '00:00' // Default start at midnight
7
+ if (!endTime) endTime = '23:59' // Default end at 23:59
7
8
 
8
- if (startHours == null) {
9
- startHours = -Number.MAX_SAFE_INTEGER
10
- }
9
+ const [startHours, startMinutes] = startTime.split(':').map(Number)
10
+ const [endHours, endMinutes] = endTime.split(':').map(Number)
11
11
 
12
- if (endHours == null) {
13
- endHours = Number.MAX_SAFE_INTEGER
12
+ // Ensure valid hour/minute values
13
+ if (
14
+ isNaN(startHours) ||
15
+ isNaN(startMinutes) ||
16
+ isNaN(endHours) ||
17
+ isNaN(endMinutes) ||
18
+ startHours < 0 ||
19
+ startHours > 23 ||
20
+ startMinutes < 0 ||
21
+ startMinutes > 59 ||
22
+ endHours < 0 ||
23
+ endHours > 23 ||
24
+ endMinutes < 0 ||
25
+ endMinutes > 59
26
+ ) {
27
+ throw new Error("Invalid time format. Use 'HH:MM'")
14
28
  }
15
29
 
16
30
  if (startHours < endHours || (startHours === endHours && startMinutes <= endMinutes)) {
17
- // The time range is within the same day
18
- return (currentHours > startHours ||
19
- (currentHours === startHours && currentMinutes >= startMinutes)) &&
31
+ // Case 1: The time range is within the same day
32
+ return (
33
+ (currentHours > startHours ||
34
+ (currentHours === startHours && currentMinutes >= startMinutes)) &&
20
35
  (currentHours < endHours || (currentHours === endHours && currentMinutes <= endMinutes))
21
- ? { currentHours, currentMinutes, startHours, startMinutes, endHours, endMinutes }
22
- : null
36
+ )
23
37
  } else {
24
- // The time range spans across two days
25
- return currentHours > startHours ||
38
+ // Case 2: The time range spans across midnight
39
+ return (
40
+ currentHours > startHours ||
26
41
  (currentHours === startHours && currentMinutes >= startMinutes) ||
27
42
  currentHours < endHours ||
28
43
  (currentHours === endHours && currentMinutes <= endMinutes)
29
- ? { currentHours, currentMinutes, startHours, startMinutes, endHours, endMinutes }
30
- : null
44
+ )
45
+ }
46
+ }
47
+
48
+ export function getUTCRangeForLocalTime(range) {
49
+ // Validate input format (hh:mm-hh:mm)
50
+ const timeFormat = /^\d{2}:\d{2}-\d{2}:\d{2}$/
51
+ if (!timeFormat.test(range)) {
52
+ throw new Error("Invalid format. Use 'hh:mm-hh:mm' (e.g., '01:00-05:00').")
53
+ }
54
+
55
+ const [startTime, endTime] = range.split('-')
56
+ const [startHour, startMinute] = startTime.split(':').map(Number)
57
+ const [endHour, endMinute] = endTime.split(':').map(Number)
58
+
59
+ // Validate time values
60
+ if (
61
+ startHour < 0 ||
62
+ startHour > 23 ||
63
+ startMinute < 0 ||
64
+ startMinute > 59 ||
65
+ endHour < 0 ||
66
+ endHour > 23 ||
67
+ endMinute < 0 ||
68
+ endMinute > 59
69
+ ) {
70
+ throw new Error('Invalid time values. Hours must be 00-23 and minutes 00-59.')
31
71
  }
72
+
73
+ const now = new Date()
74
+
75
+ // Create local Date objects
76
+ const start = new Date(now)
77
+ start.setHours(startHour, startMinute, 0, 0)
78
+
79
+ const end = new Date(now)
80
+ end.setHours(endHour, endMinute, 0, 0)
81
+
82
+ // Convert to UTC
83
+ const startUTC = `${String(start.getUTCHours()).padStart(2, '0')}:${String(start.getUTCMinutes()).padStart(2, '0')}`
84
+ const endUTC = `${String(end.getUTCHours()).padStart(2, '0')}:${String(end.getUTCMinutes()).padStart(2, '0')}`
85
+
86
+ return `${startUTC}-${endUTC}`
32
87
  }