JavaScript
MySQL
Datetime Conversion
Programming
Web Development

Convert JS date time to MySQL datetime

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

A JavaScript Date object represents a point in time, while a MySQL DATETIME column stores a textual calendar value with no timezone attached. Converting safely means choosing a timezone policy first, then formatting the date consistently before sending it through a parameterized SQL query.

Core Sections

Decide whether you are storing UTC or local wall time

The main design question is not string formatting. It is semantics. A Date in JavaScript carries an absolute timestamp, but DATETIME in MySQL is just a date-time value without timezone metadata. If one service stores UTC and another assumes local time, the data starts drifting by whole hours.

For most backend systems, storing UTC is the safer convention. You keep one canonical value in the database and only convert to local time at the display layer.

Format a JavaScript Date as MySQL DATETIME

MySQL expects the form YYYY-MM-DD HH:MM:SS. A small helper can build that from UTC parts.

javascript
1function toMySQLDateTimeUTC(date = new Date()) {
2  const pad = (n) => String(n).padStart(2, "0");
3
4  const year = date.getUTCFullYear();
5  const month = pad(date.getUTCMonth() + 1);
6  const day = pad(date.getUTCDate());
7  const hour = pad(date.getUTCHours());
8  const minute = pad(date.getUTCMinutes());
9  const second = pad(date.getUTCSeconds());
10
11  return `${year}-${month}-${day} ${hour}:${minute}:${second}`;
12}
13
14console.log(toMySQLDateTimeUTC(new Date("2026-03-11T14:30:45Z")));

Using the UTC getters is the critical detail. If you accidentally use getHours() instead of getUTCHours(), the stored value becomes dependent on the server’s local timezone.

Insert it with parameterized SQL

Do not concatenate the formatted string directly into SQL. Use query parameters so quoting and escaping are handled by the driver.

javascript
1import mysql from "mysql2/promise";
2
3function toMySQLDateTimeUTC(date = new Date()) {
4  const pad = (n) => String(n).padStart(2, "0");
5  return `${date.getUTCFullYear()}-${pad(date.getUTCMonth() + 1)}-${pad(date.getUTCDate())} ${pad(date.getUTCHours())}:${pad(date.getUTCMinutes())}:${pad(date.getUTCSeconds())}`;
6}
7
8async function insertEvent(message) {
9  const connection = await mysql.createConnection({
10    host: "localhost",
11    user: "root",
12    database: "demo",
13    password: "secret",
14  });
15
16  const createdAt = toMySQLDateTimeUTC(new Date());
17  await connection.execute(
18    "INSERT INTO events (message, created_at) VALUES (?, ?)",
19    [message, createdAt]
20  );
21
22  await connection.end();
23}

This is cleaner and safer than generating raw SQL strings.

Convert values back to JavaScript carefully

When a MySQL DATETIME string comes back from the database, JavaScript still needs to know how to interpret it. If your policy is that the stored value represents UTC, add the T separator and Z suffix before parsing.

javascript
1function parseMySQLDateTimeAsUTC(datetimeText) {
2  return new Date(datetimeText.replace(" ", "T") + "Z");
3}
4
5const dbValue = "2026-03-11 14:30:45";
6const date = parseMySQLDateTimeAsUTC(dbValue);
7console.log(date.toISOString());
8console.log(date.toLocaleString());

If you skip that policy step and let each service interpret the string differently, bugs show up around timezones, servers in different regions, and daylight saving changes.

DATETIME versus TIMESTAMP

This topic often gets mixed up with MySQL column types. TIMESTAMP has stronger built-in timezone-related behavior in MySQL. DATETIME is more literal. If the value represents a real instant in time, TIMESTAMP may be a better fit in some systems. If the value represents a business-local wall time, such as a schedule entered by a human, DATETIME may be more appropriate.

The important point is consistency. Pick the meaning once, document it, and keep every service aligned with that meaning.

Test round trips, not just formatting

Date-time bugs are often invisible until a value is written, read back, and displayed in another timezone. A round-trip test catches more than a formatting test does.

javascript
1const original = new Date("2026-03-11T14:30:45Z");
2const mysqlValue = toMySQLDateTimeUTC(original);
3const parsed = parseMySQLDateTimeAsUTC(mysqlValue);
4
5console.log(original.toISOString());
6console.log(mysqlValue);
7console.log(parsed.toISOString());

Test cases near midnight, month boundaries, and daylight saving transitions are especially useful because they reveal hidden assumptions quickly.

Common Pitfalls

  • Using local getters such as getHours() when the system expects UTC causes silent timezone drift.
  • Concatenating the date string directly into SQL is unnecessary and error-prone compared with parameterized queries.
  • Treating a MySQL DATETIME value as timezone-aware without defining a policy creates inconsistent behavior across services.
  • Parsing the returned database string without an explicit UTC rule can shift the value depending on the runtime environment.
  • Focusing only on formatting while ignoring DATETIME versus TIMESTAMP semantics leads to the wrong storage type for the business meaning.

Summary

  • MySQL DATETIME expects a YYYY-MM-DD HH:MM:SS string.
  • The real design choice is whether the stored value represents UTC or local wall time.
  • Use UTC formatting and parameterized queries for the most predictable backend behavior.
  • Parse database values back into JavaScript with the same timezone policy you used when storing them.
  • Validate with round-trip tests, not just one-way format checks.

Course illustration
Course illustration

All Rights Reserved.