Documentation

Settings

Timezone Handling

The Ellemment Stack provides robust timezone handling through client hints, ensuring accurate time display across server and client rendering.

Implementation

Server-Side Usage

Access timezone information in server code:

// In your loader
import { getHints } from '#app/utils/client-hints'
,[object Object],

const formattedDate = getDateTimeFormat(timeZone).format(date)
return json({ formattedDate })
}

Client-Side Usage

Access timezone information in components:

import { useHints } from '#app/utils/client-hints'
,[object Object],

return <time dateTime={date.toISOString()}>
{formatter.format(date)}
</time>
}

DateTimeFormat Utility

The built-in getDateTimeFormat utility provides consistent formatting:

import { getDateTimeFormat } from '#app/utils/misc.server'

function formatDateTime(date: Date, request: Request) {
const hints = getHints(request)
const formatter = getDateTimeFormat(hints.timeZone)
return formatter.format(date)
}

Best Practices

Date Storage

// Always store dates in UTC
const storedDate = new Date().toISOString()

// Convert to user timezone for display
const displayDate = format(parseISO(storedDate), 'PPpp', {
timeZone: hints.timeZone
})

Format Consistency

const dateFormatters = {
  short: getDateTimeFormat(timeZone, {
    dateStyle: 'short',
    timeStyle: 'short'
  }),
  full: getDateTimeFormat(timeZone, {
    dateStyle: 'full',
    timeStyle: 'long'
  }),
  date: getDateTimeFormat(timeZone, {
    dateStyle: 'medium'
  }),
  time: getDateTimeFormat(timeZone, {
    timeStyle: 'short'
  })
}

Relative Times

function RelativeTime({ date }: { date: Date }) {
  const hints = useHints()
  const formatter = new Intl.RelativeTimeFormat(undefined, {
    numeric: 'auto'
  })

// Implementation of relative time logic
return <time dateTime={date.toISOString()}>
{/* Formatted relative time */}
</time>
}

Error Handling

function safeDateFormat(date: Date, timeZone: string) {
  try {
    return new Intl.DateTimeFormat(undefined, {
      timeZone
    }).format(date)
  } catch (error) {
    console.error(`Invalid timezone: ${timeZone}`)
    return new Intl.DateTimeFormat(undefined, {
      timeZone: 'UTC'
    }).format(date)
  }
}

Performance Considerations

Caching Formatters

const formatterCache = new Map<string, Intl.DateTimeFormat>()

function getCachedFormatter(timeZone: string) {
const key = ,[object Object],
if (!formatterCache.has(key)) {
formatterCache.set(
key,
new Intl.DateTimeFormat(undefined, { timeZone })
)
}
return formatterCache.get(key)!
}

Batch Processing

function batchFormatDates(dates: Date[], timeZone: string) {
  const formatter = getCachedFormatter(timeZone)
  return dates.map(date => formatter.format(date))
}

For more information about client hints, see the client hints documentation. For performance considerations, refer to the performance documentation.