AD JB Toolbox 01 EN

MariaDB Tutorial / Store Dates and Times with DATE, DATETIME, and TIMESTAMP

DATE stores a date, DATETIME stores calendar date-and-time fields, and TIMESTAMP represents a time that is converted according to the connection’s time zone. Decide whether you need a local wall-clock value or an event’s instant before choosing a type; the same input can produce different TIMESTAMP displays in different sessions.

Distinguish a date, wall-clock time, and an instant

Type Example purpose Time-zone behavior
DATE A birthday or a reservation date Does not itself store a time or time-zone identity
DATETIME Calendar fields such as 2026-10-13 09:00:00 Changing the session time zone alone does not convert the value
TIMESTAMP A logged or received event Converts between the session time zone and UTC on input and output

Coordinated Universal Time (UTC) is a shared reference for comparing instants. Korea’s +09:00 offset means that 09:00 in Korea and 00:00 UTC on that date describe the same instant. Adding the letters UTC to a string does not configure a database connection. Use Calculate Date Intervals, Differences, and Display Formats for calculations and period boundaries, and Inspect Server Settings, SQL Modes, Time Zones, and Logs to compare per-connection time zones with persistent settings.

A DATETIME wall-clock value does not by itself preserve a region’s time-zone or daylight-saving rules. An application may normalize values to UTC or store local fields together with a zone identifier, depending on its purpose. TIMESTAMP also does not retain the name of the original input time zone.

Check the server version and connection time zone

Connect as course_user to the practice server prepared in the installation guides, with the shopcourse database available. The command-line client and SQL-file guide explains the connection and SOURCE command. Run these checks inside that connection, not in the operating-system shell:

SELECT VERSION() AS server_version, DATABASE() AS selected_database;
USE shopcourse;
SELECT DATABASE() AS selected_database;

The selected database should be shopcourse. Save a complete normal example as a UTF-8 .sql file and run it with SOURCE and its actual local path. Keep the intentionally failing statements separate: an error can stop a source file. Use a learning instance, not a connection containing production data.

SELECT @@SESSION.time_zone AS session_zone,
       @@GLOBAL.time_zone AS global_zone,
       @@system_time_zone AS system_zone;

SESSION is the current connection; the global setting supplies a default for new connections. SYSTEM is interpreted using the server’s operating-system time zone, so do not infer the actual connection setting from the machine’s location. This exercise uses explicit +09:00 and +00:00 offsets and therefore does not need named time-zone tables.

DATE and DATETIME support years from 1000 through 9999, while TIMESTAMP’s upper limit depends on the server version. Before MariaDB 11.5, its ordinary range ends at 2038-01-19 03:14:07 UTC; from 11.5, the upper limit is 2106-02-07 06:28:15 UTC. The lower bound is 1970-01-01 00:00:01 UTC, separate from special zero values. Check your actual SELECT VERSION() against the version-specific TIMESTAMP limits. Distribution and vendor packages may differ.

Insert once and change only the session time zone

The complete time_lab example inserts the same calendar fields into DATETIME and TIMESTAMP, then changes one setting: the session time zone. It saves both session settings first. Explicit TIMESTAMP NULL DEFAULT NULL avoids relying on implicit first-TIMESTAMP defaults that differ by version and configuration; the table-definition guide explains why inspecting actual definitions matters.

USE shopcourse;
SET @saved_sql_mode = @@SESSION.sql_mode;
SET SESSION sql_mode = 'STRICT_TRANS_TABLES';
SET @saved_time_zone = @@SESSION.time_zone;
SET SESSION time_zone = '+09:00';
CREATE TABLE time_lab (
  item_id INT PRIMARY KEY,
  event_date DATE NOT NULL,
  wall_time DATETIME NOT NULL,
  instant_time TIMESTAMP NULL DEFAULT NULL
) ENGINE=InnoDB;
INSERT INTO time_lab VALUES
  (1, '2026-10-13', '2026-10-13 09:00:00', '2026-10-13 09:00:00');
SELECT item_id, event_date, wall_time, instant_time FROM time_lab;
SET SESSION time_zone = '+00:00';
SELECT item_id, event_date, wall_time, instant_time FROM time_lab;
SET SESSION time_zone = '+09:00';
SELECT item_id, wall_time, instant_time FROM time_lab;
Query time zone event_date wall_time instant_time
+09:00 after insert 2026-10-13 2026-10-13 09:00:00 2026-10-13 09:00:00
+00:00 2026-10-13 2026-10-13 09:00:00 2026-10-13 00:00:00
+09:00 restored 2026-10-13 2026-10-13 09:00:00 2026-10-13 09:00:00

The TIMESTAMP column has not become two different events. The same instant is displayed for two connection offsets. DATETIME retains its calendar fields. Check the DATETIME definition and TIMESTAMP conversion rules when deciding which behavior an application needs.

Specify automatic values and fractional seconds deliberately

Use DEFAULT CURRENT_TIMESTAMP explicitly when a column should receive a creation time automatically. ON UPDATE CURRENT_TIMESTAMP is a separate choice for automatic changes on updates. A last-modified column does not automatically represent the time an external event actually occurred.

DATETIME(6) and TIMESTAMP(6) specify up to six fractional-second digits. The 6 describes precision below the second, not the year range or total string length. Match column and default-expression precision deliberately, and do not assume every record needs microseconds.

Use unambiguous formats such as YYYY-MM-DD and YYYY-MM-DD HH:MM:SS. Passing locale-dependent strings such as 10/11/26, or storing dates as arbitrary strings, makes conversion and comparison harder to reason about. The DATE reference gives the date type’s format and range.

Diagnose invalid dates and unexpected offsets

After the normal file, run this intentional failure separately in the same strict-mode connection. February 30 does not exist:

INSERT INTO time_lab VALUES (2, '2026-02-30', '2026-10-13 09:00:00', NULL);

Expect an Incorrect date value error, with one row still in time_lab. SQL modes affect invalid-date and zero-value handling; changing the mode merely to bypass an error can change the data’s meaning. Review the SQL mode documentation for the conditions.

If a query is unexpectedly nine hours different, inspect the column type and @@SESSION.time_zone first. Before applying an UPDATE that adds or subtracts nine hours, check whether the application and connection are converting the value twice.

A fixed offset cannot represent an entire region’s daylight-saving history. Named-zone handling needs suitable server time-zone data and an application policy. This exercise deliberately demonstrates fixed-offset conversion only.

Restore the original connection settings

SET SESSION time_zone = @saved_time_zone;
SET SESSION sql_mode = @saved_sql_mode;
SELECT @@SESSION.time_zone, @@SESSION.sql_mode;

Restore these session settings in the same connection that saved the variables. If you disconnected, those variables no longer contain the original values; inspect the new connection instead of applying an empty saved variable.

Before repeating the exercise, use SELECT DATABASE(); and SHOW CREATE TABLE table_name;, substituting each actual table name, to confirm that the targets are the disposable tables created here. Back up any data you need to keep. Only after verifying those targets, remove them with:

DROP TABLE shopcourse.time_lab;

This removes both the named tables and their rows. A data-definition statement such as DROP TABLE is not undone by an ordinary ROLLBACK. You can then rerun the complete normal example. The existing products table from the first product-table exercise is deliberately outside this reset.

More in This Category
MariaDB Tutorial / Compare NULL Correctly with IS NULL and COALESCE

MariaDB Tutorial / Compare NULL Correctly with IS NULL and COALESCE

Distinguish NULL from empty strings and zero, filter missing notes with IS NULL, choose COALESCE fallbacks and avoid NULL-related NOT IN surprises using reproducible product queries.

MariaDB Tutorial / Filter Rows with WHERE, AND, OR, IN, BETWEEN, and LIKE

MariaDB Tutorial / Filter Rows with WHERE, AND, OR, IN, BETWEEN, and LIKE

Build clear MariaDB filters using comparisons, grouped AND/OR conditions, IN lists, inclusive ranges and escaped LIKE patterns. Check expected product IDs and investigate missing or extra rows.

MariaDB Tutorial / Start InnoDB Transactions with COMMIT and ROLLBACK

MariaDB Tutorial / Start InnoDB Transactions with COMMIT and ROLLBACK

Run a complete two-row InnoDB transaction, compare rollback and commit, and verify affected counts and balances. Understand connection scope, error handling, locks and implicit-commit boundaries.

MariaDB Tutorial / Sort and Paginate Results with ORDER BY and LIMIT

MariaDB Tutorial / Sort and Paginate Results with ORDER BY and LIMIT

Create deterministic top lists, compare OFFSET and keyset pagination, and control NULL placement in MariaDB. Observe tied prices and understand concurrency and large-offset limitations.

MariaDB Tutorial / Select Columns, Aliases, Calculations, and DISTINCT

MariaDB Tutorial / Select Columns, Aliases, Calculations, and DISTINCT

Read explicit columns, label results with AS, calculate per-product stock values and understand how DISTINCT treats complete row combinations. Compare expected values and troubleshoot aliases and filters.

MariaDB Tutorial / Store Dates and Times with DATE, DATETIME, and TIMESTAMP

MariaDB Tutorial / Store Dates and Times with DATE, DATETIME, and TIMESTAMP

Choose DATE, DATETIME, or TIMESTAMP by the meaning of a time value. Run a controlled time-zone comparison, check version-dependent limits and invalid dates, and restore the original session settings.

MariaDB Tutorial / Query Hierarchies and Prevent Cycles with Recursive CTEs

MariaDB Tutorial / Query Hierarchies and Prevent Cycles with Recursive CTEs

Traverse a complete category tree with WITH RECURSIVE, depth, and path tracking. Change the traversal bound, introduce a controlled cycle, and distinguish a finite result from a complete and valid hierarchy.

MariaDB Tutorial / Restore a Backup into a Separate Database and Verify It

MariaDB Tutorial / Restore a Backup into a Separate Database and Verify It

Review a SQL dump, restore it into a verified empty database and compare object definitions, rows and goods totals. Handle source-file errors, compatibility and partial-restoration states explicitly.

MariaDB Tutorial / Define Input Rules with NULL, DEFAULT, NOT NULL, and CHECK

MariaDB Tutorial / Define Input Rules with NULL, DEFAULT, NOT NULL, and CHECK

Distinguish missing values, empty strings, defaults, and required inputs in MariaDB. Run valid and deliberately invalid inserts, inspect CHECK enforcement, and restore settings without touching existing product data.

MariaDB Tutorial / Build, Secure, Back Up, and Verify an Order Database

MariaDB Tutorial / Build, Secure, Back Up, and Verify an Order Database

Complete an order-database workflow using constrained tables, a limited app account and a checked stock transaction. Define and compare committed-state backup and restoration criteria, including denied operations.