Remove export block in favor of directly exporting symbols.

This commit is contained in:
Leo Vasanko
2025-09-25 08:39:25 -06:00
parent 86a1a4d772
commit 09df4bed5e

View File

@@ -2,14 +2,14 @@
import * as dateFns from 'date-fns' import * as dateFns from 'date-fns'
import { fromZonedTime, toZonedTime } from 'date-fns-tz' import { fromZonedTime, toZonedTime } from 'date-fns-tz'
const DEFAULT_TZ = Intl.DateTimeFormat().resolvedOptions().timeZone || 'UTC' export const DEFAULT_TZ = Intl.DateTimeFormat().resolvedOptions().timeZone || 'UTC'
// Re-exported iso helpers (keep the same exported names used elsewhere) // Re-exported iso helpers (keep the same exported names used elsewhere)
const getISOWeek = dateFns.getISOWeek export const getISOWeek = dateFns.getISOWeek
const getISOWeekYear = dateFns.getISOWeekYear export const getISOWeekYear = dateFns.getISOWeekYear
// Constants // Constants
const monthAbbr = [ export const monthAbbr = [
'jan', 'jan',
'feb', 'feb',
'mar', 'mar',
@@ -24,15 +24,15 @@ const monthAbbr = [
'dec', 'dec',
] ]
// We get scrolling issues if the virtual view is bigger than that // We get scrolling issues if the virtual view is bigger than that
const MIN_YEAR = 1582 export const MIN_YEAR = 1582
const MAX_YEAR = 3000 export const MAX_YEAR = 3000
// Core helpers ------------------------------------------------------------ // Core helpers ------------------------------------------------------------
/** /**
* Construct a date at local midnight in the specified IANA timezone. * Construct a date at local midnight in the specified IANA timezone.
* Returns a native Date whose wall-clock components in that zone are (Y, M, D 00:00:00). * Returns a native Date whose wall-clock components in that zone are (Y, M, D 00:00:00).
*/ */
function makeTZDate(year, monthIndex, day, timeZone = DEFAULT_TZ) { export function makeTZDate(year, monthIndex, day, timeZone = DEFAULT_TZ) {
const iso = `${String(year).padStart(4, '0')}-${String(monthIndex + 1).padStart(2, '0')}-${String( const iso = `${String(year).padStart(4, '0')}-${String(monthIndex + 1).padStart(2, '0')}-${String(
day, day,
).padStart(2, '0')}` ).padStart(2, '0')}`
@@ -43,40 +43,40 @@ function makeTZDate(year, monthIndex, day, timeZone = DEFAULT_TZ) {
/** /**
* Alias constructor for timezone-specific calendar date (semantic sugar over makeTZDate). * Alias constructor for timezone-specific calendar date (semantic sugar over makeTZDate).
*/ */
const TZDate = (year, monthIndex, day, timeZone = DEFAULT_TZ) => export const TZDate = (year, monthIndex, day, timeZone = DEFAULT_TZ) =>
makeTZDate(year, monthIndex, day, timeZone) makeTZDate(year, monthIndex, day, timeZone)
/** /**
* Construct a UTC-based date/time (wrapper for Date.UTC for consistency). * Construct a UTC-based date/time (wrapper for Date.UTC for consistency).
*/ */
const UTCDate = (year, monthIndex, day, hour = 0, minute = 0, second = 0, ms = 0) => export const UTCDate = (year, monthIndex, day, hour = 0, minute = 0, second = 0, ms = 0) =>
new Date(Date.UTC(year, monthIndex, day, hour, minute, second, ms)) new Date(Date.UTC(year, monthIndex, day, hour, minute, second, ms))
function toLocalString(date = new Date(), timeZone = DEFAULT_TZ) { export function toLocalString(date = new Date(), timeZone = DEFAULT_TZ) {
return dateFns.format(toZonedTime(date, timeZone), 'yyyy-MM-dd') return dateFns.format(toZonedTime(date, timeZone), 'yyyy-MM-dd')
} }
function fromLocalString(dateString, timeZone = DEFAULT_TZ) { export function fromLocalString(dateString, timeZone = DEFAULT_TZ) {
if (!dateString) return makeTZDate(1970, 0, 1, timeZone) if (!dateString) return makeTZDate(1970, 0, 1, timeZone)
const parsed = dateFns.parseISO(dateString) const parsed = dateFns.parseISO(dateString)
const utcDate = fromZonedTime(`${dateString}T00:00:00`, timeZone) const utcDate = fromZonedTime(`${dateString}T00:00:00`, timeZone)
return toZonedTime(utcDate, timeZone) || parsed return toZonedTime(utcDate, timeZone) || parsed
} }
function getMondayOfISOWeek(date, timeZone = DEFAULT_TZ) { export function getMondayOfISOWeek(date, timeZone = DEFAULT_TZ) {
const d = toZonedTime(date, timeZone) const d = toZonedTime(date, timeZone)
const dow = (dateFns.getDay(d) + 6) % 7 // Monday=0 const dow = (dateFns.getDay(d) + 6) % 7 // Monday=0
return dateFns.addDays(dateFns.startOfDay(d), -dow) return dateFns.addDays(dateFns.startOfDay(d), -dow)
} }
const mondayIndex = (d) => (dateFns.getDay(d) + 6) % 7 export const mondayIndex = (d) => (dateFns.getDay(d) + 6) % 7
// (Recurrence utilities moved to events.js) // (Recurrence utilities moved to events.js)
// Utility formatting & localization --------------------------------------- // Utility formatting & localization ---------------------------------------
const pad = (n) => String(n).padStart(2, '0') export const pad = (n) => String(n).padStart(2, '0')
function daysInclusive(aStr, bStr, timeZone = DEFAULT_TZ) { export function daysInclusive(aStr, bStr, timeZone = DEFAULT_TZ) {
const a = fromLocalString(aStr, timeZone) const a = fromLocalString(aStr, timeZone)
const b = fromLocalString(bStr, timeZone) const b = fromLocalString(bStr, timeZone)
return ( return (
@@ -84,12 +84,12 @@ function daysInclusive(aStr, bStr, timeZone = DEFAULT_TZ) {
) )
} }
function addDaysStr(str, n, timeZone = DEFAULT_TZ) { export function addDaysStr(str, n, timeZone = DEFAULT_TZ) {
return toLocalString(dateFns.addDays(fromLocalString(str, timeZone), n), timeZone) return toLocalString(dateFns.addDays(fromLocalString(str, timeZone), n), timeZone)
} }
// Weekday name helpers now return Sunday-first ordering (index 0 = Sunday ... 6 = Saturday) // Weekday name helpers now return Sunday-first ordering (index 0 = Sunday ... 6 = Saturday)
function getLocalizedWeekdayNames(timeZone = DEFAULT_TZ) { export function getLocalizedWeekdayNames(timeZone = DEFAULT_TZ) {
const sunday = makeTZDate(2025, 0, 5, timeZone) // a Sunday const sunday = makeTZDate(2025, 0, 5, timeZone) // a Sunday
return Array.from({ length: 7 }, (_, i) => return Array.from({ length: 7 }, (_, i) =>
new Intl.DateTimeFormat(undefined, { weekday: 'short', timeZone }).format( new Intl.DateTimeFormat(undefined, { weekday: 'short', timeZone }).format(
@@ -99,7 +99,7 @@ function getLocalizedWeekdayNames(timeZone = DEFAULT_TZ) {
} }
// Long (wide) localized weekday names, Sunday-first ordering // Long (wide) localized weekday names, Sunday-first ordering
function getLocalizedWeekdayNamesLong(timeZone = DEFAULT_TZ) { export function getLocalizedWeekdayNamesLong(timeZone = DEFAULT_TZ) {
const sunday = makeTZDate(2025, 0, 5, timeZone) const sunday = makeTZDate(2025, 0, 5, timeZone)
return Array.from({ length: 7 }, (_, i) => return Array.from({ length: 7 }, (_, i) =>
new Intl.DateTimeFormat(undefined, { weekday: 'long', timeZone }).format( new Intl.DateTimeFormat(undefined, { weekday: 'long', timeZone }).format(
@@ -108,26 +108,26 @@ function getLocalizedWeekdayNamesLong(timeZone = DEFAULT_TZ) {
) )
} }
function getLocaleFirstDay() { export function getLocaleFirstDay() {
const day = new Intl.Locale(navigator.language).weekInfo?.firstDay ?? 1 const day = new Intl.Locale(navigator.language).weekInfo?.firstDay ?? 1
return day % 7 return day % 7
} }
function getLocaleWeekendDays() { export function getLocaleWeekendDays() {
const wk = new Set(new Intl.Locale(navigator.language).weekInfo?.weekend ?? [6, 7]) const wk = new Set(new Intl.Locale(navigator.language).weekInfo?.weekend ?? [6, 7])
return Array.from({ length: 7 }, (_, i) => wk.has(1 + ((i + 6) % 7))) return Array.from({ length: 7 }, (_, i) => wk.has(1 + ((i + 6) % 7)))
} }
function reorderByFirstDay(days, firstDay) { export function reorderByFirstDay(days, firstDay) {
return Array.from({ length: 7 }, (_, i) => days[(i + firstDay) % 7]) return Array.from({ length: 7 }, (_, i) => days[(i + firstDay) % 7])
} }
function getLocalizedMonthName(idx, short = false, timeZone = DEFAULT_TZ) { export function getLocalizedMonthName(idx, short = false, timeZone = DEFAULT_TZ) {
const d = makeTZDate(2025, idx, 1, timeZone) const d = makeTZDate(2025, idx, 1, timeZone)
return new Intl.DateTimeFormat(undefined, { month: short ? 'short' : 'long', timeZone }).format(d) return new Intl.DateTimeFormat(undefined, { month: short ? 'short' : 'long', timeZone }).format(d)
} }
function formatDateRange(startDate, endDate, timeZone = DEFAULT_TZ) { export function formatDateRange(startDate, endDate, timeZone = DEFAULT_TZ) {
const a = toLocalString(startDate, timeZone) const a = toLocalString(startDate, timeZone)
const b = toLocalString(endDate, timeZone) const b = toLocalString(endDate, timeZone)
if (a === b) return a if (a === b) return a
@@ -138,7 +138,7 @@ function formatDateRange(startDate, endDate, timeZone = DEFAULT_TZ) {
return `${a}/${b}` return `${a}/${b}`
} }
function lunarPhaseSymbol(date) { export function lunarPhaseSymbol(date) {
// Reference new moon (J2000 era) used for approximate phase calculations // Reference new moon (J2000 era) used for approximate phase calculations
const ref = UTCDate(2000, 0, 6, 18, 14, 0) const ref = UTCDate(2000, 0, 6, 18, 14, 0)
const obs = new Date(date) const obs = new Date(date)
@@ -165,14 +165,14 @@ function lunarPhaseSymbol(date) {
/** /**
* Format date as short localized string (e.g., "Jan 15") * Format date as short localized string (e.g., "Jan 15")
*/ */
function formatDateShort(date) { export function formatDateShort(date) {
return date.toLocaleDateString(undefined, { month: 'short', day: 'numeric' }).replace(/, /, ' ') return date.toLocaleDateString(undefined, { month: 'short', day: 'numeric' }).replace(/, /, ' ')
} }
/** /**
* Format date as long localized string with optional year (e.g., "Mon Jan 15" or "Mon Jan 15, 2025") * Format date as long localized string with optional year (e.g., "Mon Jan 15" or "Mon Jan 15, 2025")
*/ */
function formatDateLong(date, includeYear = false) { export function formatDateLong(date, includeYear = false) {
const opts = { const opts = {
weekday: 'short', weekday: 'short',
month: 'short', month: 'short',
@@ -185,45 +185,9 @@ function formatDateLong(date, includeYear = false) {
/** /**
* Format date as today string (e.g., "Monday\nJanuary 15") * Format date as today string (e.g., "Monday\nJanuary 15")
*/ */
function formatTodayString(date, weekday = "long", month = "long") { export function formatTodayString(date, weekday = "long", month = "long") {
const formatted = date const formatted = date
.toLocaleDateString(undefined, { weekday, month, day: 'numeric' }) .toLocaleDateString(undefined, { weekday, month, day: 'numeric' })
.replace(/,? /, '\n') .replace(/,? /, '\n')
return formatted.charAt(0).toUpperCase() + formatted.slice(1) return formatted.charAt(0).toUpperCase() + formatted.slice(1)
} }
export {
// constants
monthAbbr,
MIN_YEAR,
MAX_YEAR,
DEFAULT_TZ,
// core tz helpers
makeTZDate,
toLocalString,
fromLocalString,
// recurrence
getMondayOfISOWeek,
mondayIndex,
// formatting & localization
pad,
daysInclusive,
addDaysStr,
getLocalizedWeekdayNames,
getLocalizedWeekdayNamesLong,
getLocaleFirstDay,
getLocaleWeekendDays,
reorderByFirstDay,
getLocalizedMonthName,
formatDateRange,
formatDateShort,
formatDateLong,
formatTodayString,
lunarPhaseSymbol,
// iso helpers re-export
getISOWeek,
getISOWeekYear,
// constructors
TZDate,
UTCDate,
}