手寫一個同步服務端時間的小工具

jump__jump發表於2022-12-14

在前端開發的過程中,開發者經常會用到 new Date() 來獲取當前時間,但是 new Date() 是獲取的當前作業系統的時間,由於使用者可以修改當前電腦時間,所以它是不準確的。

大部分情況下,使用者修改當前電腦時間都沒有什麼問題,但是當我們需要根據服務端傳遞的資料時間與當前時間進行計算時,前端展示就會出錯。同時,需要過期時間的資料(時間)存入前端快取( localStorage, IndexedDB )中也是會出現問題。

這時候我們考慮使用伺服器提供的時間,而不是前端時間。伺服器每次進行資料互動時都會在響應頭提供時間資料。我們可以透過該資料修正前端時間。

sync-time

於是個人寫了一個小工具 sync-time 。以 fetch 為例子:

import { sync, time, date } from 'sync-time'

async function getJSON() {
  let url = 'https://www.npmjs.com/search?q=';
  let response
  try {
    response = await fetch(url);

    // 響應頭部通常會有 date 資料
    console.log(response.headers.get('date'))

    // 把響應頭時間作為伺服器時間,呼叫 sync 同步資料
    sync(response.headers.get('date'))
  } catch (error) {
  }
  return response.body
}

getJson()

// => 返回數字,即修正好的毫秒 getTime
time()
// 1670345143730

// 返回 Date,new Date(time())
date()
// Wed Dec 07 2022 00:46:47 GMT+0800 (中國標準時間)

原始碼如下所示:

let diffMillisecond: number = 0

// 獲取前端時間
const getCurrentTime = (): number => (new Date()).getTime();

// 同步時間
const sync = (time: Date | string): void => {
  // 沒有傳遞時間,直接使用前端時間
  if (!time) {
    diffMillisecond = 0
    return
  }

  // 獲取 UNIX 時間戳
  const syncTime = time instanceof Date ? time.getTime() : Date.parse(time)
  
  // 當前是 NaN,直接返回
  if (Number.isNaN(syncTime)) {
    return
  }

  // 獲取兩個時間的差值
  diffMillisecond = syncTime - getCurrentTime()
}

// 補差值並獲取 UNIX 時間戳
const time = (): number => getCurrentTime() + diffMillisecond

const date = (): Date => new Date(time())

export {
  sync,
  time,
  date
}

鼓勵一下

如果你覺得這篇文章不錯,希望可以給與我一些鼓勵,在我的 github 部落格下幫忙 star 一下。

部落格地址

相關文章