JavaScript&Typescript中的時間


  • 修改操作系統的時間並不一定能馬上反映到瀏覽器中(比如new Date()有可能短時間內還是舊的時間)
  • timestamp時間戳
    • timestamp時間戳的單位一般是毫秒,因此進行加減操作時要使用毫秒為單位的時間段。不過timestamp也有以微秒為單位的,比如一些可以進行時間戳轉換的網站上就可以選使用毫秒還是微秒為單位。
  • 時區
    • IANA timezone database列出了所有的時區名稱等信息
    • 時區名稱如'Asia/Shanghai','Asia/Urumqi','Europe/Berlin'等。
    • 時區縮寫如EDT代表(美國)東部夏令時、CCT代表中國沿海時間(北京時間)等。
    • 語言名稱如zh-CN, en-US等。
  • Date類
    • new Date();
    • new Date(value);
    • new Date(dateString);
    • new Date(year,month,day,hours,minutes,seconds,milliseconds);
      • 即使day是當月最后一天,day+1后Date也可以自動跳到下個月的1號
    • new Date(number);
      • 可以根據timestamp生成Date對象。有時由於Date沒有加減1毫秒等操作,可以先把Date轉成timestamp然后加減1,然后再轉回Date對象。
      • 經常結合Date.now()使用:new Date(Date.now())
    • Date.now()
      • 獲取當前的timestamp(距離1970年1月1日)
    • date.setDate(nextHour.getDate() + 1);
      • 如果當前實際31號,可以自動跳到下一個月的1號
    • date.setHours(nextHour.getHours() + 1);
      • 如果當前實際23點,可以自動跳到下一天的零點
    • date.setMinutes(0);
    • date.setSeconds(0);
    • date.setMilliseconds(0);
    • date.toISOString():轉成ISO格式的UTC時間(不再包含時區信息),如202020-06-09T03:02:55.887Z
    • date.toLocaleString():轉成指定的語言和時區
      • new Date().toLocaleString("zh-CN", {timeZone: "America/New_York"})
    • 往前推x小時(會處理日期、月份等的變化):this.xxxDate.setHours(this.yyyDate.getHours() - 48)
    • 時區
      • JavaScript中的Date對象雖然可以用getTimezoneOffset()獲取失去偏移量,但是並不包含明確的時區描述信息(如America/New_York),也就是並沒有時區信息字段。並且你無法偽造一個其他時區的Date對象(即使是單元測試中?),因為只能獲取瀏覽器時區的Date,並且只能getTimezoneOffset(),而不能setTimezoneOffset()。
        • you can't set the timezone of Date objects in javascript. Usually you use only UTC and epoch-based timestamps. Only when creating a Date from a string or from year, month etc. the local timezone will be used, you can only get the timezone offset.
        • 只是可以使用date.toLocaleString()轉成指定的語言和時區,但這只是格式化后的顯示,Date對象本身並不能變成這些時區
        • new Date('Wed Jul 17 2019 03:00:00 GMT+0300 (GMT+03:00)')、new Date('Feb 28 2013 19:00:00 GMT-0500')、new Date("2019-04-21 21:00:00 EDT")這種使用含時區信息的字符串進行Date對象的初始化,其實都不管用,如果再getTimezoneOffset()的話還會是-480,只不過是在初始化時會把生成的Date對象的時間點根據指定的時區進行轉成當前時區的時間點,但時區還是瀏覽器時區。
        • 但moment是有明確單獨的tz字段的,並且可以設置時區,不過轉換后的時間要自己去subtract計算?
        • Date對象中已經包含了時區信息,轉時區只是改變顯示,不需要對Date對象再做處理
      • 轉成UTC的同一個時間點(比如Local的0點轉成UTC的0點,實質是不是修改時區,根本就是換了時間點)
        • new Date(date.getTime() + date.getTimezoneOffset() * -1 * 60* 1000
        • date.getTimezoneOffset()的值和UTC+X是正負相反的,比如中國是-480。
    • 加減時間段
      • 可以轉成timestamp,然后使用加減之后的timestamp重新new一個Date
      • newDate = new Date(now.getTime() - timestampInterval);
    • 比較大小
      • 可以直接使用>等進行比較
  getMondayOfCurrentWeek(): Date {
    const now = new Date(Date.now());
    const dayOfTheWeek = now.getDay() === 0 ? -6 : -1 * now.getDay() + 1;
    return new Date(now.getFullYear(), now.getMonth(), now.getDate() + dayOfTheWeek);
  }

  // UTC和Local的周一有可能不是同一天
  getUtcMondayOfCurrentWeek(): Date {
    const now = new Date(Date.now());
    const dayOfTheWeek = now.getUTCDay() === 0 ? -6 : -1 * now.getUTCDay() + 1;
    const localMonday = new Date(now.getUTCFullYear(), now.getUTCMonth(), now.getUTCDate() + dayOfTheWeek);
    return new Date(localMonday.getTime() + localMonday.getTimezoneOffset() * -1 * this.secondsInAMinute * this.millisecondsInASecond);
  }

  getEndOfToday(): Date {
    const now = new Date(Date.now());
    const tomorrow = new Date(now.getFullYear(), now.getMonth(), now.getDate() + 1);
    return new Date(tomorrow.getTime() - 1);
  }

  // 將當前瀏覽器的時區信息轉成UTC+8這種格式
  getUTCOffset(): string {
    const offset = new Date().getTimezoneOffset() * -1 / 60;
    return offset >= 0 ? (this.UTC + '+' + offset) : (this.UTC + offset);
  }
  • JavaScript
  • TypeScript
    • moment
      • moment().startOf(String);
        • 如"week"、"isoWeek"
        • 可以通過修改dow、doy來設置每周、每年的第一天取周幾
    • moment-timezone
      • moment(Number|Date)
      • moment.tz(string timezone)
      • moment.substract(number utcOffset, 'minutes')
      • moment.format('YYYY-MM-DD HH:mm ZZ')
      • moment.toISOString()


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM