處理日期和時區轉換:為什麼正確的 UTC 轉換很重要

aow054發表於2024-09-22
在檢索選定日期範圍內的資料時,我們注意到我們的計算存在一定偏差。然而,當我們將日期減少一天時,資料完全匹配! 嗯……我們的程式碼中處理日期的方式可能存在問題。也許時區處理不正確——是的,我是對的!在構建涉及來自不同時區的使用者的應用程式時,正確處理日期可能很棘手。以 utc 儲存日期是確保一致性的常見最佳實踐,但當使用者在本地時區輸入日期時,尤其是在過濾和查詢期間,事情可能會變得複雜。開發人員經常求助於本機 javascript date 物件 來處理這些轉換。然而,這種方法可能會導致跨環境的不一致,例如 node.js 與 chrome 等瀏覽器控制檯。在本文中,我們將探討為什麼正確處理日期和時區轉換至關重要,luxon 如何使此過程變得更容易,以及為什麼依賴本機 javascript date 物件會導致不一致。 問題:utc 儲存與本地時間過濾當日期以 utc 格式儲存時,它們代表了一個全球標準,可以消除時區引起的歧義。然而,使用者通常會根據他們的本地時區進行思考。當使用者嘗試使用本地時間輸入按日期過濾記錄時,這種差異變得明顯。讓我們看一個示例,如果處理不當,使用者的當地時間輸入可能會導致丟失記錄。 示例場景:gmt-7 時區的使用者想象一下位於gmt-7 時區(太平洋夏令時間) 的使用者。 2024 年 9 月 5 日,他們在當地時間晚上 10:00 建立了記錄。以下是幕後發生的事情:2024 年 9 月 5 日,晚上 10:00 gmt-7 轉換為 2024 年 9 月 6 日,05:00 am utc 並按原樣儲存在資料庫中。但是,使用者認為他們是在9 月 5 日建立了此記錄。 過濾器不匹配現在,假設使用者想要查詢 9 月 5 日 建立的所有記錄。他們輸入日期2024年9月5日,期望檢索他們的記錄。但是,如果系統直接將輸入日期與儲存的utc日期進行比較,而不調整時區差異,則使用者將錯過記錄。為什麼?該記錄已儲存在資料庫中,時間為9 月 6 日 (utc)。使用者過濾了9 月 5 日(他們的當地時間),但系統將此與 utc 進行比較,導致不匹配。 javascript 日期物件:跨環境的不一致以下示例程式碼演示了使用本機 javascript date 物件處理日期和時間轉換時的常見問題,特別是在 node.js 和瀏覽器(例如 chrome 控制檯)等不同環境中。 示例程式碼:function converttoutcstartofday(isostring) { // step 1: parse the iso string into a date object let localdate = new date(isostring); // step 2: set the time to the start of the day (00:00:00) in local time zone localdate.sethours(0, 0, 0, 0); // step 3: get the utc time using toisostring() – it converts local time to utc let utcstartofday = localdate.toisostring(); return utcstartofday; // this will be in utc}// example usage:let frontenddate = "2023-08-22t00:00:00+05:30"; // iso string with timezone offsetlet startofdayutc = converttoutcstartofday(frontenddate);console.log(startofdayutc); // expected output: "2023-08-21t18:30:00.000z"登入後複製在此示例中,使用者輸入日期“2023-08-22t00:00:00+05:30”(來自 gmt+5:30 時區)。 date 物件應該將其轉換為 utc 中一天的開始時間,但執行時:在 node.js 中,輸出為 2023-08-21t00:00:00.000z - 錯誤在 chrome 的控制檯,輸出為 2023-08-21t18:30:00.000z - 正確這種差異可能會導致不可預測的結果,具體取決於程式碼的執行位置。此行為使得 date 物件無法可靠地在不同環境中進行一致的日期處理。 使用 luxon 進行準確的日期處理要解決這個問題,使用像 luxon 這樣的庫非常重要,它可以在不同環境中提供一致的行為。 luxon 幫助您將使用者的本地輸入轉換為所在時區當天正確的 開始 和 結束,然後將這些時間轉換為 utc 以進行準確的資料庫查詢。這是一個使用 luxon 來處理此問題的示例:const { DateTime } = require('luxon');// Example user input date in ISO string with timezone information from the frontendconst userInputDate = "2023-08-22T00:00:00+05:30"; // ISO string sent by frontend// Step 1: Parse the ISO string to get the user's local timeconst userLocalDate = DateTime.fromISO(userInputDate);// Step 2: Convert this date to start of the day and end of the day in the user's local timezoneconst startOfDayLocal = userLocalDate.startOf('day'); // start of the day in the user's timezoneconst endOfDayLocal = userLocalDate.endOf('day'); // end of the day in the user's timezone// Step 3: Convert these local start and end times to UTCconst startOfDayUtc = startOfDayLocal.toUTC().toJSDate(); // start of the day in UTCconst endOfDayUtc = endOfDayLocal.toUTC().toJSDate(); // end of the day in UTC// Step 4: Query the database using the UTC rangedb.records.find({ createdAt: { $gte: startOfDayUtc, $lte: endOfDayUtc }});登入後複製 為什麼 luxon 比 javascript 日期物件更好直接使用原生 javascript date 物件 處理日期和時區轉換可能會導致像上面演示的那樣的不一致。以下是為什麼 luxon 是更好的選擇的幾個原因:跨環境的一致性:無論程式碼是在 node.js 還是瀏覽器(例如 chrome 控制檯)中執行,luxon 都提供一致的行為。這消除了在不同環境中使用 date 物件所產生的差異。內建時區支援:luxon 可以輕鬆地在時區之間進行轉換,而 date 物件不提供對時區操作的強大支援。簡單的日期操作:設定使用者本地時區的一天的開始或結束並將其轉換為 utc 是全球應用程式中的常見任務。 luxon 透過其直觀的 api 簡化了此過程,而 date 則需要複雜的手動處理。 結論正確處理日期和時區轉換對於構建可靠、使用者友好的應用程式至關重要。如果開發人員在過濾記錄時未能考慮到時區差異,使用者可能會錯過重要資料,從而導致混亂和潛在的嚴重錯誤。使用 luxon 代替原生 javascript date 物件 可提供一致性、更好的時區處理以及更輕鬆的日期操作。這使開發人員能夠為跨時區的使用者建立無縫體驗,確保查詢按預期工作,並且在過濾過程中不會遺漏任何記錄。在全球應用程式中,準確可靠的日期處理是為使用者提供高質量體驗的關鍵,無論使用者位於哪個時區。最後的想法您是否遇到過類似的情況,即日期和時區處理導致您的應用程式出現意外結果?你是如何解決這個問題的?我很想聽聽您的經歷、反饋或您可能有的任何問題或疑慮。歡迎在下面的評論部分分享它們。如果您覺得本文有幫助,請點贊並分享給可能從中受益的其他人! 以上就是處理日期和時區轉換:為什麼正確的 UTC 轉換很重要的詳細內容,更多請關注我的其它相關文章!

相關文章