Skip to content
Devix Open Source

Guide

Dates and time zones

Why dates shift in other pickers

A JavaScript Date is a moment in time, not a day on the calendar. Take the Date for "midnight 18 September" in Dubai: in London that same moment is 17 September. Save it, send it or format it in the wrong zone, and the day moves.

This is the most-reacted issue in react-datepicker's history, and it is still open on flatpickr.

How this picker avoids it

It never uses a Date for a calendar date.

  • Inside the picker, a date is a day number: days since 1970-01-01.
  • Everywhere you touch it — options, getValue(), events, the hidden input — a date is an ISO string like "2026-09-18".

Neither has a time zone, so there is nothing to shift. The browser tests pick a date in Kiritimati (UTC+14), Dubai, London, Los Angeles and Pago Pago (UTC−11), and require the same stored value in all five.

"Today" is the one time-zone question

Which day is today depends on where you are. By default the picker asks the device. For a business that runs on one zone, say which:

createDatePicker(input, { timeZone: 'Asia/Dubai' });

Now "Today", the today marker, relative typing ("tomorrow") and range presets ("Last 7 days") all follow Dubai's calendar, even for a visitor in New York.

Storing and sending

Store the ISO string in a date column (MySQL DATE, PostgreSQL date). Laravel and most frameworks read 2026-09-18 directly. If an API insists on a Date, use getDate(): it returns UTC midnight, which round-trips safely as long as you format it in UTC.

Working with dates yourself

The DOM-free core is exported for Node, workers and your own UI:

import { parseIso, toIso, addMonths, today, formatDate } from '@devix-labs/date-picker/core';

const next = toIso(addMonths(parseIso('2026-01-31'), 1)); // "2026-02-28" — clamped, never 3 March
formatDate(parseIso('2026-09-18'), 'en-GB', 'gregory', { dateStyle: 'full' }); // "Friday, 18 September 2026"
toIso(today('Pacific/Auckland'));
Updated 15 Sep 2026