RelativeTime Component
The RelativeTime component displays human-readable relative timestamps with automatic updates and tooltip functionality.
Overview
This utility component converts timestamps to relative time strings (e.g., “5 minutes ago”, “2 hours ago”) with intelligent refresh intervals and optional tooltip showing exact timestamp. It’s designed for displaying message timestamps, last updated times, and other temporal information.
Location
src/components/RelativeTime.tsx
Features
Flexible Input Support
- Accepts both timestamp numbers and Date objects
- Backward compatible with existing timestamp prop
- Graceful handling of invalid or missing timestamps
Intelligent Update Intervals
- Recent (< 1 minute): Updates every 10 seconds
- Hour old (< 1 hour): Updates every minute
- Day old (< 1 day): Updates every 5 minutes
- Older: Updates every hour
Stable Rendering
- Prevents timestamp changes during re-renders using
useRef - Ensures consistent display even when parent component updates
- Single initialization prevents time drift issues
Optional Tooltip
- Shows exact timestamp on hover when
showTooltip={true} - Uses locale-specific formatting with
toLocaleString() - Can be disabled for simple text display
Props Interface
interface TimeProps {
timestamp?: number; // Original API for backward compatibility
date?: Date; // New API to support Date objects
className?: string; // CSS classes (default: "text-xs text-muted-foreground/60")
fallback?: string; // Text when timestamp missing (default: "Never")
showTooltip?: boolean; // Enable tooltip (default: true)
}
Usage Examples
Basic Usage
import { RelativeTime } from '@/components/RelativeTime';
// Using timestamp
<RelativeTime timestamp={Date.now() - 300000} />
// Output: "5 minutes ago"
// Using Date object
<RelativeTime date={new Date('2024-01-01')} />
// Output: "about 2 months ago"
Custom Styling
<RelativeTime
timestamp={message.createdAt}
className="text-sm text-blue-600"
fallback="Unknown time"
showTooltip={false}
/>
In Message Components
function MessageItem({ message }) {
return (
<div className="message">
<div className="content">{message.text}</div>
<RelativeTime
timestamp={message.timestamp}
className="text-xs text-gray-500"
/>
</div>
);
}
Dependencies
date-fns- ProvidesformatDistanceToNowfunction@/components/ui/tooltip- Tooltip components for hover display- React hooks:
useState,useEffect,useRef
Implementation Details
Performance Optimizations
- Uses
useRefto store initial timestamp, preventing recalculation - Intelligent interval timing reduces unnecessary updates
- Cleanup of intervals on component unmount
Error Handling
- Try-catch around
formatDistanceToNowwith fallback to “Unknown time” - Graceful handling of invalid timestamps
- Console error logging for debugging
Accessibility
- Tooltip provides additional context for screen readers
- Semantic time display with proper ARIA attributes
- Respects user’s locale settings for timestamp formatting
Browser Compatibility
toLocaleString(): All modern browsersdate-fns: No specific browser requirements- Tooltip functionality: All modern browsers
Related Components
- Message display components that show timestamps
- Chat interfaces requiring relative time display
- Activity feeds and notification systems
Best Practices
- Use the Date API for new implementations when possible
- Provide fallback text for missing timestamps
- Consider disabling tooltips in space-constrained layouts
- Use appropriate CSS classes for consistent styling across the app