Panduan Pasukan Lucee MY

Tarikh dan masa dalam CFML: parseDateTime dan zon waktu

Panduan tarikh dan masa dalam CFML: parseDateTime, dateFormat, dateAdd, medan tarikh, zon waktu, dan cara selamat menyimpan UTC dan menukar zon semasa paparan.

Tarikh dan masa dalam CFML: parseDateTime dan zon waktu
0
Kandungan

Tarikh dan masa dalam CFML: parseDateTime dan zon waktu

Dalam CFML, tarikh dan masa ialah objek java.util.Date, satu titik masa dalam milisaat sejak 1 Januari 1970 UTC. Objek itu tidak membawa zon waktu; zon hanya masuk apabila anda menghurai atau memformat. Artikel ini merangkumi mencipta, menghurai, memformat, mengira dan membaca tarikh, serta mengendalikan zon waktu dengan betul.

Objek tarikh dalam CFML

Setiap nilai tarikh ialah java.util.Date. createDate(2026, 10, 17) ialah tengah malam 17 Oktober, manakala now() membawa jam semasa. Tiada zon melekat pada objek: now() di Kuala Lumpur dan di London pada saat yang sama menghasilkan milisaat yang sama. Sebab itu menyimpan detik mutlak dan menukar zon di lapisan paparan ialah satu-satunya cara yang selamat.

Mencipta tarikh

Empat fungsi mencipta tarikh: now() untuk detik semasa, createDate tanpa masa, createDateTime dengan masa, dan createTime untuk masa sahaja.

<cfscript>
    kini = now();
    tarikhSahaja = createDate(2026, 10, 17);
    tarikhMasa = createDateTime(2026, 10, 17, 14, 30, 0);
    masaSahaja = createTime(14, 30, 0);

    writeOutput("now() : " & dateTimeFormat(kini, "yyyy-mm-dd HH:nn:ss") & "<br>");
    writeOutput("createDate : " & dateFormat(tarikhSahaja, "yyyy-mm-dd") & "<br>");
    writeOutput("createDateTime : " & dateTimeFormat(tarikhMasa, "yyyy-mm-dd HH:nn:ss") & "<br>");
    writeOutput("createTime : " & timeFormat(masaSahaja, "HH:mm:ss") & "<br>");
</cfscript>

createDate tidak menerima jam, jadi masanya 00:00:00, punca perbandingan yang salah dengan now(). createODBCDateTime(date) memberi format cap masa ODBC untuk pemacu yang menuntutnya.

parseDateTime dengan format tersuai dan zon waktu

parseDateTime menukar rentetan kepada objek tarikh. Tanpa topeng, ia meneka format setempat dan boleh silap untuk nilai seperti 10/11/2026. Hantar topeng eksplisit.

<cfscript>
    t1 = parseDateTime("2026-10-17 14:30:00", "yyyy-MM-dd HH:nn:ss");
    t2 = parseDateTime("17/10/2026", "dd/MM/yyyy");

    // Argumen ketiga ialah zon waktu, bukan locale
    t3 = parseDateTime("2026-10-17 14:30:00", "yyyy-MM-dd HH:nn:ss", "UTC");

    writeOutput("t1 : " & dateTimeFormat(t1, "yyyy-mm-dd HH:nn:ss") & "<br>");
    writeOutput("t2 : " & dateFormat(t2, "yyyy-mm-dd") & "<br>");
    writeOutput("t3 (UTC ke KL) : " & dateTimeFormat(t3, "yyyy-mm-dd HH:nn:ss") & "<br>");
</cfscript>

Dalam Lucee, argumen ketiga parseDateTime ialah zon waktu, bukan locale. Contoh ketiga membaca 14:30 sebagai UTC, lalu ia menjadi 22:30 dalam zon Asia/Kuala_Lumpur. Untuk menghurai nama bulan setempat, guna LSParseDateTime(rentetan, locale, zonWaktu, format). Bersihkan rentetan kotor dengan fungsi rentetan CFML dahulu.

Memformat tarikh dan masa

dateFormat memformat tarikh, timeFormat memformat masa, dan dateTimeFormat memformat kedua-duanya. Perbezaan huruf topeng antara fungsi ini ialah perangkap nombor satu.

<cfscript>
    d = createDateTime(2026, 10, 17, 9, 5, 3);

    writeOutput(dateFormat(d, "dd/mm/yyyy") & "<br>");
    writeOutput(dateFormat(d, "dd mmm yyyy") & "<br>");
    writeOutput(dateFormat(d, "dddd, d mmmm yyyy") & "<br>");
    writeOutput(dateFormat(d, "ISO8601") & "<br>");
    writeOutput(timeFormat(d, "h:mm tt") & "<br>");
    writeOutput(timeFormat(d, "HH:mm:ss") & "<br>");
</cfscript>

Dalam dateFormat, m ialah bulan, jadi mm ialah bulan bersifar. Dalam timeFormat, m ialah minit. Dalam dateTimeFormat, m kembali bulan dan n ialah minit. Jadi masa ialah HH:mm:ss dalam timeFormat tetapi HH:nn:ss dalam dateTimeFormat.

Format mengikut locale dengan LSDateFormat dan LSTimeFormat

dateFormat dan dateTimeFormat tidak menerima argumen locale. Untuk paparan bahasa Melayu, guna LSDateFormat dan LSTimeFormat.

<cfscript>
    d = createDateTime(2026, 10, 17, 9, 5, 3);

    writeOutput(LSDateFormat(d, "long", "ms_MY") & "<br>");
    writeOutput(LSDateFormat(d, "full", "ms_MY") & "<br>");
    writeOutput(LSTimeFormat(d, "medium", "ms_MY") & "<br>");
    writeOutput(monthAsString(10, "ms_MY") & "<br>");
    writeOutput(dayOfWeekAsString(dayOfWeek(d), "ms_MY") & "<br>");
</cfscript>

Dengan ms_MY, LSDateFormat(d, "long", "ms_MY") memulangkan 17 Oktober 2026, full memulangkan Sabtu, 17 Oktober 2026, dan LSTimeFormat(d, "medium", "ms_MY") memulangkan 9:05:03 PG.

Aritmetik tarikh

dateAdd menambah unit, dateDiff mengira beza antara dua tarikh, dan dateCompare membandingkan serta memulangkan -1, 0 atau 1.

<cfscript>
    d = createDateTime(2026, 10, 17, 9, 0, 0);

    esok = dateAdd("d", 1, d);
    mingguDepan = dateAdd("ww", 1, d);
    bulanDepan = dateAdd("m", 1, d);

    bezaHari = dateDiff("d", d, esok);
    bezaHariKerja = dateDiff("wd", d, dateAdd("d", 10, d));
    banding = dateCompare(d, esok);

    writeOutput("esok : " & dateFormat(esok, "yyyy-mm-dd") & "<br>");
    writeOutput("mingguDepan : " & dateFormat(mingguDepan, "yyyy-mm-dd") & "<br>");
    writeOutput("bulanDepan : " & dateFormat(bulanDepan, "yyyy-mm-dd") & "<br>");
    writeOutput("bezaHari : " & bezaHari & "<br>");
    writeOutput("bezaHariKerja : " & bezaHariKerja & "<br>");
    writeOutput("banding : " & banding & "<br>");
</cfscript>

Unit dateAdd ialah yyyy, q, m, y, d, w, ww, h, n, s dan l. dateDiff menambah wd untuk hari bekerja sahaja. dateCompare menerima argumen ketiga untuk ketepatan.

Medan tarikh

Fungsi medan membaca satu bahagian tarikh dan memulangkan angka.

<cfscript>
    d = createDateTime(2026, 10, 17, 9, 5, 3);

    writeOutput("year : " & year(d) & "<br>");
    writeOutput("month : " & month(d) & "<br>");
    writeOutput("day : " & day(d) & "<br>");
    writeOutput("dayOfWeek : " & dayOfWeek(d) & " (1=Ahad hingga 7=Sabtu)" & "<br>");
    writeOutput("hour : " & hour(d) & "<br>");
    writeOutput("minute : " & minute(d) & "<br>");
    writeOutput("second : " & second(d) & "<br>");
    writeOutput("dayOfYear : " & dayOfYear(d) & "<br>");
    writeOutput("week : " & week(d) & "<br>");
</cfscript>

dayOfWeek memulangkan 1 untuk Ahad hingga 7 untuk Sabtu, iaitu aturan Amerika, bukan ISO. dayOfYear dan week berguna untuk pelaporan.

Zon waktu dan peraturan UTC

Lucee menyimpan satu zon waktu pelayan, ditetapkan dalam Lucee Administrator pada tetapan regional. Baca dengan getTimeZone, dan tukar buat satu permintaan dengan setTimeZone.

<cfscript>
    writeOutput("Zon pelayan : " & getTimeZone() & "<br>");

    diciptaPada = now();

    writeOutput("KL : " & dateTimeFormat(diciptaPada, "yyyy-mm-dd HH:nn:ss", "Asia/Kuala_Lumpur") & "<br>");
    writeOutput("NY : " & dateTimeFormat(diciptaPada, "yyyy-mm-dd HH:nn:ss", "America/New_York") & "<br>");
    writeOutput("UTC : " & dateTimeFormat(diciptaPada, "yyyy-mm-dd HH:nn:ss", "UTC") & "<br>");
</cfscript>

Objek tarikh ialah detik, bukan rentetan, jadi ia tidak perlu ditukar ke UTC sebelum disimpan. dateTimeFormat dengan zon ialah lapisan penukaran: detik yang sama dipaparkan 16:00 di Kuala Lumpur dan 04:00 di New York. Hantar objek tarikh terus melalui cfqueryparam dan baca balik dengan queryExecute.

Zon waktuOffset standardDST
UTC+00:00tiada
Asia/Kuala_Lumpur+08:00tiada
Asia/Singapore+08:00tiada
Asia/Tokyo+09:00tiada
Europe/London+00:00ya, +01:00 musim panas
America/New_York-05:00ya, -04:00 musim panas

Masalah biasa

Tarikh hilang masa. Punca biasa ialah createDate atau lajur SQL DATE, yang membuang jam. Guna createDateTime atau lajur TIMESTAMP apabila masa penting.

Waktu jimat siang (DST). Zon seperti America/New_York mengalih offset dua kali setahun. Hari DST bermula hanya 23 jam, dan hari ia tamat ialah 25 jam. Kod yang menambah 24 jam secara manual akan salah pada hari itu.

<cfscript>
    musimSejuk = parseDateTime("2026-01-15 12:00:00", "yyyy-MM-dd HH:nn:ss", "America/New_York");
    musimPanas = parseDateTime("2026-07-15 12:00:00", "yyyy-MM-dd HH:nn:ss", "America/New_York");

    writeOutput("Musim sejuk NY : " & dateTimeFormat(musimSejuk, "yyyy-mm-dd HH:nn:ss Z", "America/New_York") & "<br>");
    writeOutput("Musim panas NY : " & dateTimeFormat(musimPanas, "yyyy-mm-dd HH:nn:ss Z", "America/New_York") & "<br>");

    // Satu hari merentas sempadan DST hanya 23 jam
    a = parseDateTime("2026-03-07 12:00:00", "yyyy-MM-dd HH:nn:ss", "America/New_York");
    b = parseDateTime("2026-03-08 12:00:00", "yyyy-MM-dd HH:nn:ss", "America/New_York");
    writeOutput("Beza rentas DST : " & dateDiff("h", a, b) & " jam, bukan 24" & "<br>");
</cfscript>

dateConvert mengalih detik. dateConvert("local2utc", tarikh) dan dateConvert("utc2local", tarikh) menukar bacaan jam dinding, bukan label zon. Dalam zon +08:00, dateConvert("local2utc", d) memulangkan objek lapan jam lebih awal, jadi ia bukan cara menyimpan detik UTC. Simpan objek tarikh terus, dan guna dateTimeFormat(nilai, mask, zonWaktu) untuk paparan.

Tarikh tidak sah. createDate(2026, 2, 30) membuang ralat kerana Februari 2026 hanya 28 hari. Sahkan input dengan isDate dan tangkap pengecualian.

Perbandingan rentetan tarikh. "17/10/2026" dan "17-10-2026" berbeza sebagai rentetan walaupun mewakili hari yang sama. Hurai dengan parseDateTime dan bandingkan dengan dateCompare. Apabila sukar dikesan, catat nilai yang terlibat seperti dalam panduan log dan pemantauan CFML.

Jadual rujukan fungsi

FungsiTujuan
now()Detik semasa
createDate(y, m, d)Tarikh tanpa masa
createDateTime(y, m, d, h, n, s)Tarikh dan masa
createTime(h, n, s)Masa sahaja
parseDateTime(s, mask, tz)Hurai rentetan kepada tarikh
dateFormat(d, mask)Format tarikh
timeFormat(d, mask)Format masa
LSDateFormat(d, mask, locale)Format tarikh ikut locale
dateAdd(unit, n, d)Tambah atau tolak unit
dateDiff(unit, a, b)Beza antara dua tarikh
dateCompare(a, b)Bandingkan, pulang -1, 0, 1
year(d), month(d), day(d)Medan tarikh
dateTimeFormat(d, mask, tz)Format dalam zon tertentu

Soalan Lazim (FAQ)

Apakah objek tarikh dalam CFML?

Ia ialah java.util.Date, satu titik masa dikira dalam milisaat sejak 1 Januari 1970 UTC. Objek itu tidak membawa zon waktu, jadi zon hanya terpakai semasa menghurai atau memformat.

Kenapa tarikh saya hilang masa selepas disimpan?

Kemungkinan besar anda menyimpannya ke lajur DATE atau menciptanya dengan createDate, yang kedua-duanya hanya menyimpan bahagian tarikh. Guna lajur TIMESTAMP dan createDateTime apabila masa penting.

Apakah beza dateFormat dan LSDateFormat?

dateFormat guna locale pelayan tanpa argumen locale, manakala LSDateFormat menerima mask, locale dan zon waktu, jadi ia boleh memaparkan 17 Oktober 2026 dengan ms_MY.

Bagaimana cara selamat mengendalikan zon waktu?

Simpan objek tarikh terus, kerana ia sudah detik mutlak tanpa zon. Tukar ke zon pengguna hanya semasa paparan dengan dateTimeFormat(nilai, mask, zonWaktu).

Apakah perbezaan topeng m dan n?

Dalam dateFormat dan dateTimeFormat, m ialah bulan dan n ialah minit. Dalam timeFormat, m ialah minit.

Sumber

Senarai semak

  • Fahami bahawa tarikh CFML ialah java.util.Date tanpa zon waktu melekat.
  • Hurai rentetan dengan parseDateTime dan topeng eksplisit, bukan tekaan format.
  • Guna LSDateFormat dan LSTimeFormat dengan ms_MY untuk paparan bahasa Melayu.
  • Ingat m ialah bulan dalam dateFormat tetapi minit dalam timeFormat.
  • Simpan objek tarikh (detik mutlak) terus, dan tukar ke zon pengguna hanya semasa paparan.
  • Sahkan input tarikh dengan isDate dan tangkap ralat createDate.
  • Guna dateCompare untuk perbandingan, bukan perbandingan rentetan.
  • Berhati-hati dengan DST, iaitu hari 23 jam dan 25 jam pada zon ber-DST.
Bab 9 daripada 13

Asas CFML untuk Pemula

Log masuk untuk menyimpan kemajuan bacaan anda.

0 komen

0 komen

Log masuk untuk menjawab atau memberi komen.

Log masuk