refactor(time): migrate runtime time handling to Temporal

This commit is contained in:
2026-03-09 07:18:09 +04:00
parent fa8fa7fe23
commit 29f6d788e7
25 changed files with 353 additions and 104 deletions

View File

@@ -1,3 +1,5 @@
import type { Instant } from './time'
import { DOMAIN_ERROR_CODE, DomainError } from './errors'
const BILLING_PERIOD_PATTERN = /^(\d{4})-(\d{2})$/
@@ -48,8 +50,10 @@ export class BillingPeriod {
return BillingPeriod.from(Number(yearString), Number(monthString))
}
static fromDate(date: Date): BillingPeriod {
return BillingPeriod.from(date.getUTCFullYear(), date.getUTCMonth() + 1)
static fromInstant(instant: Instant): BillingPeriod {
const zoned = instant.toZonedDateTimeISO('UTC')
return BillingPeriod.from(zoned.year, zoned.month)
}
next(): BillingPeriod {

View File

@@ -2,7 +2,18 @@ export { BillingPeriod } from './billing-period'
export { DOMAIN_ERROR_CODE, DomainError } from './errors'
export { BillingCycleId, HouseholdId, MemberId, PurchaseEntryId } from './ids'
export { CURRENCIES, Money } from './money'
export {
Temporal,
instantFromDatabaseValue,
instantFromDate,
instantFromEpochSeconds,
instantFromIso,
instantToDate,
instantToEpochSeconds,
nowInstant
} from './time'
export type { CurrencyCode } from './money'
export type { Instant } from './time'
export type {
SettlementInput,
SettlementMemberInput,

View File

@@ -0,0 +1,41 @@
import { Temporal } from '@js-temporal/polyfill'
export { Temporal }
export type Instant = Temporal.Instant
export function nowInstant(): Instant {
return Temporal.Now.instant()
}
export function instantFromEpochSeconds(epochSeconds: number): Instant {
return Temporal.Instant.fromEpochMilliseconds(epochSeconds * 1000)
}
export function instantToEpochSeconds(instant: Instant): number {
return Math.floor(instant.epochMilliseconds / 1000)
}
export function instantFromDate(date: Date): Instant {
return Temporal.Instant.fromEpochMilliseconds(date.getTime())
}
export function instantToDate(instant: Instant): Date {
return new Date(instant.epochMilliseconds)
}
export function instantFromIso(value: string): Instant {
return Temporal.Instant.from(value)
}
export function instantFromDatabaseValue(value: Date | string | null): Instant | null {
if (value instanceof Date) {
return instantFromDate(value)
}
if (typeof value === 'string') {
return instantFromIso(value)
}
return null
}