( browserLocale: string, time: string, tz: string, now: Date | undefined, )
| 244 | }; |
| 245 | |
| 246 | export const quietHoursDisplay = ( |
| 247 | browserLocale: string, |
| 248 | time: string, |
| 249 | tz: string, |
| 250 | now: Date | undefined, |
| 251 | ): string => { |
| 252 | if (!validTime(time)) { |
| 253 | return "Invalid time"; |
| 254 | } |
| 255 | |
| 256 | // The cron-parser package doesn't accept a timezone in the cron string, but |
| 257 | // accepts it as an option. |
| 258 | const cron = timeToCron(time); |
| 259 | const parsed = cronParser.parseExpression(cron, { |
| 260 | currentDate: now, |
| 261 | iterator: false, |
| 262 | utc: false, |
| 263 | tz, |
| 264 | }); |
| 265 | |
| 266 | const today = dayjs(now).tz(tz); |
| 267 | const day = dayjs(parsed.next().toDate()).tz(tz); |
| 268 | |
| 269 | const formattedTime = new Intl.DateTimeFormat(browserLocale, { |
| 270 | hour: "numeric", |
| 271 | minute: "numeric", |
| 272 | timeZone: tz, |
| 273 | }).format(day.toDate()); |
| 274 | |
| 275 | let display = formattedTime; |
| 276 | |
| 277 | if (day.isSame(today, "day")) { |
| 278 | display += " today"; |
| 279 | } else if (day.isSame(today.add(1, "day"), "day")) { |
| 280 | display += " tomorrow"; |
| 281 | } else { |
| 282 | // This case will rarely ever be hit, as we're dealing with only times and |
| 283 | // not dates, but it can be hit due to mismatched browser timezone to cron |
| 284 | // timezone or due to daylight savings changes. |
| 285 | display += ` on ${day.format("dddd, MMMM D")}`; |
| 286 | } |
| 287 | |
| 288 | display += ` (${day.from(today)}) in ${tz}`; |
| 289 | |
| 290 | return display; |
| 291 | }; |
| 292 | |
| 293 | export type TemplateAutostartRequirementDaysValue = |
| 294 | | "monday" |
no test coverage detected