<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          7種最佳JavaScript日期庫(kù)

          共 6746字,需瀏覽 14分鐘

           ·

          2020-09-08 06:28


          英文 | https://blog.logrocket.com/javascript-date-libraries/

          從理論上講,向您的應(yīng)用程序添加工作日期似乎總是一件容易的事,除非您嘗試這樣做??偸菚?huì)遇到麻煩,無(wú)論是在嘗試使您的網(wǎng)站國(guó)際化時(shí)的時(shí)區(qū)問(wèn)題,還是以所需格式顯示日期的問(wèn)題,甚至試圖對(duì)它們進(jìn)行一些基本的算術(shù)運(yùn)算。
          不幸的是,JavaScript并沒(méi)有真正準(zhǔn)備好處理日期。這有點(diǎn)諷刺,因?yàn)樗_實(shí)有一個(gè)日期對(duì)象,我們可以用它來(lái)進(jìn)行一些基本的操作。
          我說(shuō)JavaScript還沒(méi)準(zhǔn)備好是什么意思呢?我的意思是,這個(gè)對(duì)象的API不夠豐富,不能滿(mǎn)足我們的日常需求,它沒(méi)有您所期望的來(lái)自這樣一個(gè)對(duì)象的高級(jí)支持來(lái)處理國(guó)際化、時(shí)區(qū)支持等問(wèn)題。
          這就是我將要回顧的庫(kù)發(fā)揮作用的地方。這七個(gè)日期庫(kù)在JavaScript的日期對(duì)象之上添加了抽象層,并使其實(shí)際有用。
          moment.js
          Moment.js是Node.js和Vanilla JavaScript(使其與瀏覽器兼容)的最古老,最知名的日期相關(guān)庫(kù)之一。因此,他們有時(shí)間使其與許多最常見(jiàn)的Web開(kāi)發(fā)實(shí)用程序兼容,例如:
          • Bower

          • requireJS

          • Nuget

          • Browsify

          • TypeScript

          • meteor

          它提供了一個(gè)很棒的API,而不需要修改Date對(duì)象的原始原型,相反,他們?cè)贒ate對(duì)象周?chē)鷦?chuàng)建了一個(gè)包裝器對(duì)象,以確保不破壞原始名稱(chēng)空間。
          作為一個(gè)簡(jiǎn)單的示例,下面是如何設(shè)置當(dāng)前日期。加上7天,然后減去一個(gè)月,最后設(shè)置年份和時(shí)間值。所有這些都在一行易于閱讀的代碼中,就像這樣:
          moment().add(7, 'days').subtract(1, 'months').year(2009).hours(0).minutes(0).seconds(0);
          它們支持20多個(gè)不同的地區(qū),因此如果您想解決國(guó)際化問(wèn)題,最好使用moment.js。
          插件的生態(tài)系統(tǒng)
          一個(gè)特定庫(kù)的成功和整體實(shí)用性的一個(gè)很好的衡量標(biāo)準(zhǔn)是檢查存在于該庫(kù)周?chē)牟寮?擴(kuò)展生態(tài)系統(tǒng)。就moment.js而言,有22個(gè)官方支持的版本。
          乍一看,這可能不是一個(gè)很大的數(shù)目,但是如果您考慮所有這些庫(kù)都是圍繞一個(gè)對(duì)象(Date對(duì)象)設(shè)計(jì)的,那么擁有超過(guò)20個(gè)插件無(wú)疑是一個(gè)很好的跡象。
          你可以在他們的文檔頁(yè)面上找到完整的插件列表,但其中一些最有趣的是:
          twitter時(shí)間
          它允許你像Twitter一樣格式化你的日期和時(shí)間(注意他們是如何用一個(gè)字母縮寫(xiě)他們的時(shí)間日期的,比如1h表示“1小時(shí)前”,2d表示“2天前”)。
          有了這個(gè)插件,你可以做一些簡(jiǎn)單的事情:
          moment().subtract(6, 'days').twitterShort();
          返回“6 d”。
          解析的格式
          當(dāng)你試圖以一種特定的方式顯示你的日期時(shí),你寫(xiě)了多少次日期格式?類(lèi)似于YYYY-MM-dd或類(lèi)似的變體。但是我們總是手動(dòng)編寫(xiě)它,然后庫(kù)相應(yīng)地格式化日期。
          這個(gè)插件不是格式化日期,而是解析一個(gè)日期字符串并返回實(shí)際的格式供您重用。
          你可以這樣做:
          var format = moment.parseFormat('Thursday, February 6th, 2014 9:20pm');// format will contain: dddd, MMMM Do, YYYY h:mma
          這個(gè)特別的插件非常適合將動(dòng)態(tài)行為添加到您的格式化邏輯中,例如,使格式化成為動(dòng)態(tài)的,并允許您的用戶(hù)輸入一個(gè)日期示例,而不是讓他們學(xué)習(xí)如何配置自己的格式。
          計(jì)時(shí)器
          這實(shí)際上是對(duì)JavaScript的setTimeInterval和setTimeout函數(shù)的完全重寫(xiě),允許您混合moment的語(yǔ)法并創(chuàng)建一個(gè)更強(qiáng)大的計(jì)時(shí)器。
          你可以這樣做:
          var timer = moment.duration(5, "seconds").timer({loop: true},function() {  // Callback});
          與以下內(nèi)容相比,以下內(nèi)容更容易閱讀和理解:
          setInterval(function() {  //Callback  }, 5000)
          date-fns
          date-fns被宣傳為大量的數(shù)據(jù)庫(kù),它試圖提供比Moment.js更好的體驗(yàn)。
          它的API非常廣泛,有140多個(gè)不同的與時(shí)間相關(guān)的函數(shù),它們的創(chuàng)建者和貢獻(xiàn)者希望讓您從使用Moment切換到自己的時(shí)間管理解決方案。
          該庫(kù)的一些關(guān)鍵方面是:
          • 所有函數(shù)都是按文件分組的,允許您導(dǎo)入您需要的東西,而不必為您真正使用的兩個(gè)方法而使項(xiàng)目變得臃腫。這對(duì)于需要優(yōu)化每js行字節(jié)數(shù)的前端開(kāi)發(fā)人員特別有用,因?yàn)槊總€(gè)字節(jié)都很重要。對(duì)于Node.js開(kāi)發(fā)人員來(lái)說(shuō),這對(duì)于保持導(dǎo)入仍然很有用,并且需要更有條理。

          • 與其他庫(kù)(查看您的Moment.js)不同,date-fns返回的日期對(duì)象是不可變的,這有助于避免不必要的修改和無(wú)數(shù)個(gè)小時(shí)的調(diào)試。

          • FP子模塊提供了一組與FP相關(guān)的功能,可以幫助您輕松地通過(guò)幾行代碼來(lái)組成復(fù)雜的行為。

          • 它們總共支持57個(gè)不同的地區(qū),所以如果您的目標(biāo)是國(guó)際化,這里是另一個(gè)不錯(cuò)的選擇!

          • 他們有TypeScript和流支持。

          • 最后但并非最不重要的是,他們的文檔非常詳細(xì),這是我從一個(gè)庫(kù)中一直欣賞的東西,特別是那些具有如此廣泛的API的文檔。

          一些代碼示例:
          讓我們快速運(yùn)行一些代碼示例,讓您了解這個(gè)庫(kù)的獨(dú)特之處。
          const { addYears, formatWithOptions  } = require('date-fns/fp')const { es } = require('date-fns/locale')
          const addFiveYears = addYears(5)
          const dateToString = formatWithOptions({ locale: es }, 'd MMMM yyyy')
          const dates = [ new Date(2017, 0, 1), new Date(2017, 1, 11), new Date(2017, 6, 2)]
          const toUpper = arg => String(arg).toUpperCase()
          const formattedDates = dates.map(addFiveYears).map(dateToString).map(toUpper)//=> ['1 ENERO 2022', '11 FEBRERO 2022', '2 JULIO 2022']
          這個(gè)例子展示了我上面提到的兩點(diǎn):每個(gè)文件的功能機(jī)制,使您只需要實(shí)際需要的位(兩個(gè)導(dǎo)入都利用了示例中的位)和功能編程輔助函數(shù)。
          請(qǐng)注意,如何使用這兩個(gè)導(dǎo)入的函數(shù)(addYears和formatWithOptions)在最后一行(這兩個(gè)函數(shù)以及toUpper匿名函數(shù))中組成整個(gè)過(guò)程。
          關(guān)于代碼的一個(gè)簡(jiǎn)短說(shuō)明:盡管它與庫(kù)主頁(yè)上顯示的示例相同,但我必須使它與Node.js兼容。
          Luxon
          luxon是一個(gè)非常有趣的項(xiàng)目,因?yàn)槿绻榭此膗rl,它就位于moment.js項(xiàng)目下,那么它為什么會(huì)存在呢?你可以從作者自己那里讀到整個(gè)故事,但主要的要點(diǎn)是,它試圖成為一個(gè)更好的版本,然而:
          • 它目前并不真正支持moment. js支持的所有功能。

          • 它嚴(yán)重依賴(lài)于來(lái)自現(xiàn)代瀏覽器的Intl API,因此舊的瀏覽器將很難處理與國(guó)際化相關(guān)的方法。

          與它的前輩(如果我們可以調(diào)用Moment.js)相比,Luxon的主要區(qū)別之一是,所有對(duì)象都是不可變的,你可能會(huì)說(shuō)Moment.js做出了一個(gè)糟糕的決定,讓他們的對(duì)象發(fā)生了變化,而社區(qū)里的每個(gè)人都想盡辦法去解決這個(gè)問(wèn)題。
          var m1 = moment();var m2 = m1.add(1, 'hours');m1.valueOf() === m2.valueOf(); //=> true
          var d1 = DateTime.local();var d2 = d1.plus({ hours: 1 });d1.valueOf() === d2.valueOf(); //=> false
          在上面的例子中,您可以看到這種不同的作用,而對(duì)于moment.js(第一個(gè)例子),您會(huì)遇到那種“問(wèn)題”(這里有引號(hào),因?yàn)閱?wèn)題只在您不注意的情況下才會(huì)發(fā)生),因?yàn)閍dd方法會(huì)變異m1,而不是返回m2上的新值,luxon的api會(huì)阻止您遇到這個(gè)問(wèn)題,因?yàn)閜lus在d2上返回一個(gè)新對(duì)象,而不是修改d1。
          與moments .js的另一個(gè)重大區(qū)別是,國(guó)際化是基于來(lái)自瀏覽器的Intl API。本質(zhì)上,這意味著:
          • 您不需要額外的配置文件來(lái)處理語(yǔ)言環(huán)境,瀏覽器會(huì)為您完成這些工作。

          • 如果你想在Node上實(shí)現(xiàn)這個(gè)功能,你需要一個(gè)polyfill模塊或者構(gòu)建一個(gè)有完整ICU支持的Node。如果這兩項(xiàng)都不做,庫(kù)仍然可以工作,但是本地化函數(shù)什么也做不了。

          如果您是Moment.js用戶(hù),您可能會(huì)對(duì)其他更改感興趣,所以一定要查看他們的文檔。
          DayJS
          DayJS試圖成為Moment.js的縮小版(人們?cè)谶@里看到這些模式了嗎?)。對(duì)于聲稱(chēng)擁有Moment.js相同API并將其文件大小減少97%的庫(kù),可以說(shuō)些什么。
          沒(méi)錯(cuò),Moment.js完整壓縮文件的總重量為67,9Kb,而DayJS壓縮文件的大小僅為2Kb。太瘋狂了,但是他們支持國(guó)際化,插件和其他所有功能。
          當(dāng)每個(gè)人都在使用下劃線時(shí),你可以把dayjs看作lodash。lodash出現(xiàn)在圖片中,提出了一個(gè)類(lèi)似的聲明,他們有一個(gè)非常相似的api,占用空間更小,他們總是試圖節(jié)省盡可能多的字節(jié),以減少加載時(shí)間。
          就像Moment.js一樣,該庫(kù)有大約20個(gè)正式支持的插件,您可以在其文檔中查看。
          最后,雖然這個(gè)庫(kù)似乎是它所聲稱(chēng)的一切,開(kāi)發(fā)人員開(kāi)始采用它,如下面的下載趨勢(shì)圖所示:

          MomentJS的月下載量仍然很高,因?yàn)樗呀?jīng)有8年多的歷史了(與DayJS 1年多的歷史相比)。這將需要一些時(shí)間,但如果MomentJS不適應(yīng)(也許Luxon可能是一個(gè)選擇?)它將最終被這個(gè)新來(lái)的家伙所取代。
          由于API實(shí)際上與MomentJS是一樣的,所以展示代碼示例是沒(méi)有意義的,如果您需要特殊的東西,只需檢查他們的官方文檔,如果您擔(dān)心加載時(shí)間和數(shù)據(jù)使用(對(duì)于移動(dòng)web開(kāi)發(fā)人員來(lái)說(shuō)是一個(gè)大問(wèn)題),則切換到DayJS。
          ms
          為了稍微改變一下,下一個(gè)庫(kù)并不是作為MomentJS的替代品創(chuàng)建的(我知道,令人震驚!),相反,它只有一個(gè)任務(wù),而且做得非常好。
          MS的目標(biāo)是將任何類(lèi)型的日期格式轉(zhuǎn)換為毫秒并返回。
          這是一個(gè)非常狹窄的用例,我知道,但你知道,日期轉(zhuǎn)化為毫秒都有其優(yōu)點(diǎn),尤其是如果你想做比較,和某些形式的算術(shù)運(yùn)算(這很容易添加1000毫秒數(shù),比說(shuō)你需要添加1秒約會(huì)對(duì)象)。
          換句話說(shuō),有了這個(gè)庫(kù),你可以這樣做:
          ms('2 days')  // 172800000ms('1d')      // 86400000ms('10h')     // 36000000ms('2.5 hrs') // 9000000ms('2h')      // 7200000ms('1m')      // 60000ms('5s')      // 5000
          ms(60000) // "1m"ms(2 * 60000) // "2m"ms(-3 * 60000) // "-3m"
          考慮到這個(gè)庫(kù)每周有超過(guò)3000萬(wàn)次的下載,我認(rèn)為它涵蓋了一個(gè)非常具體但又很常見(jiàn)的用例。所以,如果這是你的時(shí)間相關(guān)邏輯所需要的全部,考慮檢查一下。
          js-joda
          另一個(gè)通用時(shí)間管理庫(kù),旨在取代MomentJS和其他從上述名單。它試圖通過(guò)避免對(duì)Date對(duì)象技術(shù)使用相同的包裝來(lái)區(qū)別于MomentJS等其他技術(shù),相反,它從頭實(shí)現(xiàn)了整個(gè)邏輯。
          這樣更好嗎?這個(gè)問(wèn)題還沒(méi)有定論,它可能會(huì)給維護(hù)人員更多的空間來(lái)處理基本概念,并以日期對(duì)象無(wú)法處理的方式扭曲它們。也就是說(shuō),這個(gè)庫(kù)比momentjs(大約40kb)要小一些,而momentjs離dayjs的2kb很小。
          但是,它確實(shí)提供了不變性(沖擊)和特定于域的類(lèi),從而幫助開(kāi)發(fā)人員編寫(xiě)更清晰的OOP代碼。
          js-joda的一個(gè)非常有趣的特性是它提供的可擴(kuò)展性。由于不可變對(duì)象實(shí)際上沒(méi)有setter,這個(gè)庫(kù)提供了with方法,它返回一個(gè)帶有新值集的新對(duì)象。如果不設(shè)置一個(gè)值,而是設(shè)置一個(gè)特殊對(duì)象,那么可以擴(kuò)展獲取值的方式。
          讓我告訴你:
          // implement a TemporalAdjuster that returns the next or same even day of monthvar nextOrSameEvenDay = {  adjustInto: function(t) {    return t.dayOfMonth() % 2 === 0 ? t : t.plusDays(1);  }};
          LocalDateTime.parse("2012-12-23T12:00").with(nextOrSameEvenDay); // '2012-12-24T12:00'LocalDate.parse("2012-12-24").with(nextOrSameEvenDay); // '2012-12-24'
          基本上,我們正在解析一個(gè)日期字符串(沒(méi)什么特別的),然后使用自定義對(duì)象(請(qǐng)注意特殊的into方法),我們正在添加一個(gè)非常隨機(jī)的行為,但仍然有效。
          如果您正在尋找這種靈活性,我個(gè)人會(huì)推薦該庫(kù),否則,上面已經(jīng)介紹了一些更好的方法。
          Spacetime
          我不能漏掉一個(gè)叫做時(shí)空的時(shí)間庫(kù),這一個(gè)有一個(gè)非常有趣的重點(diǎn):時(shí)區(qū)。
          是的,它提供了一個(gè)類(lèi)似于momentjs的API,還提供了不可變的對(duì)象(哎呀!),但是這個(gè)庫(kù)的主要目的是幫助您輕松地處理時(shí)區(qū)。請(qǐng)記住,在處理任何類(lèi)型的國(guó)際化開(kāi)發(fā)時(shí),時(shí)區(qū)往往是主要問(wèn)題之一,所以這看起來(lái)很有前途。
          讓我給你看一些代碼:
          const spacetime = require('spacetime')
          let d = spacetime('March 1 2012', 'America/New_York')//set the timed = d.time('4:20pm')console.log(d.time())
          d = d.goto('America/Los_Angeles')console.log(d.time())//'1:20pm'
          那非常容易,不是嗎?不過(guò),有關(guān)時(shí)空的說(shuō)明是,它不像Luxon那樣依賴(lài)Intl API,因此該庫(kù)本身并不是真正的輕量級(jí)設(shè)備,大約40Kb。話雖如此,時(shí)區(qū)仍然遵循IANA命名約定,這對(duì)于標(biāo)準(zhǔn)化代碼非常有用。
          關(guān)于我們最后一個(gè)圖書(shū)館的另一件很酷的事情是,它可以在適用的情況下遵守夏令時(shí),所以會(huì)發(fā)生以下情況:
          d = d.goto('Eastern Time') // "America/New_York"d = d.goto('PST') // automatically becomes 'PDT' in the summer
          還有其他的方法,如賽季返回當(dāng)前季節(jié)為特定日期(夏季/冬季/返回春季/秋季)以及hasDST inDST它返回一個(gè)時(shí)區(qū)是否使用日光節(jié)約時(shí)間和如果它活躍在特定日期/時(shí)間配置。
          最后,擴(kuò)展時(shí)空非常簡(jiǎn)單,這有助于添加額外的功能,如:
          spacetime.extend({  isHappyHour: function() {    return this.hour() === 16  }})d = d.time('4:15pm')console.log(d.isHappyHour())//true
          結(jié)論
          這是處理日期和時(shí)間的7種最常見(jiàn)的JavaScript庫(kù)。鑒于在線上已有的現(xiàn)有信息和使用情況數(shù)據(jù),如果您必須處理非常復(fù)雜的與日期時(shí)間相關(guān)的功能。
          那么我的建議是使用MomentJS(因?yàn)樗墙?jīng)過(guò)時(shí)間驗(yàn)證的經(jīng)典庫(kù)),或者只是嘗試全新的和 更快的模型:DayJS,相同的API,更好的對(duì)象管理和更小的占地面積。
          另一方面,如果您有非常特定的需求,請(qǐng)考慮使用ms或Spacetime。
          本文完~
          瀏覽 76
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  玖玖国产在线 | 国产精品久久免费视频 | 成人97| 香蕉视频毛片看看 | 欧美日皮视频 |