精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

JavaScript日期時間操作完整指南!

開發 前端
JavaScript 中的日期和時間操作相對復雜且具有一些特殊的行為,處理日期和時間時常常會遇到很多挑戰。下面就來深入理解日期和時間操作,并提供一些日期/時間操作的最佳實踐!

標準化時間

標準化時間是指使用一套公認的標準來表示和衡量時間的方法。這種標準化使得不同地區和系統之間能夠統一地解讀和比較時間。目前最常用的標準化時間系統是協調世界時(Coordinated Universal Time,簡稱UTC)。UTC 是基于原子鐘的國際標準時間,被廣泛應用于全球各個領域,包括科學、航空、計算機網絡等。

在 Web 應用中,只要知道用戶所在的時區,就可以隨時轉換、展示時間。如果知道用戶當地的時間和時區,就可以將其轉換為 UTC。計算機中的時間采用 ISO 日期格式,它是 ISO-8601 擴展格式的簡化版本,如下所示:

日期/時間操作

下面先來看看如何使用 JavaScript 進行日期/時間操作。

Date對象

Date 對象基于 Unix Time Stamp,即自 1970 年 1 月 1 日(UTC)起經過的毫秒數。其語法如下:

new Date();
new Date(value);
new Date(dateString);
new Date(year, monthIndex [, day [, hours [, minutes [, seconds [, milliseconds]]]]]);

注意, 創建一個新Date對象的唯一方法是通過 new 操作符,例如:let now = new Date(); 若將它作為常規函數調用(即不加 new 操作符),將返回一個字符串,而非 Date 對象。

獲取當前時間

const currentDate = new Date();

如果不向 Date 構造函數傳遞任何內容,則返回的日期對象就是當前的日期和時間。然后,就可以將其格式化為僅提取日期部分,如下所示:

const currentDate = new Date();

const currentDayOfMonth = currentDate.getDate();
const currentMonth = currentDate.getMonth();
const currentYear = currentDate.getFullYear();

const dateString = currentDayOfMonth + "-" + (currentMonth + 1) + "-" + currentYear;
// '4-7-2023'

需要注意,月份是從 0 開始的,一月就是 0,依此類推。

獲取當前時間戳

可以創建一個新的 Date 對象并使用 getTime() 方法來獲取當前時間戳:

const currentDate = new Date();
const timestamp = currentDate.getTime();

在 JavaScript 中,時間戳是自 1970 年 1 月 1 日以來經過的毫秒數。如果不需要支持<IE8,可以使用Date.now()直接獲取時間戳,而無需創建新的 Date 對象。

解析日期

可以通過不同的方式將字符串轉換為 JavaScript 日期對象。Date 對象的構造函數接受多種日期格式:

const date1 = new Date("Wed, 27 July 2016 13:30:00");
const date2 = new Date("Wed, 27 July 2016 07:45:00 UTC");
const date3 = new Date("27 July 2016 13:30:00 UTC+05:45");

需要注意,這里字符串不需要包含星期幾,因為 JS 可以確定任何日期是星期幾。

我們還可以傳入年、月、日、小時、分鐘和秒作為單獨的參數:

const date = new Date(2016, 6, 27, 13, 30, 0);

當然,也可以使用 ISO 日期格式:

const date = new Date("2016-07-27T07:45:00Z");

但是,如果不明確提供時區,就會有問題:

const date1 = new Date("25 July 2016");
const date2 = new Date("July 25, 2016");
date1 === date2;   // false

這兩個都會展示當地時間 2016 年 7 月 25 日 00:00:00,但是兩者是不相等的。

如果使用 ISO 格式,即使只提供日期而不提供時間和時區,它也會自動接受時區為 UTC。

new Date("25 July 2016").getTime() !== new Date("2016-07-25").getTime()
new Date("2016-07-25").getTime() === new Date("2016-07-25T00:00:00Z").getTime()

設置日期格式

現代 JavaScript 在標準命名空間中內置了一些方便的國際化函數Intl,使日期格式化變得簡單。

為此,我們需要兩個對象:Date 和 Intl.DateTimeFormat,并使用輸出首選項進行初始化。假設想使用美國 (M/D/YYYY) 格式,則如下所示:

const firstValentineOfTheDecade = new Date(2020, 1, 14);
const enUSFormatter = new Intl.DateTimeFormat('en-US');
console.log(enUSFormatter.format(firstValentineOfTheDecade));
// 2/14/2020

如果想要荷蘭 (D/M/YYYY) 格式,只需將不同的區域性代碼傳遞給 DateTimeFormat 構造函數即可:

const nlBEFormatter = new Intl.DateTimeFormat('nl-BE');
console.log(nlBEFormatter.format(firstValentineOfTheDecade));
// 14/2/2020

或者美國格式的較長形式,并拼寫出月份名稱:

const longEnUSFormatter = new Intl.DateTimeFormat('en-US', {
    year:  'numeric',
    month: 'long',
    day:   'numeric',
});
console.log(longEnUSFormatter.format(firstValentineOfTheDecade));
// February 14, 2020

更改日期格式

我們知道了如何解析日期并對其進行格式化,將日期從一種格式更改為另一種格式只需將兩者結合起來即可。

例如,如果日期格式為 Jul 21, 2013,并且想要將格式更改為 21-07-2013,可以這樣實現:

const myDate = new Date("Jul 21, 2013");
const dayOfMonth = myDate.getDate();
const month = myDate.getMonth();
const year = myDate.getFullYear();

function pad(n) {
    return n<10 ? '0'+n : n
}

const ddmmyyyy = pad(dayOfMonth) + "-" + pad(month + 1) + "-" + year;
// "21-07-2013"

本地化日期

上面討論的日期格式化方法應該適用于大多數應用,但如果想本地化日期的格式,建議使用 Date 對象的toLocaleDateString()方法:

const today = new Date().toLocaleDateString('en-GB', {  
    day:   'numeric',
    month: 'short',
    year:  'numeric',
});

console.log(today); // '4 Jul 2023'

如果想顯示日期的數字版本,建議使用以下解決方案:

const today = new Date().toLocaleDateString(undefined, {
    day:   'numeric',
    month: 'numeric',
    year:  'numeric',
});

這里輸出了 7/26/2016. 如果想確保月份和日期是兩位數,只需更改選項:

const today = new Date().toLocaleDateString(undefined, {
    day:   '2-digit',
    month: '2-digit',
    year:  'numeric',
});

這樣就會輸出 07/26/2016。

還可以使用其他一些相關函數來本地化時間和日期的顯示方式:

計算相對日期和時間

下面是在 JavaScript 日期中添加 20 天的示例(即計算出已知日期后 20 天的日期):

const myDate = new Date("July 20, 2016 15:00:00");
const nextDayOfMonth = myDate.getDate() + 20;
myDate.setDate(nextDayOfMonth);
const newDate = myDate.toLocaleString();

原始的日期對象現在表示7月20日之后20天的日期,newDate包含的是表示該日期的本地化字符串。newDate的值是2016/8/9 15:00:00。

要計算相對時間戳,并得到更精確的差異,可以使用Date.getTime()和Date.setTime()來處理表示自某個特定時刻(即1970年1月1日)以來的毫秒數的整數。例如,如果想知道距離現在17小時后的時間:

const msSinceEpoch = (new Date()).getTime();
const seventeenHoursLater = new Date(msSinceEpoch + 17 * 60 * 60 * 1000);

比較時間

在比較時間時,首先需要創建日期對象,<、>、<= 和 >= 都可以工作。 因此,比較 2014 年 7 月 19 日和 2014 年 7 月 18 日就很簡單:

const date1 = new Date("July 19, 2014");
const date2 = new Date("July 28, 2014");

if(date1 > date2) {
    console.log(date1);
} else {
    console.log(date2);
}

檢查相等性比較棘手,因為表示同一日期的兩個日期對象仍然是兩個不同的日期對象并且不相等。 比較日期字符串不是一個好主意,因為例如“July 20, 2014”和“20 July 2014”表示相同的日期,但具有不同的字符串表示形式。 下面的代碼片段說明了第一點:

const date1 = new Date("June 10, 2003");
const date2 = new Date(date1);

const equalOrNot = date1 == date2 ? "相等" : "不等";
console.log(equalOrNot);

這里將輸出“不等”,這種特殊情況可以通過比較日期的時間戳來解決,如下所示:

date1.getTime() == date2.getTime()

這個例子不太符合實際的應用,因為通常不會從另一個日期對象創建日期對象。下面來看一個更實際的例子。比較用戶輸入的生日是否與從后端獲得的幸運日期相同。

const userEnteredString = "12/20/1989"; // MM/DD/YYYY format
const dateStringFromAPI = "1989-12-20T00:00:00Z";

const dateFromUserEnteredString = new Date(userEnteredString)
const dateFromAPIString = new Date(dateStringFromAPI);

if (dateFromUserEnteredString.getTime() == dateFromAPIString.getTime()) {
    transferOneMillionDollarsToUserAccount();
} else {
    doNothing();
}

兩者都代表相同的日期,但不幸的是用戶將無法獲得這百萬美元。問題在于:JavaScript 會假定時區是瀏覽器提供的時區,除非另有明確指定。

這意味著,new Date ("12/20/1989") 將創建一個日期 1989-12-20T00:00:00+5:45 或 1989-12-19T18:15:00Z ,而這與時間戳為 1989-12-20T00:00:00Z 是不同的。

不能只更改現有日期對象的時區,因此現在的目標是創建一個新的日期對象,但使用 UTC 而不是本地時區。

在創建日期對象時將忽略用戶的時區并使用 UTC。有兩種方法可以做到這一點:

根據用戶輸入日期創建 ISO 格式的日期字符串,并使用它創建 Date 對象。 使用有效的 ISO 日期格式創建 Date 對象,同時明確指定使用的是 UTC 而不是本地時區。

const userEnteredDate = "12/20/1989";
const parts = userEnteredDate.split("/");

const userEnteredDateISO = parts[2] + "-" + parts[0] + "-" + parts[1];

const userEnteredDateObj = new Date(userEnteredDateISO + "T00:00:00Z");
const dateFromAPI = new Date("1989-12-20T00:00:00Z");

const result = userEnteredDateObj.getTime() == dateFromAPI.getTime(); // true

如果不指定時間,這也適用,因為默認為午夜(即 00:00:00Z):

const userEnteredDate = new Date("1989-12-20");
const dateFromAPI = new Date("1989-12-20T00:00:00Z");
const result = userEnteredDate.getTime() == dateFromAPI.getTime(); // true

注意,如果向日期構造函數傳遞了正確的 ISO 日期格式 YYYY-MM-DD 的字符串,則它會自動采用 UTC。

JavaScript 提供了一個簡潔的 Date.UTC() 函數,可以使用它來獲取日期的 UTC 時間戳。從日期中提取組件并將它們傳遞給函數。

const userEnteredDate = new Date("12/20/1989");
const userEnteredDateTimeStamp = Date.UTC(userEnteredDate.getFullYear(), userEnteredDate.getMonth(), userEnteredDate.getDate(), 0, 0, 0);

const dateFromAPI = new Date("1989-12-20T00:00:00Z");
const result = userEnteredDateTimeStamp == dateFromAPI.getTime(); // true

日期差異

下面來討論兩個用例:

  • 計算兩個日期之間的天數

將兩個日期轉換為 UTC 時間戳,找出以毫秒為單位的差異并找到等效的天數。

const dateFromAPI = "2016-02-10T00:00:00Z";

const now = new Date();
const datefromAPITimeStamp = (new Date(dateFromAPI)).getTime();
const nowTimeStamp = now.getTime();

const microSecondsDiff = Math.abs(datefromAPITimeStamp - nowTimeStamp);

// 使用 Math.round 代替 Math.floor 來考慮某些 DST 情況
// 每天的毫秒數 = 24 小時/天 * 60 分鐘/小時 * 60 秒/分鐘 * 1000 毫秒/秒
const daysDiff = Math.round(microSecondsDiff / (1000 * 60 * 60  * 24));

console.log(daysDiff);
  • 根據出生日期計算用戶的年齡
const birthDateFromAPI = "12/10/1989";

日期/時間操作最佳實踐

從用戶獲取日期和時間

如果需要從用戶那里獲取日期和時間,那么很可能需要的是他們的本地日期時間。我們在日期計算部分看到Date構造函數可以接受多種不同的日期格式。

為了消除任何混淆,建議使用new Date(year, month, day, hours, minutes, seconds, milliseconds)格式來創建日期,這是使用Date構造函數時能夠做到的最明確的方式。

可以使用允許省略最后四個參數的變體,如果它們為零;例如,new Date(2012, 10, 12)與new Date(2012, 10, 12, 0, 0, 0, 0)是相同的,因為未指定的參數默認為零。

例如,如果正在使用一個日期和時間選擇器,它給出了日期2012-10-12和時間12:30,可以提取這些部分并創建一個新的Date對象,如下所示:

const datePickerDate = '2012-10-12';
const timePickerTime = '12:30';

const [year, month, day] = datePickerDate.split('-').map(Number);
const [hours, minutes] = timePickerTime.split(':').map(Number);

const dateTime = new Date(year, month - 1, day, hours, minutes);

console.log(dateTime); // Fri Oct 12 2012 12:30:00 GMT+0800 (中國標準時間)

在上述示例中,首先將日期和時間分別存儲在datePickerDate和timePickerTime變量中。然后,使用split()方法將日期字符串和時間字符串拆分為數值數組,并將其存儲在[year, month, day]和[hours, minutes]變量中。最后,使用這些值創建一個新的Date對象,注意按照 JavaScript 的月份規則,需要將月份減去1。這樣就得到了一個包含用戶所選日期和時間的Date對象。

通過遵循這種方法,可以明確地指定日期和時間,以便消除不同日期解析格式可能帶來的混亂。

const dateFromPicker = "2012-10-12";
const timeFromPicker = "12:30";

const dateParts = dateFromPicker.split("-");
const timeParts = timeFromPicker.split(":");
const localDate = new Date(dateParts[0], dateParts[1]-1, dateParts[2], timeParts[0], timeParts[1]);

注意,盡量避免從字符串創建日期,除非它是 ISO 日期格式。 請改用 Date(year, month, date, hours, minutes, seconds, microseconds) 方法。

僅獲取日期

如果只獲取日期(例如用戶的生日),最好將格式轉換為有效的 ISO 日期格式,以消除任何可能導致日期在轉換為 UTC 時向前或向后移動的時區信息。 例如:

const dateFromPicker = "12/20/2012";
const dateParts = dateFromPicker.split("/");
const ISODate = dateParts[2] + "-" + dateParts[0] + "-" + dateParts[1];
const birthDate = new Date(ISODate).toISOString();

如果使用有效的 ISO 日期格式 (YYYY-MM-DD) 輸入創建一個 Date 對象,它將默認為 UTC,而不是默認為瀏覽器的時區。

存儲日期

始終以 UTC 格式存儲日期時間,始終將 ISO 日期字符串或時間戳保存到數據庫。實踐證明,在后端存儲本地時間是一個壞主意,最好讓瀏覽器在前端處理到本地時間的轉換。不應該將“July 20, 1989 12:10 PM”之類的日期時間字符串發送到后端。

可以使用 Date 對象的 toISOString() 或 toJSON() 方法將本地時間轉換為 UTC。

const dateFromUI = "12-13-2012";
const timeFromUI = "10:20";
const dateParts = dateFromUI.split("-");
const timeParts = timeFromUI.split(":");

const date = new Date(dateParts[2], dateParts[0]-1, dateParts[1], timeParts[0], timeParts[1]);

const dateISO = date.toISOString();

$.post("http://example.com/", {date: dateISO}, ...)

顯示日期和時間

  1. 從 API 獲取時間戳或 ISO 格式的日期。
  2. 創建一個日期對象。
  3. 使用 toLocaleString() 或 toLocaleDateString() 和 toLocaleTimeString() 方法或日期庫來顯示本地時間。
const dateFromAPI = "2016-01-02T12:30:00Z";

const localDate = new Date(dateFromAPI);
const localDateString = localDate.toLocaleDateString(undefined, {  
    day:   'numeric',
    month: 'short',
    year:  'numeric',
});


const localTimeString = localDate.toLocaleTimeString(undefined, {
    hour:   '2-digit',
    minute: '2-digit',
    second: '2-digit',
});

現代日期/時間處理 API:Temporal

JavaScript 中的日期處理 Date() 對象一直是飽受詬病,該對象是1995 年受到 Java 的啟發而實現的,自此就一直沒有改變過。雖然Java已經放棄了這個對象,但是 Date() 仍保留在 JavaScript 中來實現瀏覽器的兼容。

Date() API 存在的問題:

  • 只支持UTC和用戶的PC時間;
  • 不支持公歷以外的日歷;
  • 字符串到日期解析容易出錯;
  • Date 對象是可變的,比如:
const today = new Date();
const tomorrow = new Date(today.setDate(today.getDate() + 1));

console.log(tomorrow);  
console.log(today);

此時,兩個時間輸出是一樣的,不符合我們的預期。正因為 Date() 對象存在的種種問題。平時我們經常需要借助 moment.js、Day.js等日期庫,但是它們的體積較大,有時一個簡單的日期處理就需要引入一個庫,得不償失。

目前,由于Date API 在很多庫和瀏覽器引擎中的廣泛使用,沒有辦法修復API的不好的部分。而改變Date API 的工作方式也很可能會破壞許多網站和庫。

正因如此,TC39提出了一個全新的用于處理日期和時間的標準對象和函數——Temporal。新的Temporal API 提案旨在解決Date API的問題。它為 JavaScript 日期/時間操作帶來了以下修復:

  • 僅可以創建和處理不可變Temporal對象;
  • 提供用于日期和時間計算的簡單 API;
  • 支持所有時區;
  • 從 ISO-8601 格式進行嚴格的日期解析;
  • 支持非公歷。

Temporal 將取代 Moment.js 之類的庫,這些庫很好地填補了 JavaScript 中的空白,這種空白非常普遍,因此將功能作為語言的一部分更有意義。

由于該提案還未正式發布,所以,可以借助官方提供的prlyfill來測試。首選進行安裝:

npm install @js-temporal/polyfill

導入并使用:

import { Temporal } from '@js-temporal/polyfill';

console.log(Temporal);

Temporal 對象如下:

下面就來看看 Temporal 對象有哪些實用的功能。

當前時間和日期

Temporal.Now 會返回一個表示當前日期和時間的對象:

// 自1970年1月1日以來的時間(秒和毫秒)
Temporal.Now.instant().epochSeconds;
Temporal.Now.instant().epochMilliseconds;

// 當前位置的時間
Temporal.Now.zonedDateTimeISO();

// 當前時區
Temporal.Now.timeZone();

// 指定時區的當前時間
Temporal.Now.zonedDateTimeISO('Europe/London');

實例時間和日期

Temporal.Instant 根據 ISO 8601 格式的字符串返回一個表示日期和時間的對象,結果會精確到納秒:

Temporal.Instant.from('2022-02-01T05:56:78.999999999+02:00[Europe/Berlin]');
// 輸出結果:2022-02-01T03:57:18.999999999Z 
Temporal.Instant.from('2022-02-011T05:06+07:00');
// 輸出結果:2022-01-31T22:06:00Z

除此之外,還可以獲取紀元時間的對應的日期(UTC 1970年1月1日0點是紀元時間):

Temporal.Instant.fromEpochSeconds(1.0e8);
// 輸出結果:1973-03-03T09:46:40Z

時區日期和時間

Temporal.ZonedDateTime 返回一個對象,該對象表示在特定時區的日期/時間:

new Temporal.ZonedDateTime(
  1234567890000, // 紀元時間
  Temporal.TimeZone.from('Europe/London'), // 時區
  Temporal.Calendar.from('iso8601') // 默認日歷
);

Temporal.ZonedDateTime.from('2025-09-05T02:55:00+02:00[Africa/Cairo]');

Temporal.Instant('2022-08-05T20:06:13+05:45').toZonedDateTime('+05:45');
// 輸出結果:

Temporal.ZonedDateTime.from({
  timeZone: 'America/New_York',
  year: 2025,
  month: 2,
  day: 28,
  hour: 10,
  minute: 15,
  second: 0,
  millisecond: 0,
  microsecond: 0,
  nanosecond: 0
});
// 輸出結果:2025-02-28T10:15:00-05:00[America/New_York]

簡單的日期和時間

我們并不會總是需要使用精確的時間,因此 Temporal API 提供了獨立于時區的對象。這些可以用于更簡單的活動。

  • Temporal.PlainDateTime:指日歷日期和時間。
  • Temporal.PlainDate:指特定的日歷日期。
  • Temporal.PlainTime:指一天中的特定時間。
  • Temporal.PlainYearMonth:指沒有日期成分的日期,例如“2022 年 2 月”。
  • Temporal.PlainMonthDay:指沒有年份的日期,例如“10 月 1 日”。

它們都有類似的構造函數,以下有兩種形式來創建簡單的時間和日期:

new Temporal.PlainDateTime(2021, 5, 4, 13, 14, 15);
Temporal.PlainDateTime.from('2021-05-04T13:14:15');

new Temporal.PlainDate(2021, 5, 4);
Temporal.PlainDate.from('2021-05-04');

new Temporal.PlainTime(13, 14, 15);
Temporal.PlainTime.from('13:14:15');

new Temporal.PlainYearMonth(2021, 4);
Temporal.PlainYearMonth.from('2019-04');

new Temporal.PlainMonthDay(3, 14);
Temporal.PlainMonthDay.from('03-14');

日期和時間值

所有 Temporal 對象都可以返回特定的日期/時間值。例如,使用ZonedDateTime:

const t1 = Temporal.ZonedDateTime.from('2025-12-07T03:24:30+02:00[Africa/Cairo]');

t1.year;        // 2025
t1.month;       // 12
t1.day;         // 7
t1.hour;        // 3
t1.minute;      // 24
t1.second;      // 30
t1.millisecond; // 0
t1.microsecond; // 0
t1.nanosecond;  // 0

其他有用的屬性包括:

  • dayOfWeek(周一為 1 至周日為 7)
  • dayOfYear(1 至 365 或 366)
  • weekOfYear(1 到 52,有時是 53)
  • daysInMonth(28、29、30、31)
  • daysInYear(365 或 366)
  • inLeapYear(true或false)

比較和排序日期

所有 Temporal 對象都可以使用 compare() 返回整數的函數進行比較。例如,比較兩個ZonedDateTime對象:

Temporal.ZonedDateTime.compare(t1, t2);

這個比較結果會有三種情況:

  • 當兩個時間值相等時,返回 0;
  • 當 t1 在 t2 之后時,返回 1;
  • 當 t1 在 t2 之前時,但會 -1;
const date1 = Temporal.Now,
const date2 = Temporal.PlainDateTime.from('2022-05-01');

Temporal.ZonedDateTime.compare(date1, date2); // -1

compare() 的結果可以用于數組的 sort() 方法來對時間按照升序進行排列(從早到晚):

const t = [
  '2022-01-01T00:00:00+00:00[Europe/London]',
  '2022-01-01T00:00:00+00:00[Africa/Cairo]',
  '2022-01-01T00:00:00+00:00[America/New_York]'
].map(d => Temporal.ZonedDateTime.from(d))
  .sort(Temporal.ZonedDateTime.compare);

日期計算

提案還提供了幾種方法來對任何 Temporal 對象執行日期計算。當傳遞一個Temporal.Duration對象時,它們都會返回一個相同類型的新的 Temporal,該對象使用years, months, weeks, days, hours, minutes, seconds, milliseconds, microseconds 和 nanoseconds 字段來設置時間。

const t1 = Temporal.ZonedDateTime.from('2022-01-01T00:00:00+00:00[Europe/London]');

t1.add({ hours: 8, minutes: 30 }); // 往后8小時30分

t1.subtract({ days: 5 });  // 往前5天

t1.round({ smallestUnit: 'month' });  // 四舍五入到最近的月份

until() 和 since() 方法會返回一個對象,該 Temporal.Duration 對象描述基于當前日期/時間的特定日期和時間之前或之后的時間,例如:

t1.until().months; // 到t1還有幾個月

t2.until().days;  // 到t2還有幾天

t3.since().weeks; // t3已經過去了幾周

equals() 方法用來確定兩個日期/時間值是否相同:

const d1 = Temporal.PlainDate.from('2022-01-31');
const d2 = Temporal.PlainDate.from('2023-01-31');
d1.equals(d2);  // false

格式化日期

雖然這不是 Temporal API 的一部分,但 JavaScript Intl(國際化)API提供了一個 DateTimeFormat() 構造函數,可以用于格式化 Temporal 或 Date 對象:

const d = new Temporal.PlainDate(2022, 3, 14);

// 美國日期格式:3/14/2022
new Intl.DateTimeFormat('en-US').format(d);

// 英國日期格式:14/3/2022
new Intl.DateTimeFormat('en-GB').format(d);

// 西班牙長日期格式:miércoles, 14 de abril de 2022
new Intl.DateTimeFormat('es-ES', { dateStyle: 'full' }).format(d);

瀏覽器支持

目前還沒有瀏覽器支持 Temporal API:

Temporal 提案:https://tc39.es/proposal-temporal/。

日期/時間操作庫

在 JavaScript 中進行日期/時間操作是一個很麻煩的事,JS的生態中有很多實用的日期操作庫,最后就來分享幾個實用的日期庫。

Moment.js

Moment.js 是一個輕量級 JavaScript 日期庫,用于解析、驗證、操作和格式化日期,是一個很受歡迎的日期操作庫。

不過,Moment.js 是一個遺留項目,現在處于維護模式。維護者認為,無法重構 Moment.js 來滿足現代 JavaScript 開發的需求,例如不變性和 tree shaking。Lighthouse(Chrome 的內置審核工具)警告不要使用 Moment,因為它的大小較大 (329 kb)。

安裝Moment.js

可以通過以下任一方式來安裝該庫:

npm install moment --save   # npm
yarn add moment             # Yarn
Install-Package Moment.js   # NuGet
spm install moment --save   # spm
meteor add momentjs:moment  # meteor

導入Moment.js

在 JavaScript 文件中,導入Moment.js庫:

const moment = require('moment');

創建日期對象

可以傳遞一個日期字符串或日期對象給moment()函數,然后返回一個Moment對象:

const date = moment('2023-07-04');

格式化日期顯示

Moment.js 提供了豐富的日期格式化選項??梢允褂胒ormat()方法將日期格式化為所需的字符串格式:

const formattedDate = date.format('YYYY-MM-DD');
console.log(formattedDate); // 輸出:2023-07-04

日期運算

Moment.js提供了許多方便的方法來進行日期和時間的運算。下面是一些示例:

// 添加一天
const tomorrow = date.add(1, 'day');
console.log(tomorrow.format('YYYY-MM-DD')); // 輸出:2023-07-05

// 減去一個月
const lastMonth = date.subtract(1, 'month');
console.log(lastMonth.format('YYYY-MM-DD')); // 輸出:2023-06-04

// 比較日期
const otherDate = moment('2023-07-10');
console.log(date.isBefore(otherDate)); // 輸出:true
console.log(date.isAfter(otherDate)); // 輸出:false

Moment.js還提供了許多其他常用的功能,如獲取當前日期、解析日期字符串、計算日期之間的差異等。

Date-fns

Date-fns 是一個現代、輕量級的JavaScript日期處理庫,用于在瀏覽器和Node.js環境中處理日期和時間。它的設計目標是提供一組簡單、純函數式的API來執行各種日期操作,而不依賴于全局對象。

以下是Date-fns 的特點:

  1. 輕量級:Date-fns非常小巧,只包含所需的功能,可以減少項目的文件大小。
  2. 純函數:Date-fns的函數都是純函數,即相同的輸入總是產生相同的輸出,不存在副作用。這使得代碼更可預測、易測試和可維護。
  3. 易于使用:Date-fns的API設計簡單易懂,與現代JavaScript的語法和慣用法保持一致。它提供了大量的日期處理功能,如格式化、解析、比較、計算等。
  4. 兼容性:Date-fns支持所有現代的瀏覽器和Node.js版本。

安裝Date-fns

可以使用npm或yarn等包管理工具來安裝Date-fns。在項目目錄下運行以下命令安裝Date-fns:

npm install date-fns

導入Date-fns

在JavaScript文件中導入所需的Date-fns函數:

import { format, parseISO, differenceInDays } from 'date-fns';

使用Date-fns函數

使用導入的函數來執行各種日期操作。以下是一些示例:

const date = new Date();

// 格式化日期
const formattedDate = format(date, 'yyyy-MM-dd');
console.log(formattedDate); // 輸出:2023-07-04

// 解析日期字符串
const parsedDate = parseISO('2023-07-04');
console.log(parsedDate); // 輸出:Tue Jul 04 2023 00:00:00 GMT+0530 (India Standard Time)

// 計算日期之間的差異
const startDate = new Date(2023, 6, 1);
const endDate = new Date(2023, 6, 10);
const diff = differenceInDays(endDate, startDate);
console.log(diff); // 輸出:9

在上述示例中,使用了format()函數將日期格式化為指定的字符串格式,使用了parseISO()函數解析日期字符串為日期對象,以及使用了differenceInDays()函數計算兩個日期之間的天數差異。

Day.js

Day.js 是一個輕量級的JavaScript日期處理庫,用于解析、操作和格式化日期對象。它的設計目標是提供一個簡單、靈活的API,使得處理日期和時間變得更加方便。

以下是 Day.js 的特點:

  1. 輕量級:Day.js非常小巧,壓縮后僅有2 KB左右的大小,可以減少項目的文件大小。
  2. 易用性:Day.js的API設計簡潔明了,與現代JavaScript的語法和慣用法保持一致。你可以輕松地對日期進行解析、格式化、計算、比較等操作。
  3. 不可變性:Day.js的日期對象是不可變的,即每次對日期進行操作都會返回一個新的日期對象,而不會修改原始對象。這種設計模式有助于避免副作用,并提高代碼的可預測性。
  4. Moment.js兼容性:Day.js的API設計與Moment.js類似,因此可以很容易地從Moment.js遷移到Day.js,而無需更改太多代碼。

安裝Day.js

可以使用npm或yarn等包管理工具來安裝Day.js。在項目目錄下運行以下命令安裝Day.js:

npm install dayjs

導入Day.js

在JavaScript文件中導入Day.js:

import dayjs from 'dayjs';

使用Day.js函數

使用Day.js的函數來進行日期操作。以下是一些示例:

const date = dayjs();

// 格式化日期
const formattedDate = date.format('YYYY-MM-DD');
console.log(formattedDate); // 輸出:2023-07-04

// 解析日期字符串
const parsedDate = dayjs('2023-07-04');
console.log(parsedDate); // 輸出:Tue Jul 04 2023 00:00:00 GMT+0530 (India Standard Time)

// 計算日期之間的差異
const startDate = dayjs('2023-07-01');
const endDate = dayjs('2023-07-10');
const diff = endDate.diff(startDate, 'day');
console.log(diff); // 輸出:9

在上述示例中,使用了format()函數將日期格式化為指定的字符串格式,使用了dayjs()函數解析日期字符串為日期對象,以及使用了diff()函數計算兩個日期之間的天數差異。

Luxon

Luxon 是一個用于處理日期、時間和時區的先進 JavaScript 庫。它提供了一組強大的功能,可以幫助你在瀏覽器和 Node.js 環境中輕松處理日期和時間。

以下是 Luxon 的特點:

  1. 強大的日期和時間處理:Luxon 提供了豐富的 API,用于解析、格式化、操作和比較日期和時間。它支持多種標準和自定義的日期和時間格式,包括 ISO 8601、RFC 2822 等。
  2. 支持時區處理:Luxon 支持全球各地的時區,并提供了靈活的時區轉換功能。它使用 IANA(Olson)時區數據庫,確保準確的時區信息。
  3. 不可變性:Luxon 的日期對象是不可變的,每次對日期進行操作都會返回一個新的日期對象,而不會修改原始對象。這種設計模式有助于避免副作用,并提高代碼的可預測性。
  4. 鏈式調用:Luxon 的 API 允許你使用鏈式調用,使得代碼更簡潔、易讀。你可以按順序執行多個操作,而無需多次引用日期對象。

安裝 Luxon

使用 npm 或 yarn 等包管理工具,在項目目錄下運行以下命令安裝 Luxon:

npm install luxon

導入 Luxon

在 JavaScript 文件中導入 Luxon:

import { DateTime } from 'luxon';

使用 Luxon 函數

使用 Luxon 的函數來處理日期和時間。以下是一些示例:

const now = DateTime.now();

// 格式化日期
const formattedDate = now.toFormat('yyyy-MM-dd');
console.log(formattedDate); // 輸出:2023-07-04

// 解析日期字符串
const parsedDate = DateTime.fromISO('2023-07-04');
console.log(parsedDate); // 輸出:DateTime { ... }

// 計算日期之間的差異
const startDate = DateTime.fromISO('2023-07-01');
const endDate = DateTime.fromISO('2023-07-10');
const diff = endDate.diff(startDate, 'days').toObject().days;
console.log(diff); // 輸出:9

在上述示例中,使用了 toFormat() 函數將日期格式化為指定的字符串格式,使用了 fromISO() 函數解析 ISO 8601 格式的日期字符串為日期對象,以及使用了 diff() 函數計算兩個日期之間的天數差異。

責任編輯:姜華 來源: 前端充電寶
相關推薦

2022-11-16 08:41:43

2024-07-18 09:07:04

Python窗口操作

2020-09-18 09:02:20

JavaScript

2024-08-12 16:28:37

LinuxSSH密鑰

2024-08-05 09:58:24

2014-12-22 10:14:31

Java8

2020-09-15 08:28:17

JavaScript錯誤處理

2020-09-22 12:22:32

Windows TerWindowsLinux

2010-04-30 16:02:45

Unix操作系統

2010-03-31 18:47:08

Oracle時間

2020-09-14 08:35:36

JavaScript編程開發

2025-02-08 10:58:07

2024-12-13 09:42:38

javascripmatch方法

2022-09-14 10:24:54

物聯網架構物聯網

2021-10-27 08:00:00

DevSecOps開發安全

2024-07-03 14:14:07

2023-11-29 09:00:00

KubernetesDevOps

2024-05-13 08:00:00

2017-01-12 14:55:50

JavaScript編程

2016-04-25 10:23:52

點贊
收藏

51CTO技術棧公眾號

中文字幕日本在线| 日韩综合在线观看| 一区二区三区四区高清视频 | 精品亚洲欧美一区| 久久久久久久久久久久久久久久久久av | 亚洲欧美在线看| 在线观看av免费观看| 天堂中文最新版在线中文| 国产精品久久久久久福利一牛影视| 91在线视频九色| 国产成人在线免费观看视频| 99久久综合| 精品亚洲国产成av人片传媒| 精品亚洲视频在线| 日韩国产激情| 亚洲福利一二三区| 日本黄色a视频| 你懂的在线观看| 成人午夜在线免费| 成人亚洲激情网| 国产精品乱码一区二区视频| 激情国产一区| 久久久久999| 91狠狠综合久久久久久| 午夜精品福利影院| 欧美成人午夜电影| 成年网站免费在线观看| 成人做爰视频www网站小优视频| 亚洲在线一区二区三区| 影音先锋欧美资源| a黄色在线观看| 久久视频一区二区| 国产午夜精品在线| 午夜精品久久久久久久99| 美女视频黄免费的久久 | 岛国av中文字幕| 亚洲精华国产欧美| 欧美黑人极品猛少妇色xxxxx| 亚洲午夜精品久久久久久高潮| 国产精品jk白丝蜜臀av小说| 日韩一区二区三区电影| www.久久久久久久久久久| 成人在线免费| 欧美偷拍一区二区| 亚洲欧美另类动漫| 免费观看一级欧美片| 欧美日韩国产麻豆| 131美女爱做视频| а√天堂8资源在线| 亚洲一区二区在线视频| 久久久久久久久久伊人| 国产在线观看a视频| 亚洲欧洲性图库| 在线亚洲美日韩| 美女羞羞视频在线观看| 亚洲日本在线a| 成人在线免费高清视频| 在线观看a级片| 亚洲一线二线三线久久久| 日本五级黄色片| 免费电影视频在线看| 一区二区三区高清不卡| 99在线观看视频免费| 爱啪视频在线观看视频免费| 一区二区三区四区视频精品免费| 欧美a级免费视频| 99riav视频在线观看| 亚洲福利一二三区| 激情五月开心婷婷| 欧美另类激情| 日韩一级在线观看| 91视频啊啊啊| 精品久久不卡| 欧美精品在线看| 国产91av视频| 日日嗨av一区二区三区四区| 国产一区二区在线免费视频| 国产av无码专区亚洲a∨毛片| 成人午夜电影网站| 欧美一区二区三区精美影视| 最新97超碰在线| 亚洲制服欧美中文字幕中文字幕| 国产精品网站免费| 欧美在线se| 精品久久一二三区| 国产毛片久久久久久久| 91成人免费| 97在线免费观看| 黄色污污网站在线观看| 激情综合网最新| 国产亚洲精品美女久久久m| 国产福利免费在线观看| 亚洲精品欧美专区| 免费高清在线观看免费| www久久久| 亚洲人成电影网| 欧美日韩在线国产| 日韩电影网1区2区| 国产精品12| 国产粉嫩一区二区三区在线观看| 亚洲精品网站在线观看| 日本精品免费在线观看| 日本高清久久| 中文字幕久热精品视频在线| 国产在线成人精品午夜| 免费看精品久久片| 九九九热999| 污污影院在线观看| 精品视频免费看| 精品夜夜澡人妻无码av| 亚洲精品一区二区妖精| 欧美中在线观看| 亚洲黄色小说网址| 中文字幕一区二区三区不卡在线 | 极品少妇xxxx偷拍精品少妇| 精品国产乱码久久久久久108| 好吊日视频在线观看| 91国产视频在线观看| v天堂中文在线| 欧美日韩蜜桃| 成人a在线观看| yw193.com尤物在线| 黑人巨大精品欧美一区二区免费| 手机看片国产精品| 欧美顶级大胆免费视频| 国产精品黄视频| 色视频免费在线观看| 亚洲大尺度视频在线观看| 超碰人人cao| 亚洲精品电影| 成人国产精品免费视频| 第一福利在线| 91成人在线精品| 国产色视频一区二区三区qq号| 在线精品亚洲| 成人综合av网| 欧美bbbxxxxx| 精品国产伦理网| 久久久久久天堂| 国产精品亚洲午夜一区二区三区 | 日韩丝袜情趣美女图片| 九九精品视频免费| 国产呦萝稀缺另类资源| 欧美 另类 交| 免费精品一区二区三区在线观看| 色诱女教师一区二区三区| 中文字幕免费在线看| 欧美经典一区二区| 自拍偷拍21p| 久久久影院免费| 成人黄色av网| 国产在线69| 日韩美女视频一区二区在线观看| 欧美精品一级片| 成人精品小蝌蚪| 三上悠亚久久精品| 视频一区欧美| 国产精品偷伦一区二区| 日本成人网址| 日韩欧美另类在线| 国产成年人免费视频| 久久网这里都是精品| 国产精品久久久久9999小说| 青青草原综合久久大伊人精品 | 亚洲奶汁xxxx哺乳期| 亚洲国产成人av| 亚洲一区二区三区四区五区六区| 性感少妇一区| 少妇特黄a一区二区三区| 成人福利片在线| 久久av.com| 成人小说亚洲一区二区三区| 婷婷激情综合网| 国产毛片欧美毛片久久久| 极品销魂美女一区二区三区| 日韩极品视频在线观看| 国产免费播放一区二区| 成人性生交xxxxx网站| av电影在线免费| 国产亚洲欧美日韩美女| 91theporn国产在线观看| 亚洲自拍与偷拍| 一区二区三区四区免费| 极品尤物av久久免费看| 玩弄中年熟妇正在播放| 欧美熟乱15p| av日韩中文字幕| 国产亚洲一区二区手机在线观看 | jizz久久久久久| 欧美成人在线影院| 蜜桃视频在线入口www| 日韩欧美在线综合网| 午夜精品一区二| 亚洲精品老司机| 中文字幕免费高清| 国产精品一区二区不卡| 红桃av在线播放| 一区二区三区在线| 日韩精品福利视频| 9l亚洲国产成人精品一区二三| 国产成人精品在线播放| 欧美卡一卡二| 日韩视频免费在线| 日韩欧美在线番号| 欧美成人国产一区二区| 中文天堂在线视频| 欧美日韩国产一区中文午夜| 天堂网avav| 国产欧美一区二区三区网站| 天天躁日日躁狠狠躁av| 激情六月婷婷综合| 国产一线二线三线在线观看| 亚洲激情社区| 国产女人18毛片| 日本精品黄色| 欧美极品色图| 精品久久ai电影| 国产成人亚洲欧美| 亚洲精品成a人ⅴ香蕉片| 日本久久久a级免费| 国产第一页在线| 久久综合五月天| 91网在线播放| 国产亚洲一区二区在线| 国产又爽又黄网站亚洲视频123| 欧美一区二区私人影院日本| 在线观看视频二区| 狠狠躁夜夜躁人人躁婷婷91| 极品颜值美女露脸啪啪| 中文字幕一区二区三区视频| 免费一级特黄3大片视频| 91在线视频在线| 中文字幕第3页| 成人午夜激情影院| 91精品啪在线观看国产| 东方欧美亚洲色图在线| 国产女主播在线播放| 国产69精品久久777的优势| 久久无码人妻一区二区三区| 毛片一区二区三区| 国产精品一区二区小说| 秋霞午夜鲁丝一区二区老狼| 成年人在线观看视频免费| 日韩vs国产vs欧美| 久久综合伊人77777麻豆最新章节| 久久成人亚洲| 能看的毛片网站| 三级久久三级久久| 91插插插插插插插插| 麻豆中文一区二区| 日韩中文字幕a| 韩国女主播成人在线| 熟妇无码乱子成人精品| 国产91精品精华液一区二区三区| 韩国三级在线看| av一区二区三区| 亚洲a v网站| 国产精品久久久久精k8| 欧美激情图片小说| 亚洲成人av电影在线| 久久久久久久久久久影院| 日本乱人伦一区| 在线播放精品视频| 欧美一区二区三区系列电影| 亚洲第一成年人网站| 日韩成人av一区| 成人性生交大片免费看午夜 | 1区2区3区在线| 清纯唯美亚洲综合| 国产原创一区| 国产精品v欧美精品v日韩| 日韩av三区| 三区精品视频| 欧美在线二区| 国产91在线免费| 老司机午夜精品| 国产在线观看免费播放| 久久久电影一区二区三区| www.4hu95.com四虎| 一区二区三区自拍| 依依成人综合网| 777精品伊人久久久久大香线蕉| 亚洲精品久久久久久久久久| 亚洲欧美制服丝袜| 在线网址91| 日韩av123| 久久视频免费| 欧美一区免费视频| 欧美不卡视频| 黄色一级免费大片| 国产激情91久久精品导航| 美女100%无挡| 亚洲夂夂婷婷色拍ww47| 一区二区视频网站| 亚洲精品国偷自产在线99热| 生活片a∨在线观看| 亚洲**2019国产| 超碰国产精品一区二页| 麻豆91av| 亚洲午夜精品久久久久久app| 精品亚洲一区二区三区四区| 99精品久久只有精品| 性欧美疯狂猛交69hd| 色婷婷综合视频在线观看| 国产成a人亚洲精v品无码| 国产午夜精品全部视频播放| 国产盗摄一区二区| 亚洲free嫩bbb| 青青草91久久久久久久久| 大肉大捧一进一出好爽视频| 国产盗摄精品一区二区三区在线| 五月天综合视频| 福利视频导航一区| 亚洲精品18p| 久久久精品视频在线观看| 嫩草伊人久久精品少妇av杨幂| 国产精品制服诱惑| 亚洲香蕉av| 奇米视频7777| 中文字幕精品三区| 青青草免费观看视频| 精品国产1区2区3区| 91在线中字| 91免费综合在线| 99久久99热这里只有精品| 超碰在线97免费| 国产色综合一区| 99精品人妻国产毛片| 亚洲成人黄色在线| 日本在线观看高清完整版| 91视频九色网站| 午夜免费一区| xxxx在线免费观看| 亚洲欧洲日产国产综合网| 精品国产青草久久久久96| 亚洲色图35p| 婷婷激情一区| 欧美日韩国产精品一卡| 久久福利精品| 免费福利视频网站| 91搞黄在线观看| aaa在线观看| 91精品国产综合久久香蕉的用户体验| 欧美中文一区二区| 午夜久久久精品| 亚洲欧美综合另类在线卡通| 91黄色在线视频| 欧美成aaa人片免费看| 欧美成人精品午夜一区二区| 狠狠干视频网站| av一本久道久久综合久久鬼色| 国产情侣自拍av| 国产丝袜一区二区三区免费视频| 悠悠资源网亚洲青| 日韩高清专区| 美女爽到高潮91| 日日骚一区二区三区| 日韩美一区二区三区| 国产精品13p| 日韩国产在线一区| 久久成人精品无人区| 1024手机在线视频| 亚洲国产三级网| 欧美男体视频| 在线视频一区观看| 成人av影院在线| 日日夜夜狠狠操| 久久天天躁狠狠躁夜夜爽蜜月| 中文字幕日韩高清在线| a√天堂在线观看| 国产精品乱人伦| 亚洲av无码专区在线| 欧美在线性视频| 欧美a级成人淫片免费看| 亚洲在线观看网站| 欧美性高潮在线| 日本三级在线视频| 国产青春久久久国产毛片| 老司机午夜精品视频| 日韩一级片大全| 亚洲乱码国产乱码精品精| 亚洲天堂1区| av女优在线播放| 国产精品人妖ts系列视频| 亚洲av无码一区二区乱子伦| 国产不卡视频在线| 欧美1区2区视频| 极品久久久久久久| 亚洲第一区在线观看| www.26天天久久天堂| 女人帮男人橹视频播放| 国产免费成人在线视频| 亚洲第一成人av| 国产精品偷伦一区二区| 亚洲精品在线二区| 国产免费美女视频| 亚洲天堂免费视频| 国产成人aa在线观看网站站| 浓精h攵女乱爱av| 欧美日韩国产一区二区|