a tool for shared writing and social publishing
298
fork

Configure Feed

Select the types of activity you want to include in your feed.

at ae852ba6d5ff811925df7ecb21ae0b943725c113 53 lines 2.1 kB view raw
1"use client"; 2import { useContext, useMemo } from "react"; 3import { DateTime } from "luxon"; 4import { RequestHeadersContext } from "components/Providers/RequestHeadersProvider"; 5import { useHasPageLoaded } from "components/InitialPageLoadProvider"; 6 7/** 8 * Hook that formats a date string using Luxon with timezone and locale from request headers. 9 * On initial page load, uses the timezone from request headers. After hydration, uses the system timezone. 10 * 11 * @param dateString - ISO date string to format 12 * @param options - Intl.DateTimeFormatOptions for formatting 13 * @returns Formatted date string 14 * 15 * @example 16 * const formatted = useLocalizedDate("2024-01-15T10:30:00Z", { dateStyle: 'full', timeStyle: 'short' }); 17 */ 18export function useLocalizedDate( 19 dateString: string, 20 options?: Intl.DateTimeFormatOptions, 21): string { 22 const { timezone, language } = useContext(RequestHeadersContext); 23 const hasPageLoaded = useHasPageLoaded(); 24 25 return useMemo(() => { 26 // Parse the date string to Luxon DateTime 27 let dateTime = DateTime.fromISO(dateString); 28 29 // On initial page load, use header timezone. After hydration, use system timezone 30 const effectiveTimezone = !hasPageLoaded 31 ? timezone || "UTC" 32 : Intl.DateTimeFormat().resolvedOptions().timeZone; 33 34 // Apply timezone if available 35 if (effectiveTimezone) { 36 dateTime = dateTime.setZone(effectiveTimezone); 37 } 38 39 // On initial page load, use header locale. After hydration, use system locale 40 // Parse locale from accept-language header (take first locale) 41 // accept-language format: "en-US,en;q=0.9,es;q=0.8" 42 const effectiveLocale = !hasPageLoaded 43 ? language?.split(",")[0]?.split(";")[0]?.trim() || "en-US" 44 : Intl.DateTimeFormat().resolvedOptions().locale; 45 46 try { 47 return dateTime.toLocaleString(options, { locale: effectiveLocale }); 48 } catch (error) { 49 // Fallback to en-US if locale is invalid 50 return dateTime.toLocaleString(options, { locale: "en-US" }); 51 } 52 }, [dateString, options, timezone, language, hasPageLoaded]); 53}