Database
 sql >> Teknologi Basis Data >  >> RDS >> Database

Apa Masalah Tahun 2038?

Masalah Tahun 2038 (juga disebut sebagai bug Y2K38) mengacu pada masalah yang mungkin dihadapi beberapa sistem komputer saat menangani masa lalu 2038-01-19 03:14:07.

Banyak sistem komputer, seperti sistem berbasis Unix dan Unix, tidak menghitung waktu menggunakan kalender Gregorian. Mereka menghitung waktu sebagai jumlah detik sejak 1 Januari 1970. Oleh karena itu, dalam sistem ini, waktu direpresentasikan sebagai angka besar (yaitu jumlah detik yang berlalu sejak 1970-01-01 00:00:00). Ini biasanya disebut sebagai waktu Epoch, waktu Unix, waktu Unix Epoch, atau waktu POSIX. Saat saya menulis ini, waktu Unix adalah 1560913841. Dan saat saya menulis baris berikutnya, waktu Unix bertambah menjadi 1560913879.

Masalah 2038 disebabkan oleh fakta bahwa banyak sistem menyimpan nomor ini sebagai bilangan bulat biner 32-bit yang ditandatangani. Rentang bilangan bulat 32-bit yang ditandatangani adalah -2.147.483.648 hingga 2.147.483.647. Artinya waktu Epoch terbaru yang dapat direpresentasikan adalah 2147483647. Ini akan terjadi pada 03:14:07 pada hari Selasa, 19 Januari 2038.

Setelah itu, hasilnya akan sangat tergantung pada sistem. Dalam banyak sistem, luapan bilangan bulat akan terjadi, dan waktu berikutnya akan membungkus dan disimpan secara internal sebagai angka negatif. Hasilnya, satu detik kemudian, waktu akan ditafsirkan sebagai 13 Desember 1901 daripada 19 Januari 2038.

Namun, Anda juga bisa mendapatkan hasil yang bervariasi, tergantung pada aplikasi yang digunakan. Meskipun sistem operasi Anda tidak bermasalah, kode Anda sendiri mungkin masih bermasalah. Misalnya, jika Anda telah menulis kode khusus untuk mengembalikan waktu Unix, dan Anda menyimpannya dalam bilangan bulat 4 byte yang ditandatangani, Anda akan mengalami masalah. Dalam kasus seperti itu, Anda hanya perlu menulis ulang kode untuk menggunakan bilangan bulat 8 byte.

Karena situs web ini berisi tentang basis data, berikut adalah beberapa contoh basis data.

Contoh 1 – MySQL

Di MySQL, TIMESTAMP tipe data mendukung tanggal/waktu dari '1970-01-01 00:00:01.000000' UTC hingga '2038-01-19 03:14:07.999999'. Oleh karena itu, Anda dapat mengatakan bahwa database apa pun yang menggunakan tipe data ini memiliki bug Y2K38.

MySQL juga memiliki fungsi bawaan yang disebut UNIX_TIMESTAMP() yang, seperti yang Anda duga, mengembalikan stempel waktu Unix.

UNIX_TIMESTAMP() function menerima argumen opsional yang memungkinkan Anda menentukan tanggal yang akan digunakan untuk waktu Unix (yaitu jumlah detik dari '1970-01-01 00:00:00' UTC hingga waktu yang Anda tentukan). Rentang nilai argumen yang valid sama dengan TIMESTAMP tipe data, yaitu '1970-01-01 00:00:01.000000' UTC hingga '2038-01-19 03:14:07.999999' UTC. Jika Anda melewatkan tanggal di luar rentang ke fungsi ini, fungsi ini akan mengembalikan 0 .

Inilah yang terjadi jika Anda mencoba menggunakan fungsi ini untuk mengembalikan waktu Unix dari tanggal melewati '2038-01-19 03:14:07.999999':

SELECT UNIX_TIMESTAMP('2038-01-20') Result;

Hasil:

+--------+
| Result |
+--------+
|      0 |
+--------+

Kami mendapatkan 0 karena argumen tanggal berada di luar rentang yang didukung.

Laporan bug terkait diajukan untuk tim MySQL pada tahun 2005 (walaupun beberapa spesifikasinya tampak berbeda), dan hingga tulisan ini dibuat, masih belum ditangani.

Masalah serupa juga diangkat untuk mengatasi batasan dengan TIMESTAMP tipe data, yang juga belum ditangani.

Contoh 2 – SQL Server

SQL Server saat ini tidak memiliki yang setara dengan UNIX_TIMESTAMP MySQL fungsi. Oleh karena itu, jika Anda perlu mengembalikan waktu Epoch, Anda harus melakukan sesuatu seperti ini:

SELECT DATEDIFF(SECOND,'1970-01-01', GETUTCDATE());

Ini bagus untuk tanggal sebelum masalah 2038. Setelah tanggal tersebut, Anda akan mengalami masalah, karena DATEDIFF() fungsi mengembalikan hasil sebagai int tipe data. int tipe data memiliki rentang -2^31 (-2.147.483.648) hingga 2^31-1 (2.147.483.647).

Inilah yang terjadi jika saya mencoba mengembalikan waktu Epoch lebih lambat dari '2038-01-19 03:14:07':

SELECT DATEDIFF(SECOND,'1970-01-01', '2038-01-19 03:14:08') AS 'Result';

Hasil:

The datediff function resulted in an overflow. The number of dateparts separating two date/time instances is too large. Try to use datediff with a less precise datepart.

Untungnya, ada juga DATEDIFF_BIG() fungsi, yang melakukan hal yang persis sama, kecuali mengembalikan hasilnya sebagai besar tipe data.

Jadi kita dapat menulis ulang contoh sebelumnya menjadi berikut untuk mengatasi masalah ini:

SELECT DATEDIFF_BIG(SECOND,'1970-01-01 00:00:00', '2038-01-19 03:14:08') AS 'Result';

Hasil:

+------------+
| Result     |
|------------|
| 2147483648 |
+------------+

besar tipe data menggunakan 8 byte (berlawanan dengan 4 byte untuk int ), jadi Anda perlu memutuskan apakah akan beralih ke DATEDIFF_BIG() atau tidak sekarang atau nanti. Jika aplikasi Anda berhubungan dengan tanggal yang akan datang, mungkin lebih bijaksana untuk melakukannya lebih awal daripada nanti.


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. 5 Tips Tanpa Repot untuk Menggunakan Pernyataan SQL UPDATE dengan JOIN

  2. Spool Indeks Eager dan Pengoptimal

  3. Cara Menjadi Desainer Basis Data

  4. Fungsi Penyembunyian Data Mana yang Harus Saya Gunakan?

  5. Migrasi Database ke Azure SQL Database