前端的時間會根據 GMT 時間,減掉後再帶回後端,因此當前端選擇用 /
去 parse 時間,會出現時間不會加上時區的時間,因此在減掉時區的時間後,反而帶到後端的時間會變成前一天
new Date()
1
2
3
4
5
| // 前端
2020-04-17T03:11:29.686Z
// 後端
Fri Apr 17 2020 11:11:29 GMT+0800 (台北標準時間)
|
new Date(‘1979-08-01’)
1
2
3
4
5
| // 前端
Wed Aug 01 1979 09:00:00 GMT+0900 (台北夏令時間)
// 後端
1971-08-01T00:00:00.000Z
|
new Date(‘1979/08/01’)
1
2
3
4
5
| // 前端
Wed Aug 01 1979 00:00:00 GMT+0900 (台北夏令時間)
// 後端
1979-07-31T15:00:00.000Z
|
可以看到只有 new Date('1979/08/01')
帶到後端的時候變成 1979-07-31T15:00:00.000Z
,後端存日期就會錯誤,因此如果前端用 /
,必須將 timezoneOffset 加回來
可以使用套件
1
| dayjs.utc(date, 'YYYY/MM/DD').add(dayjs().utcOffset(), 'minute').toDate()
|
1
| moment(date).hours(new Date().getTimezoneOffset()/-60)._d;
|
夏令時間
有發現上面的 1979-08-01
後面的時間會是 +9
?? 台灣不是 +8
嗎??
點連結發現其實台灣以前也有夏令時間,因此只要日期是那個時間內,就會是 +9
,所以記得 utcOffset()
and getTimezoneOffset
記得要用當下的時間去取得
1
2
3
4
5
6
7
8
| var d = new Date('1979/08/01')
var offset = ((new Date().getTimezoneOffset())/-60)
var now = moment(d).hours(offset)._d;
Wed Aug 01 1979 00:00:00 GMT+0900 (台北夏令時間)
8
Wed Aug 01 1979 08:00:00 GMT+0900 (台北夏令時間)
// 08:00 但 GMT 是 +0900,所以帶回後端,-9 就會變成 1979/7/31
|
所以正確應該是要
1
2
| // 帶 date 進去
dayjs.utc(date, 'YYYY/MM/DD').add(dayjs(date).utcOffset(), 'minute').toDate()
|
1
2
3
4
5
| // 帶 date 進去
moment(date).hours(new Date(date).getTimezoneOffset()/-60)._d;
// 當遇到有時候會有時區有夏令時間時,可改用 minutes,因為用 hours 會因為有些 hour 會是 7.5 hours 後變成 7 導致有一小時的差距
moment(date).minutes(new Date().getTimezoneOffset()/-1)._d;
|
或是後端吃 string 的話
1
| new Date(date).toDateString()
|
或是最好就是用標準時間
1
2
| YYYY-MM-DDTHH:mm:ss
2019-08-14T00:00:00
|
Reference