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