Waktu Saat Ini MySQL: NOW(), CURDATE(), UTC_TIMESTAMP(), Zona Waktu, dan Praktik Terbaik

目次

1. Dapatkan Waktu Saat Ini di MySQL (Intinya: Cheat Sheet SQL Terpendek)

Jika Anda ingin mendapatkan waktu saat ini di MySQL, hanya ada beberapa fungsi SQL yang perlu Anda ingat.
Berikut adalah jawaban terpendek untuk kata kunci pencarian “MySQL get current time”.

1.1 MySQL tanggal dan waktu saat ini: NOW() / CURRENT_TIMESTAMP

Mengembalikan tanggal + waktu saat ini (YYYY-MM-DD HH:MM:SS).

SELECT NOW();
SELECT CURRENT_TIMESTAMP;

Contoh output

2025-02-01 15:30:45
  • NOW() dan CURRENT_TIMESTAMP biasanya mengembalikan hasil yang sama.
  • Keduanya mengembalikan tanggal dan waktu saat ini.
  • Jika Anda membutuhkan milidetik, gunakan yang berikut.
    SELECT NOW(3);
    

Catatan (kesalahan umum)

  • Bergantung pada pengaturan zona waktu server.
  • Dalam lingkungan UTC, Anda mungkin mendapatkan UTC alih-alih waktu Jepang.
  • Selama eksekusi query, pada dasarnya mengembalikan waktu yang sama (tetap dalam satu pernyataan).

1.2 MySQL tanggal saat ini: CURDATE()

Mengembalikan hanya tanggal (tanpa waktu).

SELECT CURDATE();

Contoh output

2025-02-01

Kasus penggunaan

  • Menanyakan data hari ini
  • Perbandingan tanggal (mis., menyaring hanya catatan hari ini)

Catatan

  • Nilai yang dikembalikan adalah tipe DATE.
  • Tidak cocok ketika Anda membutuhkan pemrosesan waktu dalam hari.

1.3 MySQL waktu saat ini: CURTIME()

Mengembalikan hanya waktu.

SELECT CURTIME();

Contoh output

15:30:45

Kasus penggunaan

  • Pemeriksaan jam kerja
  • Logika percabangan berdasarkan jendela waktu

Catatan

  • Tidak menyertakan informasi tanggal.
  • Tidak dapat digunakan untuk membandingkan dengan kolom tipe DATE.

1.4 MySQL waktu UTC saat ini: UTC_TIMESTAMP()

Mengembalikan waktu dalam UTC (Coordinated Universal Time), terlepas dari pengaturan zona waktu server.

SELECT UTC_TIMESTAMP();

Contoh output

2025-02-01 06:30:45

Kapan Anda harus menggunakannya

  • Layanan global
  • Desain yang menyimpan log secara konsisten dalam UTC

Kesalahan umum

  • Mencampurnya dengan NOW() menyebabkan offset waktu
  • Jika aplikasi mengasumsikan JST, Anda akan melihat perbedaan 9 jam

1.5 MySQL waktu saat ini dengan milidetik: NOW(3) / CURRENT_TIMESTAMP(3)

MySQL 5.6 dan yang lebih baru mendukung detik pecahan.

SELECT NOW(3);
SELECT CURRENT_TIMESTAMP(3);

Contoh output

2025-02-01 15:30:45.123

Catatan untuk penyimpanan

Kolom Anda juga harus mendukung detik pecahan.

DATETIME(3)
TIMESTAMP(3)

Jika Anda menyimpannya ke dalam kolom yang tidak mendukung, bagian pecahan akan dipotong.

1.6 Cheat sheet cepat berdasarkan tujuan

PurposeSQL
Current date and timeSELECT NOW();
Get UTCSELECT UTC_TIMESTAMP();
Date onlySELECT CURDATE();
Time onlySELECT CURTIME();
Get millisecondsSELECT NOW(3);

Ringkasan jebakan umum

  • Waktu ter-offset karena Anda tidak memverifikasi zona waktu
  • Menggunakan NOW(3) tanpa kolom yang mendukung milidetik
  • Mencampur UTC dan waktu lokal
  • Tidak memahami perbedaan antara DATETIME dan TIMESTAMP

MySQL DATETIME と TIMESTAMP の違いを示した図。TIMESTAMPはUTC変換され、DATETIMEは変換されない。

Perbedaan antara MySQL DATETIME dan TIMESTAMP (membandingkan apakah konversi zona waktu terjadi)

2. Perbedaan antara MySQL NOW() dan CURRENT_TIMESTAMP

NOW() dan CURRENT_TIMESTAMP terlihat serupa, tetapi kesalahpahaman tentang kapan menggunakannya dan bagaimana perilakunya dapat dengan mudah menyebabkan bug. Di sini kami merangkum perbedaan, penggunaan yang tepat, dan jebakan umum.

2.1 Mana yang harus Anda gunakan? (penggunaan SELECT / penggunaan DEFAULT)

■ Saat mengambil tanggal/waktu saat ini dalam SELECT

SELECT NOW();
SELECT CURRENT_TIMESTAMP;

Biasanya, keduanya mengembalikan hasil yang sama.

  • Mereka setara (sinonim)
  • Nilai yang dikembalikan setara dengan DATETIME
  • Dipengaruhi oleh pengaturan zona waktu

Intisari praktis

  • Pilih keterbacaan → NOW()
  • Pilih gaya SQL standar → CURRENT_TIMESTAMP

■ Saat mengatur nilai default kolom

CREATE TABLE logs (
    id INT AUTO_INCREMENT PRIMARY KEY,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

Poin utama di sini adalah:

Untuk nilai default, biasanya menggunakan CURRENT_TIMESTAMP.

Beberapa lingkungan mengizinkan NOW() juga, tetapi perilaku dapat berbeda tergantung pada versi MySQL dan mode SQL. Pilihan yang lebih aman adalah CURRENT_TIMESTAMP.

2.2 Penggunaan yang Benar dari DEFAULT / ON UPDATE

Jika Anda ingin memperbarui otomatis stempel waktu “updated at”:

CREATE TABLE logs (
    id INT AUTO_INCREMENT PRIMARY KEY,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
        ON UPDATE CURRENT_TIMESTAMP
);

Perilaku

  • Pada INSERT → menetapkan waktu saat ini untuk created_at / updated_at
  • Pada UPDATE → memperbarui hanya updated_at

Kesalahan umum

  • Tidak mencocokkan presisi pecahan detik saat menggunakan DATETIME
  • Menghadapi batasan MySQL lama dengan beberapa kolom TIMESTAMP (MySQL 5.6 dan sebelumnya memiliki pembatasan)

2.3 Perbedaan Antara NOW() dan SYSDATE() (Penting)

Poin yang mudah terlewat adalah perbedaan dengan SYSDATE().

SELECT NOW(), SYSDATE();

■ Perbedaan perilaku

  • NOW() → tetap pada waktu mulai kueri
  • SYSDATE() → mengembalikan waktu pada saat dipanggil

Contoh:

SELECT NOW(), SLEEP(3), NOW();

NOW() mengembalikan nilai yang sama.

SELECT SYSDATE(), SLEEP(3), SYSDATE();

SYSDATE() menunjukkan perbedaan 3 detik.

2.4 Mana yang harus Anda gunakan?

FunctionBehaviorRecommended use
NOW()Fixed within a queryLogging, consistency-focused
SYSDATE()Call-time valuePrecise real-time retrieval

Mengapa NOW() sering direkomendasikan dalam sistem dunia nyata

  • Menjaga konsistensi di dalam transaksi (mekanisme yang memproses beberapa pernyataan SQL bersama)
  • Lebih aman di lingkungan replikasi

2.5 Kesalahpahaman umum dan masalah

❌ “NOW() dan CURRENT_TIMESTAMP persis sama, jadi Anda tidak perlu memikirkannya.”

→ Perbedaan dapat muncul pada nilai default atau perilaku pembaruan, tergantung pada lingkungan.

❌ “SYSDATE() lebih akurat, jadi selalu lebih baik.”

→ Hal ini dapat menyebabkan masalah di lingkungan replikasi.

❌ Tidak memverifikasi zona waktu

SHOW VARIABLES LIKE '%time_zone%';

Jika Anda menggunakannya tanpa memeriksa, Anda dapat mendapatkan selisih waktu.

2.6 Praktik terbaik praktis

  • Pengambilan SELECT → NOW()
  • Default kolom → CURRENT_TIMESTAMP
  • Auto-pembaruan → ON UPDATE CURRENT_TIMESTAMP
  • Fokus pada konsistensi → default ke NOW()
  • Desain berbasis UTC → TIMESTAMP + simpan dalam UTC
  1. Pemformatan Waktu Saat Ini MySQL (DATE_FORMAT / TIME_FORMAT)
    Setelah mengambil waktu saat ini di MySQL, sangat umum untuk mengubah format tampilan.
    Untuk maksud pencarian “format waktu saat ini MySQL,” fungsi terpenting yang harus dipahami adalah DATE_FORMAT().

3.1 Pemformatan datetime MySQL: DATE_FORMAT(NOW(), …)

Sintaks dasar:
SELECT DATE_FORMAT(target_datetime, 'format_string');

Contoh: memformat waktu saat ini
SELECT DATE_FORMAT(NOW(), '%Y-%m-%d %H:%i:%s');

Contoh output
2025-02-01 15:30:45

Spesifikator format yang sering digunakan

SpesifikatorMaknaContoh
%YTahun (4 digit)2025
%mBulan (2 digit)02
%dHari (2 digit)01
%HJam (format 24‑jam)15
%hJam (format 12‑jam)03
%iMenit30
%sDetik45
%pAM/PMPM

3.2 Mengonversi ke format gaya Jepang atau format 12‑jam

■ Format gaya Jepang
SELECT DATE_FORMAT(NOW(), '%Y-%m-%d %H:%i');

Contoh output:
2025-02-01 15:30

■ Format 12‑jam + AM/PM
SELECT DATE_FORMAT(NOW(), '%Y-%m-%d %h:%i:%s %p');

Contoh output:
2025-02-01 03:30:45 PM

3.3 Pemformatan hanya waktu MySQL: TIME_FORMAT()

Fungsi pemformatan khusus untuk data tipe TIME.
SELECT TIME_FORMAT(CURTIME(), '%H:%i');

Contoh output:
15:30

Catatan
TIME_FORMAT() hanya untuk tipe TIME
Untuk DATETIME, gunakan DATE_FORMAT()

3.4 Konversi string → datetime: STR_TO_DATE()

Untuk mengubah data string menjadi tipe datetime:
SELECT STR_TO_DATE('2025-02-01 15:30:45', '%Y-%m-%d %H:%i:%s');

Contoh output:
2025-02-01 15:30:45

Kesalahan umum
Ketidaksesuaian format mengembalikan NULL
Membingungkan %m dan %c (bulan berisi nol vs tidak berisi nol)

3.5 Poin penting dalam produksi

❌ Jangan membandingkan setelah pemformatan
Contoh yang buruk:
WHERE DATE_FORMAT(created_at, '%Y-%m-%d') = '2025-02-01';

Ini tidak disarankan karena indeks menjadi tidak efektif (kinerja query menurun).

Disarankan:
WHERE created_at >= '2025-02-01' AND created_at < '2025-02-02';

❌ Jangan terlalu memformat di sisi DB
Pada aplikasi web, pemformatan untuk tampilan biasanya lebih fleksibel di sisi aplikasi.
Database sebaiknya fokus pada “penyimpanan dan perhitungan”.

3.6 Pemformatan dengan milidetik

SELECT DATE_FORMAT(NOW(3), '%Y-%m-%d %H:%i:%s.%f');
%f mewakili mikrodetik (6 digit).

Catatan
Jika kolom bukan DATETIME(3) atau serupa, bagian pecahan akan dipotong.
Tersedia sejak MySQL 5.6 ke atas.

3.7 Ringkasan berdasarkan tujuan pemformatan

TujuanFungsi
Mengubah format tampilanDATE_FORMAT
Memformat hanya waktuTIME_FORMAT
Konversi string → datetimeSTR_TO_DATE
Menampilkan milidetik%f

4. Penambahan/Pengurangan Tanggal dan Waktu MySQL (DATE_ADD / DATE_SUB)

Meskipun Anda dapat mengambil waktu saat ini, Anda tidak dapat menggunakannya secara efektif dalam produksi tanpa perhitungan tanggal/waktu seperti “X hari kemudian” atau “X jam yang lalu.”
Berikut penjelasan cara menggunakan DATE_ADD() dan DATE_SUB() dengan waktu saat ini di MySQL.

4.1 Penambahan datetime MySQL: DATE_ADD()

Sintaks dasar:
SELECT DATE_ADD(base_datetime, INTERVAL value unit);

Contoh: 7 hari dari sekarang
SELECT DATE_ADD(NOW(), INTERVAL 7 DAY);

Contoh: 2 jam kemudian
SELECT DATE_ADD(NOW(), INTERVAL 2 HOUR);

Unit yang sering digunakan

UnitMakna
SECONDDetik
MINUTEMenit
HOURJam
DAYHari
MONTHBulan
YEARTahun

4.2 Pengurangan datetime MySQL: DATE_SUB()

Sintaks dasar:
SELECT DATE_SUB(base_datetime, INTERVAL value unit);

Contoh: 30 hari yang lalu
SELECT DATE_SUB(NOW(), INTERVAL 30 DAY);

Contoh: 1 jam yang lalu
SELECT DATE_SUB(NOW(), INTERVAL 1 HOUR);

Kasus penggunaan
Pemeriksaan kedaluwarsa
Menghapus log lama
* Mengambil data terbaru

4.3 Pola produksi yang umum

■ Mengambil data dari 24 jam terakhir
SELECT * FROM logs WHERE created_at >= DATE_SUB(NOW(), INTERVAL 1 DAY);

■ Menetapkan batas waktu 7 hari kemudian
INSERT INTO tasks (deadline) VALUES (DATE_ADD(NOW(), INTERVAL 7 DAY));

4.4 Kesalahan umum dan tindakan pencegahan
❌ Menerapkan fungsi pada kolom
Contoh buruk:
WHERE DATE(created_at) = CURDATE();
Ini menonaktifkan indeks (optimasi kinerja kueri).
Disarankan:
WHERE created_at >= CURDATE() AND created_at < DATE_ADD(CURDATE(), INTERVAL 1 DAY);
❌ Mengabaikan zona waktu
NOW() didasarkan pada zona waktu server
Jika Anda menyimpan dalam UTC, gunakan UTC_TIMESTAMP() sebagai dasar
Contoh:
SELECT DATE_ADD(UTC_TIMESTAMP(), INTERVAL 1 DAY);
❌ Perangkap penambahan bulan
SELECT DATE_ADD('2025-01-31', INTERVAL 1 MONTH);
→ Karena penyesuaian akhir bulan, tanggal dapat berubah.
(Hasilnya mungkin menjadi 2025-02-28 tergantung pada lingkungan.)
Pahami spesifikasi sebelum menggunakan perhitungan berbasis bulan.
4.5 Penambahan dengan milidetik
SELECT DATE_ADD(NOW(3), INTERVAL 500 MILLISECOND);
※ MySQL tidak mendukung MILLISECOND secara langsung.
Tentukan dalam mikrodetik:
SELECT DATE_ADD(NOW(3), INTERVAL 500000 MICROSECOND);
4.6 Praktik terbaik
Standarkan penggunaan NOW() atau UTC_TIMESTAMP() sebagai dasar Anda
Jangan menerapkan fungsi pada kolom di klausa WHERE
Pahami perilaku penambahan berbasis bulan
Jika presisi diperlukan, gunakan DATETIME(3) atau lebih tinggi

5. Menghitung Selisih Tanggal/Waktu di MySQL (DATEDIFF / TIMESTAMPDIFF)

Di sistem produksi, sekadar mengambil waktu saat ini tidak cukup. Anda sering perlu menghitung berapa hari yang telah berlalu atau berapa jam yang tersisa.

5.1 Menghitung selisih tanggal: DATEDIFF()

DATEDIFF() menghitung selisih dalam hari antara dua tanggal.

SELECT DATEDIFF('2025-02-10', '2025-02-01');

Hasil

9

Poin penting

  • Mengembalikan selisih dalam hari saja
  • Bagian waktu diabaikan
  • Hasil dapat bernilai negatif

Contoh: menghitung hari sejak pembuatan

SELECT DATEDIFF(NOW(), created_at)
FROM users;

5.2 Menghitung selisih berdasarkan satuan: TIMESTAMPDIFF()

TIMESTAMPDIFF() memungkinkan Anda menentukan satuan.

SELECT TIMESTAMPDIFF(unit, start_datetime, end_datetime);

Contoh: selisih jam

SELECT TIMESTAMPDIFF(HOUR, '2025-02-01 10:00:00', '2025-02-01 15:00:00');

Hasil

5

Satuan umum

UnitMeaning
SECONDSeconds
MINUTEMinutes
HOURHours
DAYDays
MONTHMonths
YEARYears

Contoh: menghitung menit sejak login

SELECT TIMESTAMPDIFF(MINUTE, login_at, NOW())
FROM users;

5.3 Kasus penggunaan produksi

  • Pemeriksaan batas waktu sesi
  • Pemeriksaan kedaluwarsa langganan
  • Menghitung waktu yang telah berlalu dalam log
  • Logika pembatasan laju

5.4 Kesalahan umum

❌ Menggunakan DATEDIFF ketika presisi waktu diperlukan

DATEDIFF() mengabaikan jam dan menit.

❌ Membalik urutan argumen

Urutannya adalah:

TIMESTAMPDIFF(unit, start, end)

Jika dibalik, hasilnya menjadi negatif.

❌ Mengabaikan zona waktu

Jika mencampur UTC dan waktu lokal, selisihnya dapat tidak tepat.

5.5 Praktik terbaik

  • Gunakan TIMESTAMPDIFF() ketika presisi waktu penting
  • Gunakan DATEDIFF() untuk perhitungan hari sederhana
  • Pastikan penggunaan zona waktu konsisten
  • Standarkan penggunaan UTC dalam sistem terdistribusi

6. Kuery Rentang Tanggal Menggunakan Waktu Saat Ini

Salah satu kebutuhan dunia nyata yang paling umum adalah mengambil catatan dalam rentang waktu tertentu, seperti:

  • Catatan hari ini
  • 7 hari terakhir
  • 24 jam terakhir
  • Bulan ini

6.1 Mengambil catatan hari ini (ramah indeks)

SELECT *
FROM logs
WHERE created_at >= CURDATE()
  AND created_at < DATE_ADD(CURDATE(), INTERVAL 1 DAY);

Mengapa ini benar

  • Tidak ada fungsi yang diterapkan pada kolom
  • Indeks tetap dapat digunakan
  • Kuery rentang yang efisien

6.2 7 hari terakhir

SELECT *
FROM logs
WHERE created_at >= DATE_SUB(NOW(), INTERVAL 7 DAY);

6.3 24 jam terakhir

SELECT *
FROM logs
WHERE created_at >= DATE_SUB(NOW(), INTERVAL 1 DAY);

6.4 Bulan ini

SELECT *
FROM logs
WHERE created_at >= DATE_FORMAT(NOW(), '%Y-%m-01')
  AND created_at < DATE_ADD(DATE_FORMAT(NOW(), '%Y-%m-01'), INTERVAL 1 MONTH);

Pada sistem produksi, seringkali lebih baik menghitung batas pada sisi aplikasi dan mengirimkannya sebagai parameter.

6.5 Kesalahan kinerja umum

❌ Menerapkan fungsi pada kolom yang diindeks

WHERE DATE(created_at) = CURDATE();

Ini mencegah penggunaan indeks dan menyebabkan pemindaian tabel penuh.

❌ Menggunakan BETWEEN secara sembarangan

BETWEEN bersifat inklusif dan dapat menyebabkan masalah selisih satu detik.

6.6 Ringkasan praktik terbaik

  • Selalu gunakan kondisi rentang untuk penyaringan tanggal
  • Hindari menerapkan fungsi pada kolom yang diindeks
  • Lebih pilih penyimpanan UTC dalam sistem global
  • Jadilah eksplisit tentang asumsi zona waktu