11import { GlobeAltIcon , GlobeAmericasIcon } from "@heroicons/react/20/solid" ;
22import { Laptop } from "lucide-react" ;
3- import { Fragment , memo , type ReactNode , useMemo , useSyncExternalStore } from "react" ;
3+ import { memo , type ReactNode , useMemo , useSyncExternalStore } from "react" ;
44import { CopyButton } from "./CopyButton" ;
55import { useLocales } from "./LocaleProvider" ;
66import { Paragraph } from "./Paragraph" ;
@@ -19,7 +19,7 @@ function getLocalTimeZone(): string {
1919// For SSR compatibility: returns "UTC" on server, actual timezone on client
2020function subscribeToTimeZone ( ) {
2121 // No-op - timezone doesn't change
22- return ( ) => { } ;
22+ return ( ) => { } ;
2323}
2424
2525function getTimeZoneSnapshot ( ) : string {
@@ -44,6 +44,7 @@ type DateTimeProps = {
4444 timeZone ?: string ;
4545 includeSeconds ?: boolean ;
4646 includeTime ?: boolean ;
47+ includeDate ?: boolean ;
4748 showTimezone ?: boolean ;
4849 showTooltip ?: boolean ;
4950 hideDate ?: boolean ;
@@ -56,6 +57,7 @@ export const DateTime = ({
5657 timeZone,
5758 includeSeconds = true ,
5859 includeTime = true ,
60+ includeDate = true ,
5961 showTimezone = false ,
6062 showTooltip = true ,
6163 hour12 = true ,
@@ -66,17 +68,18 @@ export const DateTime = ({
6668 const realDate = useMemo ( ( ) => ( typeof date === "string" ? new Date ( date ) : date ) , [ date ] ) ;
6769
6870 const formattedDateTime = (
69- < Fragment >
71+ < span suppressHydrationWarning >
7072 { formatDateTime (
7173 realDate ,
7274 timeZone ?? localTimeZone ,
7375 locales ,
7476 includeSeconds ,
7577 includeTime ,
78+ includeDate ,
7679 hour12
7780 ) . replace ( / \s / g, String . fromCharCode ( 32 ) ) }
7881 { showTimezone ? ` (${ timeZone ?? "UTC" } )` : null }
79- </ Fragment >
82+ </ span >
8083 ) ;
8184
8285 if ( ! showTooltip ) return formattedDateTime ;
@@ -104,12 +107,13 @@ export function formatDateTime(
104107 locales : string [ ] ,
105108 includeSeconds : boolean ,
106109 includeTime : boolean ,
110+ includeDate : boolean ,
107111 hour12 : boolean = true
108112) : string {
109113 return new Intl . DateTimeFormat ( locales , {
110- year : "numeric" ,
111- month : "short" ,
112- day : "numeric" ,
114+ year : includeDate ? "numeric" : undefined ,
115+ month : includeDate ? "short" : undefined ,
116+ day : includeDate ? "numeric" : undefined ,
113117 hour : includeTime ? "numeric" : undefined ,
114118 minute : includeTime ? "numeric" : undefined ,
115119 second : includeTime && includeSeconds ? "numeric" : undefined ,
@@ -179,7 +183,7 @@ export const SmartDateTime = ({ date, previousDate = null, hour12 = true }: Date
179183 ? formatSmartDateTime ( realDate , localTimeZone , locales , hour12 )
180184 : formatTimeOnly ( realDate , localTimeZone , locales , hour12 ) ;
181185
182- return < Fragment > { formattedDateTime . replace ( / \s / g, String . fromCharCode ( 32 ) ) } </ Fragment > ;
186+ return < span suppressHydrationWarning > { formattedDateTime . replace ( / \s / g, String . fromCharCode ( 32 ) ) } </ span > ;
183187} ;
184188
185189// Helper function to check if two dates are on the same day
@@ -251,14 +255,14 @@ const DateTimeAccurateInner = ({
251255 return hideDate
252256 ? formatTimeOnly ( realDate , localTimeZone , locales , hour12 )
253257 : realPrevDate
254- ? isSameDay ( realDate , realPrevDate )
255- ? formatTimeOnly ( realDate , localTimeZone , locales , hour12 )
256- : formatDateTimeAccurate ( realDate , localTimeZone , locales , hour12 )
257- : formatDateTimeAccurate ( realDate , localTimeZone , locales , hour12 ) ;
258+ ? isSameDay ( realDate , realPrevDate )
259+ ? formatTimeOnly ( realDate , localTimeZone , locales , hour12 )
260+ : formatDateTimeAccurate ( realDate , localTimeZone , locales , hour12 )
261+ : formatDateTimeAccurate ( realDate , localTimeZone , locales , hour12 ) ;
258262 } , [ realDate , localTimeZone , locales , hour12 , hideDate , previousDate ] ) ;
259263
260264 if ( ! showTooltip )
261- return < Fragment > { formattedDateTime . replace ( / \s / g, String . fromCharCode ( 32 ) ) } </ Fragment > ;
265+ return < span suppressHydrationWarning > { formattedDateTime . replace ( / \s / g, String . fromCharCode ( 32 ) ) } </ span > ;
262266
263267 const tooltipContent = (
264268 < TooltipContent
@@ -271,7 +275,7 @@ const DateTimeAccurateInner = ({
271275
272276 return (
273277 < SimpleTooltip
274- button = { < Fragment > { formattedDateTime . replace ( / \s / g, String . fromCharCode ( 32 ) ) } </ Fragment > }
278+ button = { < span suppressHydrationWarning > { formattedDateTime . replace ( / \s / g, String . fromCharCode ( 32 ) ) } </ span > }
275279 content = { tooltipContent }
276280 side = "right"
277281 asChild = { true }
@@ -328,7 +332,7 @@ export const DateTimeShort = ({ date, hour12 = true }: DateTimeProps) => {
328332 const realDate = typeof date === "string" ? new Date ( date ) : date ;
329333 const formattedDateTime = formatDateTimeShort ( realDate , localTimeZone , locales , hour12 ) ;
330334
331- return < Fragment > { formattedDateTime . replace ( / \s / g, String . fromCharCode ( 32 ) ) } </ Fragment > ;
335+ return < span suppressHydrationWarning > { formattedDateTime . replace ( / \s / g, String . fromCharCode ( 32 ) ) } </ span > ;
332336} ;
333337
334338function formatDateTimeShort (
@@ -409,20 +413,20 @@ function TooltipContent({
409413 { timeZone && timeZone !== "UTC" && (
410414 < DateTimeTooltipContent
411415 title = { timeZone }
412- dateTime = { formatDateTime ( realDate , timeZone , locales , true , true ) }
416+ dateTime = { formatDateTime ( realDate , timeZone , locales , true , true , true ) }
413417 isoDateTime = { formatDateTimeISO ( realDate , timeZone ) }
414418 icon = { < GlobeAmericasIcon className = "size-4 text-purple-500" /> }
415419 />
416420 ) }
417421 < DateTimeTooltipContent
418422 title = "UTC"
419- dateTime = { formatDateTime ( realDate , "UTC" , locales , true , true ) }
423+ dateTime = { formatDateTime ( realDate , "UTC" , locales , true , true , true ) }
420424 isoDateTime = { formatDateTimeISO ( realDate , "UTC" ) }
421425 icon = { < GlobeAltIcon className = "size-4 text-blue-500" /> }
422426 />
423427 < DateTimeTooltipContent
424428 title = "Local"
425- dateTime = { formatDateTime ( realDate , localTimeZone , locales , true , true ) }
429+ dateTime = { formatDateTime ( realDate , localTimeZone , locales , true , true , true ) }
426430 isoDateTime = { formatDateTimeISO ( realDate , localTimeZone ) }
427431 icon = { < Laptop className = "size-4 text-green-500" /> }
428432 />
0 commit comments