Remove export block in favor of directly exporting symbols.
This commit is contained in:
@@ -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,
|
|
||||||
}
|
|
||||||
|
|||||||
Reference in New Issue
Block a user