Subject: Handle any date from any timezone, precisely and predictably — with the help of dayjs.

📦 Why Move Beyond Native Date Formatting?

In Part 1, we built a clean useDateFormatter hook using JavaScript’s built-in Intl.DateTimeFormat.

That works great for simple needs — but what if you need to:

  • Show dates in a specific timezone (e.g. always show in "Asia/Kolkata")
  • Format dates like YYYY-MM-DD HH:mm A
  • Do math like "3 days from now" or "subtract 2 hours"?

💥 That’s where dayjs shines.


🧰 Step 1: Install dayjs with Plugins

npm install dayjs
npm install dayjs-plugin-utc dayjs-plugin-timezone

Now lets build a superior useDateFormatter custom React hook to auto-detect timezone and format dates cleanly.

🧠 Step 2: Create useDateFormatter with dayjs

// hooks/useDateFormatter.ts
import { useCallback } from "react";
import dayjs from 'dayjs';
import utc from 'dayjs/plugin/utc';
import timezone from 'dayjs/plugin/timezone';

dayjs.extend(utc);
dayjs.extend(timezone);

type FormatOptions = {
  format?: string;         // e.g. 'YYYY-MM-DD HH:mm'
  timezone?: string;       // e.g. 'Asia/Kolkata'
};

export const useDateFormatter = () => {
  const formatDate = useCallback(
    (
      input: string | Date | number | null | undefined,
      options: FormatOptions = {}
    ): string => {
      if (!input) return "N/A";

      try {
        const { format = "MMM D, YYYY h:mm A", timezone = dayjs.tz.guess() } = options;

        return dayjs.utc(input).tz(timezone).format(format);
      } catch (error) {
        return "Invalid Date";
      }
    },
    []
  );

  return { formatDate };
};

🧪 Example Usage in a Component

// components/EventCard.tsx
import React from "react";
import { useDateFormatter } from "../hooks/useDateFormatter";

const EventCard: React.FC<{ startDate: string }> = ({ startDate }) => {
  const { formatDate } = useDateFormatter();

  return (
    <div>
      <h3>Event Starts</h3>
      <p>{formatDate(startDate, { timezone: "Asia/Kolkata", format: "dddd, MMM D [at] h:mm A" })}</p>
    </div>
  );
};

export default EventCard;

Even if it's just 1 line inside the helper — it's worth it.


🌏 Bonus Example – Showing in User’s Local Time

formatDate("2025-04-29T12:00:00Z", {
  format: "DD-MM-YYYY hh:mm A",
  timezone: dayjs.tz.guess(), // User's current zone
});

🧪 Output Examples

Input UTC Date Format Timezone Output
2025-04-29T12:00:00Z "MMM D, YYYY h:mm A" Asia/Kolkata Apr 29, 2025 5:30 PM
2025-04-29T12:00:00Z "YYYY-MM-DD HH:mm" America/New_York 2025-04-29 08:00

🆚 Native vs Day.js Summary

Feature Native Intl dayjs
Localized output
Timezone support ⚠️ Limited ✅ Full
Custom format strings
Add/subtract time
Parsing & validation Basic Strong
Lightweight ✅ (~5KB with plugins)

🧼 Final Thoughts

Use native if your needs are simple and performance is key.
Use dayjs if you:

  • Need timezone handling
  • Want full control over format
  • Are working with global users or scheduling

✅ This is exactly how big production dashboards (admin panels, SaaS apps) build it professionally.


🧩 Missed Part 1?
👉 Go back to the Native useDateFormatter without libraries