Convert Date Formats Between PHP, MySQL, and JavaScript
MySQL, PHP, and JavaScript each default to a different date format — here's exactly how to convert between all three without losing the timezone.
By DevStudio Online Team · Published September 3, 2026
A single date, moving through a typical stack, passes through three different formats: MySQL's DATETIME (2026-09-03 14:30:00), PHP's DateTime object, and JavaScript's Date (usually as an ISO string). Getting any one of these conversions wrong is one of the most common sources of "the date is off by a day" bugs.
MySQL → PHP
$row = $pdo->query("SELECT created_at FROM orders LIMIT 1")->fetch();
$date = new DateTime($row['created_at']); // PHP's DateTime parses MySQL's format natively
echo $date->format('F j, Y'); // "September 3, 2026"DateTime understands MySQL's YYYY-MM-DD HH:MM:SS format out of the box — no manual string parsing needed in either direction.
PHP → MySQL
$date = new DateTime('now');
$mysqlFormat = $date->format('Y-m-d H:i:s'); // "2026-09-03 14:30:00"
$stmt = $pdo->prepare("INSERT INTO orders (created_at) VALUES (?)");
$stmt->execute([$mysqlFormat]);Always format explicitly with Y-m-d H:i:s before inserting — never pass a DateTime object directly into a query, since PHP will silently stringify it using its own default format, which does not match what MySQL expects.
PHP → JavaScript (via JSON)
echo json_encode(['created_at' => $date->format(DateTime::ATOM)]);
// {"created_at":"2026-09-03T14:30:00+00:00"}const data = await response.json()
const jsDate = new Date(data.created_at) // JS Date parses ISO 8601 nativelyDateTime::ATOM produces ISO 8601 with an explicit timezone offset — this is the one format that both PHP and JavaScript's Date constructor agree on without ambiguity. Sending a bare MySQL-style string (2026-09-03 14:30:00, no timezone) to the frontend is asking for trouble: some browsers parse it as UTC, others as local time.
JavaScript → MySQL
const now = new Date()
const mysqlFormat = now.toISOString().slice(0, 19).replace('T', ' ')
// "2026-09-03T14:30:00.000Z".slice(0,19) -> "2026-09-03T14:30:00" -> "2026-09-03 14:30:00"toISOString() always returns UTC — if your MySQL column should store local time rather than UTC, convert on the server (PHP) side instead, where you have proper timezone-aware DateTime objects, rather than trying to do timezone math in JavaScript.
The one rule that prevents most of these bugs
Store and pass dates in UTC everywhere except the final render to a human — convert to the viewer's local timezone only at the very last step, in the frontend, right before display.
Related tool
MySQL Connector