JavaScript >> Javascript 文檔 >  >> Tags >> Date

Moment.js:一個更好的 JavaScript 日期庫

任何有經驗的程序員都知道,日期和時間在大多數應用程序級代碼中非常常見。您可以使用日期來跟踪對象的創建、跟踪事件發生後的時間或保存即將發生的事件的日期。但是,日期並不容易使用,因此擁有一個既準確又具有簡單界面的庫非常重要。標準 JavaScript Date 對像還不錯,但它缺少一些重要的功能,而且使用起來並不總是那麼簡單。

在本文中,您將了解 Moment 如何使日期和時間易於解析、格式化和操作。

解析日期

字符串

默認情況下,Moment 嘗試使用 ISO 8601 格式解析日期字符串,該格式具有廣泛的有效日期。您可以使用此格式在日期時間中指定盡可能少或盡可能多的時間精度。這對我們來說非常有用,因為日期可以採用多種不同的形式,具體取決於您要指​​定的詳細程度。

考慮嘗試自己解析所有這些不同的格式:

  • 20160628
  • 2016-06-28T09
  • 20160628T080910,123
  • 2016-06-28 09:30:26.123
  • 2016-06-28 09:30:26.123+07:00

如您所見,不僅時間精度會發生變化,而且指定它的格式也會有很大差異,這就是為什麼擁有一個功能強大的時間解析器如此重要的原因。

首先,創建 moment 的最簡單方法 object 是調用不帶參數的構造函數:

> const moment = require('moment');
> let m = moment();

這將使用當前時間實例化一個日期對象。

要使用 Moment 解析日期時間字符串,只需將其傳遞給構造函數即可:

> let date = moment('2016-06-28 09:30:26.123');

如果由於某種原因 Moment 無法解析你給它的字符串,那麼它將回退到使用內置的 new Date() 解析對象。

要檢查您的日期是否已解析且有效,請使用 .isValid() 方法:

> moment('2016-06-28 09:30:26.123').isValid();
true
> moment('derp').isValid();
false

對於所有使用 Moment 創建的日期對象,無論您如何解析或創建它們,對像中的時區都將默認為當前時區,除非直接指定。要返回 UTC 時間,請使用 moment.utc() 反而。有關時區的更多信息,請查看時刻時區部分。

指定格式

Moment 中我最喜歡的解析功能之一是字符串/格式解析器。它基本上就像一個反向字符串格式化程序。您提供要解析的日期時間字符串 另一個指定其格式的字符串。這樣您可以使用任何您想要的格式的字符串,並且仍然可以輕鬆地將它們與 Moment 一起使用。

例如,在美國(出於某種原因),我們喜歡將日期格式設置為“月/日/年”,而世界其他大部分地區將日期格式設置為“日/月/年”。這留下了很大的混亂空間。例如,日期“11/06/2016”應該是 11 月 6 日還是 6 月 11 日?


圖片:衛報的 John Harding/Mona Chalabi

那麼我們如何知道您的日期是否被正確解析?使用這樣的格式說明符可確保您的日期沒有歧義,假設您事先知道它們的格式。在下面的示例中,儘管格式不同且可能令人困惑,我們仍然能夠解析正確的日期。

> let d1 = moment('11.06.2016', 'DD-MM-YYYY');
> let d2 = moment('06/11/2016', 'MM-DD-YYYY');

> d1.format();    // '2016-06-11T00:00:00-05:00'
> d2.format();    // '2016-06-11T00:00:00-05:00'

請注意,我們還在日期字符串中使用了不同的分隔符“.”。和 ”/”。 Moment 在使用這些格式時實際上會忽略所有非字母數字字符,因此您不必總是擔心完美匹配格式。

有關完整的可用格式標記集,請查看 Moment.js 文檔的這一部分。

Unix 時間戳

如您所料,Moment 還能夠解析整數日期(Unix 時間),無論是秒還是毫秒格式:

> moment.unix(1467128085);      // Date in seconds from 1970
> moment(1467128085747);        // Date in milliseconds from 1970

結果時間的唯一區別是精度。 millisecondDate 毫秒字段將具有非零值。

打印日期

在我看來,這是 Moment 中比較有用的部分之一,主要是因為 JavaScript 內置的 Date object 對它沒有很好的支持。令人驚訝的是,使用 Date 進行格式化的唯一內置方法 是使用Date.toLocaleDateString() 方法,感覺很笨拙,不夠靈活:

> let d = new Date(1467128085747);
> let options = {
...    weekday: 'long', year: 'numeric', month: 'short',
...    day: 'numeric', hour: '2-digit', minute: '2-digit'
... };

> date.toLocaleTimeString('en-us', options);
'Tuesday, Jun 28, 2016, 10:34 AM'

使用 Moment,我們只需一行代碼就可以輕鬆實現相同的格式(我將在下一節中展示)。

我們將把它分解成幾個小節。首先,我們將介紹帶有標記的傳統格式,然後我們將展示可用的相對日期格式(如“18 分鐘前”),最後我們將展示如何將日期格式化為不同類型的結構化數據,例如數組、JSON 或純 JavaScript Object .

格式化

使用 .format() 將日期顯示為字符串的方法。沒有任何參數,它以 ISO 8601 表示形式打印字符串:

> let date = moment.unix(1467128085);
> date.format();
'2016-06-28T10:34:45-05:00'

否則,您可以提供自己的格式並使用令牌根據自己的喜好對其進行自定義。

> date.format('dddd, MMMM Do YYYY, h:mm a');
'Tuesday, June 28th 2016, 10:34 am'

您可能會注意到這與 Date.toLocaleTimeString() 的表示形式相同 上面的例子,但在一行中。所需要的只是字符串 'dddd, MMMM Do YYYY, h:mm a'。

同樣,格式標記的完整列表可以在 Moment 非常詳盡的文檔網站上找到。

相對格式

例如,在 Web 應用程序中,經常向用戶顯示事件發生後已經過去了多少時間很有幫助。 Moment 提供了一些實用函數來為您處理這種格式設置,而不是自己計算。

在所有情況下,您都可以使用過去或未來的任何日期,返回的字符串將反映正確的時態。

開箱即用,您可以獲得幾個不同的選項:

從現在開始

假設今天的日期是 2016 年 7 月 1 日,您將獲得以下相對格式:

免費電子書:Git Essentials

查看我們的 Git 學習實踐指南,其中包含最佳實踐、行業認可的標準以及隨附的備忘單。停止谷歌搜索 Git 命令並真正學習 它!

> moment({year: 2016, month: 3, day: 13, hour: 10}).fromNow();
'3 months ago'
> moment({year: 2016, month: 9, day: 23, hour: 10}).fromNow();
'in 4 months'

您可以選擇傳遞 Boolean.fromNow() 告訴它是否在格式中包含“ago”(或“in”)字符串。這樣您仍然可以在需要時輕鬆自定義相對字符串。

> moment({year: 2016, month: 3, day: 13, hour: 10}).fromNow(true);
'3 months'

從日期開始的時間

> let may = moment({year: 2016, month: 5, day: 3});
> let october = moment({year: 2016, month: 10, day: 9});
>
> may.from(october);
'5 months ago'
> october.from(may);
'in 5 months'

現在時間

> moment({year: 2016, month: 3, day: 13, hour: 10}).toNow();
'in 3 months'
> moment({year: 2016, month: 9, day: 23, hour: 10}).toNow();
'4 months ago'

時間日期

> let may = moment({year: 2016, month: 5, day: 3});
> let october = moment({year: 2016, month: 10, day: 9});
> may.to(october)
'in 5 months'
> 
> october.to(may)
'5 months ago'

您可能已經註意到,“from”和“to”方法都可以互換,具體取決於參數中傳遞的日期。都是相對的。

結構化日期時間

在某些情況下,將日期數據採用結構化格式可能更方便,可能用於算法或序列化。 Moment 提供了幾種不同的方式將數據格式化為數據結構:

  • toDate() :以 JavaScript Date 形式返回 Moment 日期
  • toArray() :以數組形式返回日期數據 - [ 2016, 5, 28, 10, 34, 45, 747 ]
  • toJSON() :返回調整為 UTC 的 ISO 日期字符串 - “2016-06-28T15:34:45.747Z”
  • toISOString() :返回調整為 UTC 的 ISO 日期字符串 - “2016-06-28T15:34:45.747Z”
  • toObject() :返回一個純 JavaScript Object 帶有日期數據 - {years: 2016, months: 5, date: 28, hours: 10, minutes: 34, seconds: 45, milliseconds: 747}
  • toString() :返回類似於 Date.toString() 的格式化字符串 - “2016 年 6 月 28 日星期二 10:34:45 GMT-0500”

操縱日期

對於許多應用程序來說,操作日期的能力也非常重要。這也不像你的普通算術那麼簡單——操縱日期很困難。你能輕鬆算出這些日期/時間的加法/減法嗎?編程不是一件容易的事。

  • 2 月 21 日 + 13 週
  • 凌晨 3:14 + 424 分鐘
  • 7 月 1 日 - 1899400140 毫秒

現在,如果是閏年呢?還是有閏秒的年份?幸運的是,您不需要自己弄清楚這一點。時刻已經為你準備好了。

時間操作的方法有很多,這裡只介紹比較常用的幾種:

加/減

使用數字/字符串或對象來操作日期:

> moment().add(7, 'days');
> moment().subtract({days:13, months:3});

鏈接也很有效:

> moment().add({hours: 7}).subtract(13, 'minutes');

時間的開始/結束

這些便捷方法將日期/時間設置為給定時間單位的末尾。例如,如果您有一個時間為 2:15 的日期,但您需要它作為一天的開始,您可以使用:

> moment().startOf('day');

這會將時間設置為當天的凌晨 12:00。同樣適用於年、月、小時等等。

> moment().endOf('year');   // sets date to 12-31-2016 23:59:59.999

我發現這在用戶可以選擇報告時間範圍的報告應用程序中非常有用,例如 Google Analytics。為了檢索正確的數據,您需要有正確的範圍。

時刻時區

Moment 支持開箱即用設置時區偏移量,但如果您需要更好的時區支持,那麼您應該考慮使用 moment-timezone .

該庫允許您按城市、地區或其他標識符指定時區,這可以讓面向用戶的應用程序變得更加簡單。

要使用它,請使用 npm 和 require() 安裝 代替 moment

> const moment = require('moment-timezone');

擁有超過 550 個時區標識符,您可以按不同的區域類別和名稱來劃分您的時區說明符:

  • 時區名稱:美國/中部、美國/東部、美國/山區等
  • 城市:美國/芝加哥、美國/洛杉磯、亞洲/迪拜、澳大利亞/悉尼等
  • GMT 偏移量:Etc/GMT+6、Etc/GMT-2、Etc/GMT0 等

對於時區標識符的完整列表,您可以通過執行以下命令查看完整的名稱列表:

> const moment = require('moment-timezone');
> moment.tz.names()

使用這些標識符通過 .tz() 設置時間和時區 方法:

> moment.tz({year: 2016, month: 6, day: 30, hour: 11}, 'America/Los_Angeles').format();
'2016-07-30T11:00:00-07:00'
> moment.tz({year: 2016, month: 6, day: 30, hour: 11}, 'America/Chicago').format();
'2016-07-30T11:00:00-05:00'

結論

以編程方式處理日期和時間很困難,但這並不一定是您所做的最困難的事情。 Moment 是一個很好的例子,它通過一個乾淨且易於使用的 API 使一個困難的主題變得更加簡單。

除了 Moment 提供的解析、格式化和操作之外,還有通過 moment-timezone 對時區的附加支持 包裹。通過添加對時區的更好支持,讓您和您的用戶的生活更輕鬆。

您經常使用 Moment 的其他哪些功能?請在評論中告訴我們!


Tutorial JavaScript 教程
  1. 使用回溯算法解決數獨

  2. Firebase:用於構建應用程序的谷歌 API

  3. PascalCase 問題

  4. GraphQL 簡介

  5. 胡迪尼

  6. 不夠雄辯

  7. 如果尚未加載 jQuery,我該如何加載它?

  1. JSX 簡介

  2. Vue3 Composition API - 創建可拖動元素

  3. 使用 GraphQL 和 Chart.js 構建實時權力遊戲投票應用程序

  4. Babel 的資助計劃

  5. 將 ReactJS 組件轉換為 VueJS

  6. 如何在 nextjs 中將對像作為道具傳遞

  7. Buildspace 項目:構建 web 3 應用程序……我的筆記

  1. 像你 5 歲一樣解釋 JavaScript 中的回調函數

  2. Next.js 自定義鏈接屬性

  3. 拖拽下載:從瀏覽器拖拽鏈接到桌面下載

  4. 合併函數