6 poin oleh GN⁺ 2026-01-13 | 1 komentar | Bagikan ke WhatsApp
  • Menyoroti ketidaklengkapan dan inkonsistensi objek Date di JavaScript, serta memperkenalkan Temporal API sebagai penggantinya
  • Date bekerja sebagai objek yang dapat diubah (mutable object) sehingga tidak selaras dengan konsep tanggal yang sebenarnya, dan memiliki masalah struktural seperti error parsing serta keterbatasan penanganan zona waktu
  • Temporal menyediakan model penanganan tanggal dan waktu baru berbasis immutable, dengan kelas-kelas yang lebih terperinci seperti PlainDate, ZonedDateTime, Duration
  • Metode-metode di Temporal tidak memodifikasi objek yang ada, melainkan mengembalikan objek baru, sehingga memungkinkan operasi chaining yang jelas dan aman
  • Temporal saat ini berada pada tahap standardisasi 3 (Stage 3) dan didukung secara eksperimental di browser modern seperti Chrome dan Firefox

Masalah pada objek Date di JavaScript

  • Konstruktor Date menimbulkan kebingungan karena aturan parsing yang tidak konsisten dan pengindeksan yang tidak intuitif
    • Contoh: bulan (month) dimulai dari 0, tetapi hari (day) dan tahun (year) dimulai dari 1
    • String "99" ditafsirkan sebagai tahun 1999, sedangkan "100" ditafsirkan sebagai tahun 0100, menunjukkan kurangnya konsistensi
  • Date dirancang dengan fokus pada waktu (time) dan disimpan secara internal sebagai Unix timestamp (dalam milidetik)
  • Dukungan zona waktu (time zone) terbatas, serta tidak mengenali daylight saving time (DST) maupun kalender non-Gregorian
  • Karena keterbatasan ini, ketergantungan pada pustaka pihak ketiga besar seperti Moment.js dan date-fns menjadi hal umum, yang dapat berujung pada penurunan performa

Benturan antara immutability dan konsep referensi

  • Nilai primitif (primitive) di JavaScript bersifat immutable dan disimpan sebagai nilai itu sendiri, sedangkan objek (object) disimpan sebagai referensi dan dapat diubah
  • Date adalah objek yang dibuat melalui constructor, sehingga bersifat mutable
    • Contoh: saat setMonth() atau setDate() dipanggil, objek asli akan langsung berubah
  • Akibatnya, dapat terjadi perubahan nilai tak terduga antar-variabel yang mereferensikan objek yang sama
    • Contoh: jika fungsi menerima today sebagai argumen lalu mengubah tanggal di dalamnya, maka today asli juga ikut berubah

Temporal: API tanggal dan waktu yang baru

  • Temporal adalah namespace object, bukan constructor, dengan struktur yang mirip Math
    • Komponen utama: PlainDate, PlainDateTime, PlainTime, ZonedDateTime, Duration, Now, dan lainnya
  • Temporal.Now mengembalikan berbagai bentuk waktu saat ini
    • plainDateISO() → tanggal dalam format ISO
    • zonedDateTimeISO() → waktu dengan zona waktu
  • Objek Temporal menyediakan sistem metode yang jelas
    • Operasi satuan eksplisit dapat dilakukan dengan add({ days: 1 }), subtract({ years: 2 }), dan sebagainya
    • Objek lama tidak dimodifikasi, melainkan mengembalikan objek baru, sehingga immutability tetap terjaga

Cara kerja dan keunggulan Temporal

  • Objek Temporal tetap bertipe objek, tetapi mengikuti pola penggunaan immutable yang memang dirancang demikian
    • Contoh: today.add({ days: 1 }) mengembalikan objek tanggal baru, sementara today asli tidak berubah
  • Menyediakan sintaks yang lebih ringkas dan jelas dibanding Date
    • Contoh:
      const today = Temporal.Now.plainDateISO();  
      console.log(`Tomorrow will be ${ today.add({ days: 1 }) }. Today is ${ today }.`);  
      // hasil: Tomorrow will be 2026-01-01. Today is 2025-12-31.  
      
  • Sesuai dengan kebutuhan modern seperti penentuan zona waktu, perhitungan durasi, dan pemeliharaan format ISO
  • Melalui method chaining seperti add, subtract, since, dan until, perhitungan tanggal yang kompleks dapat diekspresikan dengan ringkas

Status standardisasi dan prospek ke depan

  • Temporal telah mencapai ECMAScript proposal Stage 3, yaitu tahap ketika implementasi di browser sudah direkomendasikan
  • Dukungan eksperimental sudah dimulai di Chrome dan Firefox, dan browser lain diperkirakan akan menyusul
  • Developer sudah bisa berpartisipasi dalam penyempurnaan spesifikasi mulai sekarang melalui pengujian dan pemberian feedback
  • Date akan tetap ada, tetapi ke depannya Temporal diperkirakan menjadi cara default untuk menangani tanggal
  • Artikel ditutup dengan kalimat bahwa “ini seharusnya sudah diganti pada 1995, tetapi setidaknya sekarang adalah waktu yang tepat untuk Temporal.Now”

1 komentar

 
GN⁺ 2026-01-13
Opini Hacker News
  • Artikel ini membahas berbagai perilaku aneh dari konstruktor Date di JavaScript
    Secara khusus dijelaskan bahwa format 'YYYY-MM-DD' ditafsirkan sebagai tengah malam UTC, sehingga di zona waktu lokal bisa bergeser satu hari
    Awalnya, dalam ISO 8601 jika zona waktu tidak ditentukan maka seharusnya dianggap sebagai waktu lokal, tetapi karena kesalahan saat penulisan spesifikasi ES5, format ini diperlakukan sebagai “Z” (UTC)
    Setelah itu sempat ingin diperbaiki di ES2015, namun karena sangat banyak situs web bergantung pada perilaku lama yang salah tersebut, perubahan itu dibatalkan demi kompatibilitas web
    Untuk detail lebih lanjut, lihat bagian Broken Parser

    • Akan bagus jika dulu ada direktif 'strict datetime' seperti 'use strict'
      Dengan begitu, perilaku yang benar bisa diterapkan secara opsional tanpa menimbulkan masalah inkompatibilitas dengan kode lama
      Atau bisa juga lewat pendekatan seperti import Date from 'browser:date', yaitu memanggil objek global yang telah diperbaiki lewat modul internal
    • Saya juga dulu pernah memisahkan string secara manual untuk membuat objek tanggal tanpa zona waktu
      Untuk nilai seperti ulang tahun yang hanya bermakna sebagai tanggal, tidak masuk akal jika berubah hanya karena zona waktu
      Dulu Outlook pernah menyimpan ulang tahun beserta zona waktunya, jadi setiap kali pindah negara, tanggal ulang tahunnya ikut bergeser satu hari
    • Ungkapan “dikorbankan di altar kompatibilitas web” terasa berkesan
      Tapi adakah alternatifnya? Memaksa percabangan berdasarkan versi browser seperti era IE5 terdengar malah lebih buruk
    • Jika melihat situs jsdate.wtf, kita bisa langsung merasakan sendiri perilaku-perilaku ganjil dari JS Date
    • Kalau dipikirkan bahwa masalah-masalah seperti ini menjadi sumber dari begitu banyak bug kecil, rasanya lucu sekaligus menyedihkan
  • Saya benar-benar iri dengan cara Rails dan Ruby menangani waktu
    API seperti Time.current.in_time_zone('America/Los_Angeles') + 3.days - 4.months + 1.hour terasa intuitif dan kuat
    Ruby melakukan overload pada objek Time sebagai satu objek yang konsisten, sehingga hampir tidak perlu memikirkan konversi atau casting
    Di JS, alangkah enaknya jika bisa menulis sesederhana new Date().add({ days: 1 })

    • Namun ada juga yang mempertanyakan apakah sintaks seperti “3.days - 4.months + 1.hour” benar-benar bagus
      Selain itu, pendekatan overload pada pustaka inti juga masih bisa diperdebatkan apakah benar-benar ide yang baik
  • Sayang sekali Safari masih belum mendukung Temporal API
    Semoga tahun depan sudah ada dukungannya

  • JavaScript Date memang punya banyak masalah, tetapi fakta bahwa ia adalah sebuah objek sendiri menurut saya bukan masalah besar
    Akan lebih baik kalau objeknya immutable, tetapi objek yang mutable lalu berubah bukan sesuatu yang mengejutkan

    • Masalahnya adalah kode lain bisa mengubah objek Date yang saya pegang secara implisit
      Bahaya sesungguhnya dari mutabilitas muncul dari perubahan non-lokal, bukan perubahan lokal
  • Cukup merepotkan bahwa Temporal API sama sekali tidak menangani informasi leap second
    Saya ingin membuat alat JS untuk perhitungan astronomi, tetapi konversi UTC membutuhkan data leap second
    Ada solusi memutar seperti temporal-tai, tetapi itu merepotkan karena harus memelihara berkas leap second di sisi klien
    Karena SOP (kebijakan CORS), berkas itu juga tidak bisa langsung diambil dari situs lain
    Browser diperbarui secara berkala, jadi terasa aneh mengapa informasi leap second tidak dibundel sejak awal

    • Anggapan bahwa SOP memblokir berkas leap second adalah kesalahpahaman
      Jika server mengatur header Access-Control-Allow-Origin atau menyediakannya dalam bentuk berkas JS, maka itu bisa dilakukan
      Namun membundel dan memelihara data leap second langsung di browser sendiri memang bisa menjadi pekerjaan yang mahal
    • Ungkapan “hanya menangani UTC” juga kurang tepat
      UTC pada dasarnya memang mencakup leap second, jadi yang sebenarnya ditangani hanyalah waktu POSIX
  • Pada contoh kode, seharusnya bukan "33" melainkan "50" yang diperlakukan sebagai tahun 1900-an — ini hanya koreksi typo

  • Saya sedang memakai Temporal polyfill, dan sejauh ini sangat puas

    • Hanya saja ukurannya 51KB, jadi tidak bisa dibilang ringan (tautan bundlephobia)
      Untuk server atau aplikasi besar mungkin tidak masalah, tetapi untuk aplikasi kecil bisa terasa berat
    • Ada juga yang bertanya bagaimana perbandingannya dengan moment atau luxon
  • Anehnya, artikel ini sama sekali tidak menyinggung Date.now()
    Jika ingin membandingkannya dengan Temporal, seharusnya penjelasan dimulai dari Date.now()
    Fungsi ini mengembalikan waktu yang telah berlalu dalam milidetik sejak 1 Januari 1970
    Temporal memang punya API yang lebih ramah, tetapi pada dasarnya tujuan utamanya tetap untuk merepresentasikan jarak relatif waktu

    • Namun bug terkait timestamp yang disebut dalam artikel juga memang ada
      Kalau begitu, muncul pertanyaan bagaimana cara mengubahnya ke format yang diinginkan tanpa melewati Date
  • Ada koreksi kecil tapi penting bahwa yang benar adalah “daylight saving time”, bukan “daylight savings time”

  • Sampai sekarang saya tidak tahu bahwa JS Date ternyata sebegitu berantakannya

    • Yang lebih disayangkan lagi, masalah-masalah seperti ini ternyata sudah terlihat jelas sejak 1995
      Andai saat itu sedikit lebih berhati-hati, begitu banyak developer tidak perlu jatuh ke jebakan seperti ini