Subject: Let build useDateFormatter
react custom hook without any libraries only with Native JavaScript.
Have you ever seen a date like this in your app that comes from the backend?
"2024-04-29T07:30:00.000Z"
And wondered why it looks weird, or why it's showing the wrong time?
Thatβs because dates coming from a backend (like Node.js + PostgreSQL) are usually in ISO format, in UTC time, and not user-friendly.
π« The Wrong Way: Using TO_CHAR in PostgreSQL
This is what many people do in their SQL:
SELECT TO_CHAR(emp.emp_join_date, 'DD-MM-YYYY') AS emp_join_date FROM employees;
output:
"29-04-2025"
and thought, βLooks fine, right?β
π Nope. That format might look nice, but it breaks a lot of things in your app later.
Letβs understand why it's bad to format dates in PostgreSQL, and then fix it using a clean, reusable React useDateFormatter
custom hook.
Here's why it causes real problems:
β Disadvantages of TO_CHAR(date, 'DD-MM-YYYY')
Problem | Why itβs bad |
---|---|
1. Loses Date Type | TO_CHAR turns your date into a plain text string. So the frontend can't sort, compare, or manipulate it like a real Date . |
2. Not ISO/Standard | 'DD-MM-YYYY' is not a universal format. JS expects ISO like '2025-04-29T00:00:00Z' . Manual parsing is needed. |
3. Hard to Re-format Later | If frontend wants to show it as April 29, 2025 or local time β you can't. Itβs just a string! |
4. No Time Info | You lose the hours, minutes, seconds β which might matter for logs, tickets, comments, etc. |
5. No Timezone Awareness | There's no way to tell if the date was in UTC, IST, PST, etc. You risk showing wrong times to users. |
β The Right Way: Send Raw Dates (as ISO) from Backend
Instead of this:
SELECT TO_CHAR(emp_join_date, 'DD-MM-YYYY') AS emp_join_date FROM employees;
Do this:
SELECT emp_join_date FROM employees;
Let the date stay as a proper timestamp or ISO string ("2025-04-29T00:00:00.000Z")
, and then format it in React using a reusable hook.
π‘ Solution 1: A fundamental approach.
π§ The Reusable useDateFormatter React Hook
Letβs build a simple hook in TypeScript that works in any component.
// hooks/useDateFormatter.ts import { useCallback } from "react"; type FormatOptions = Intl.DateTimeFormatOptions; const defaultOptions: FormatOptions = { year: "numeric", month: "short", day: "numeric", hour: "2-digit", minute: "2-digit", }; export const useDateFormatter = () => { const formatDate = useCallback( ( dateInput: string | number | Date | null | undefined, options: FormatOptions = defaultOptions ): string => { if (!dateInput) return "N/A"; const date = new Date(dateInput); if (isNaN(date.getTime())) return "Invalid Date"; return new Intl.DateTimeFormat(undefined, options).format(date); // locale-aware }, [] ); return { formatDate }; };
π§ͺ Example Usage in a Component
// components/EmployeeCard.tsx import React from "react"; import { useDateFormatter } from "../hooks/useDateFormatter"; type Employee = { name: string; emp_join_date: string; }; const EmployeeCard: React.FC<{ emp: Employee }> = ({ emp }) => { const { formatDate } = useDateFormatter(); return ( <div> <h4>{emp.name}</h4> <p>Joined on: {formatDate(emp.emp_join_date)}</p> </div> ); }; export default EmployeeCard;
β‘ Real-World Use Case
Imagine you're building an HR dashboard. If the date is a string like "29-04-2025
", this fails:
const date = new Date("29-04-2025"); // β Invalid Date in many browsers
But if you get a raw ISO date like "2025-04-29T00:00:00Z
", it's perfect:
const date = new Date("2025-04-29T00:00:00Z"); // β
Works everywhere
Then useDateFormatter
formats it for display.
When to Use Just Native Intl.DateTimeFormat
(like the above solution1)
β Pros:
- Zero dependencies β no need to install any libraries.
- Lightweight β perfect for small apps or dashboards.
- Localized formatting based on userβs browser language.
- Handles common formatting needs: short/long date, time, etc. Works great for:
- Showing dates like "
Apr 29, 2025, 10:00 AM
" - Safe fallback behavior for invalid/missing dates
β Cons:
- Limited support for custom formats like "
YYYY-MM-DD HH:mm
". - Hard to manipulate dates (e.g. add/subtract days, set timezones).
- Browser support for time zones via Intl.DateTimeFormat is decent, but not fully flexible like
dayjs
.
β
Now you know how to format dates cleanly using native JavaScript!
But what if you need timezones, custom formats, or date math?
π Read Part 2: Building useDateFormatter
with dayjs
+ timezone support
Top comments (0)