Open3

date-fnsでタイムゾーンを考慮してstartOfDayなどを行う

Nakano as a ServiceNakano as a Service
import { fromZonedTime, toZonedTime } from "date-fns-tz"

export function zoned(date: Date, tz: string, fn: (date: Date) => Date) {
  const inputZoned = toZonedTime(date, tz)
  const fnZoned = fn(inputZoned)
  return fromZonedTime(fnZoned, tz)
}

Nakano as a ServiceNakano as a Service
formatInTimeZone(
    zoned(new Date(), "Asia/Tokyo", (d) => startOfDay(d)),
    "Asia/Tokyo",
    'yyyy-MM-dd HH:mm:ss zzz'
)
// '2024-09-09 00:00:00 GMT+9'
Nakano as a ServiceNakano as a Service

このテクニックはdate-fns v4のタイムゾーンサポートで不要になりました。

// TZ=UTCでNodeを起動

import { tz } from "@date-fns/tz";
import { startOfDay } from "date-fns/tz";

new Date()
// 2024-09-16T13:24:09.969Z

startOfDay(new Date(), { in: tz("Asia/Tokyo") })
// TZDate 2024-09-15T15:00:00.000Z {
//   timeZone: 'Asia/Tokyo',
//   internal: 2024-09-16T00:00:00.000Z
// }

https://blog.date-fns.org/v40-with-time-zone-support/