在本地,一切都是按分鐘準確的。部署到 Heroku 后,時間之間的差異將減少約 6 小時。我不想轉換 Heroku 時區(希望它保持 UTC)。我已經嘗試了從 getTimezoneOffset() 轉換到不同日期格式的所有方法,但最終還是得到了相同的結果。我怎樣才能讓這 2 個日期時間相互匹配,并且在部署時不會被小時數抵消?當以完全相同的方式格式化時,它們為什么不同?
// Used to calculate current date time
const currentDate = new Date();
// ^ Production - (2021-10-12T19:12:41.081Z)
const time = `${currentDate.getHours()}:${currentDate.getMinutes()}`;
const fullDate = `${currentDate.getMonth()}/${currentDate.getDate()}/${currentDate.getFullYear()}`;
const currentDateFormatted = new Date(`${fullDate} ${time}`);
// ^ Production - (2021-10-12T19:12:00.000Z)
const currentParsedDateToUTC = Date.parse(currentDateFormatted.toUTCString());
// Used to calculate an event date time
const eventDate = new Date(`${event.date} ${event.endTime}`); // same exact format as above
// ^ Production - (2021-10-12T13:12:00.000Z)
const eventParsedDateToUTC = Date.parse(eventDate.toUTCString());
const isExpired = (currentParsedDateToUTC > eventParsedDateToUTC); // works locally, but not in production
在此示例中,事件日期和開始時間與當前日期時間相同。我怎樣才能防止它們有很大的不同?
uj5u.com熱心網友回復:
那是因為 Heroku 服務器與您的時區不同,您可以通過從前端轉換時間格式來處理它,我建議您在前端使用moment.js例如,您可以像這樣轉換:
npm install moment --save
然后你可以創建一個函式來改變顯示的格式:
const formatDatetime = (
datetime = "N/A",
format = 'LLL' // here is your format
) => {
return moment(datetime).isValid()
? moment(datetime).format(format)
: datetime;
};
uj5u.com熱心網友回復:
所以 - Heroku 正在回傳正確的 UTC 本地時間,在撰寫本文時它是2021-10-12T19:36:00.000Z.
您要求 Heroku 解釋2012-10-12 13:12為日期,但您沒有指定它應該使用的時區,因此它默認為它自己的本地時間 UTC。
這里的一切都按預期作業。
我認為您隱含地要求是您希望它將 13:12 解釋為您的當地時間。但是,Heroku 無法知道您的當地時間是什么,因此您需要跟蹤資料庫中事件的時區。
這在本地作業的唯一原因是您的本地服務器恰好與您在同一時區——如果我從我的時區連接到您的本地服務器,我會遇到同樣的問題。
uj5u.com熱心網友回復:
前四行代碼似乎是嘗試創建一個 Date 并將秒和毫秒設定為零。可以這樣做:
let d = new Date();
d.setSeconds(0,0);
這會將秒和毫秒設定為零。
我不知道您認為以下內容是什么:
const currentParsedDateToUTC = Date.parse(currentDateFormatted.toUTCString());
但相同的結果由以下給出:
d.getTime();
這實際上是上一次呼叫setSeconds 時回傳的值。所以前 5 行代碼簡化為:
let currentParsedDateToUTC = new Date().setSeconds(0,0);
然后在:
const eventDate = new Date(`${event.date} ${event.endTime}`);
使用內置決議器決議格式為 d/m/y H:m 的時間戳,這是一個壞主意,請參閱為什么 Date.parse 給出不正確的結果?. 您可以改用庫或僅撰寫 2 行函式來完成這項作業。
然后又是:
const eventParsedDateToUTC = Date.parse(eventDate.toUTCString());
這很簡單:
const eventParsedDateToUTC = eventDate.getTime();
最后還有:
const isExpired = (currentParsedDateToUTC > eventParsedDateToUTC);
比較運算子將強制日期為您編號,因此您可以將值保留為日期。
完成這項作業的功能是:
// eventDate is UTC timestamp in m/d/y H:m format
function isExpired(eventDate) {
// Parse eventDate as UTC
let [M,D,Y,H,m] = eventDate.split(/\W/);
let eventD = new Date(Date.UTC(Y, M-1, D, H, m));
// return true if has passed (minute precision)
return eventD < new Date().setSeconds(0,0);
}
// Event dates (UTC)
['10/12/2021 12:00', // 12 Oct 2021 12:00
'10/13/2021 12:00', // 13 Oct 2021 12:00
'10/13/2022 12:00', // 13 Oct 2022 12:00
].forEach(d =>
console.log(d ' has' (isExpired(d)? '':' not') ' Expired')
);
您可以在Date.UTC(Y, M-1, D, H, m)不轉換為 Date的情況下使用回傳的值,因此最后兩行可以是:
return Date.UTC(Y, M-1, D, H, m) < new Date().setSeconds(0,0);
但是使用 Date 更具語意(如果沒有必要)。:-)
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/318874.html
標籤:javascript 日期 英雄 时间
上一篇:如何在heroku上寫入環境變數
