now.js 0.1.0 發佈了

now.js是什麼

now.js是一個javascript的時間操做小工具,相似date-fnsmomentjavascript

長啥樣

簡單的把示例放這,更多用法請到github去發現。java

import Now from 'now.js'; // for node(browser do not need this)

now = new Now()

now.format() // "2017-11-20T22:23:00+08:00"
now.format('YYYY-MM-DD HH:mm:ss.SSS') // "2017-11-20 22:23:00.285"
now.format("dddd, MMMM Do YYYY, h:mm:ss a") // "Monday, November 20th 2017, 10:23:00 pm"

now.locale('zh-cn') // support 118 languages
now.format("dddd, MMMM Do YYYY, h:mm:ss a") // "星期一, 十一月 20日 2017, 10:23:00 晚上"
now.elapse() // "10 天前"
// same as
now.timeAgo() // "10 天前"

// monday
now.monday() // "2017-11-20 00:00:00"

// isMonday
now.isMonday() // true

// isBefore
now.isBefore(new Date(2020, 10, 11)) // true

// isLeapYear
now.isLeapYear() // false
now.isLeapYear(2008) // true

// between
now.between(new Date(2008, 10, 10), new Date(2018, 10, 10)) // true

// UTC
now.UTC().format() // "2017-11-20T22:23:00+00:00"

now.beginningOfMinute()   // "2017-11-20 22:23:00"
now.beginningOfHour()     // "2017-11-20 22:00:00"
now.beginningOfDay()      // "2017-11-20 00:00:00"
now.beginningOfWeek()     // "2017-11-19 00:00:00"
now.firstDayMonday = true // Set Monday as first day, default is Sunday
now.beginningOfWeek()     // "2017-11-20 00:00:00"
now.beginningOfMonth()    // "2017-11-01 00:00:00"
now.beginningOfQuarter()  // "2017-10-01 00:00:00"
now.beginningOfYear()     // "2017-01-01 00:00:00"

now.endOfMinute()         // "2017-11-20 22:23:59.999"
now.endOfHour()           // "2017-11-20 22:59:59.999"
now.endOfDay()            // "2017-11-20 23:59:59.999"
now.endOfWeek()           // "2017-11-25 23:59:59.999"
now.firstDayMonday = true // Set Monday as first day, default is Sunday
now.endOfWeek()           // "2017-11-26 23:59:59.999"
now.endOfMonth()          // "2017-11-30 23:59:59.999"
now.endOfQuarter()        // "2017-12-31 23:59:59.999"
now.endOfYear()           // "2017-12-31 23:59:59.999"

All the above functions return String type. You can pass 'self' to return Now instance:

var beginningOfMinute = now.beginningOfMinute('self') // return Now instance
beginningOfMinute.format('ddd, Ah') // "Mon, PM10"
beginningOfMinute.format('LLLL') // "Monday, November 20, 2017 10:23 PM"
beginningOfMinute.isMonday() // true

爲何要寫這個庫

由於學習underscore源碼的過程當中,感受無聊。想寫個庫調劑一下,當作學習的機會。

我是照着underscore源碼一個個commit敲的.代碼放在這裏,剛看了一眼,有668次commit,兩個月,敲到了1.4.3版本,可能還沒到一半。

敲久了有點無聊。想動手寫一個庫做爲調劑。碰巧以前作防健忘短信提醒的時候是用go寫的後臺,用了gorm,在做者jinzhu的github主頁上發現了now,是一個go的時間幫助庫,以爲頗有意思。clone之,學之。

偷了now的思想。造一個javascript版的就顯得很容易。很快我就寫完了除了Parse MustParse 以外的全部方法。跟原庫對比一下。以爲now.js就是個玩具。這不怪我,javascript對時間處理的支持遠不如go。好比go原生支持format、字符串解析成時間以及Duration等等。

想着加上format。該怎麼去寫?立馬就想到的方法是平時常常寫的根據不一樣條件作字符串拼接。確實是個方法。但得多少switch case才能涵蓋全部狀況,想一想均可怕。顯然這是最蠢也是工做量最大的方法。

不會,那就借鑑別人的。github上發現了date-fns和moment,支持i18n國際化。node

date-fns:git

import { formatRelative } from 'date-fns'
import { es, ru } from 'date-fns/esm/locale'

formatRelative(subDays(new Date(), 3), new Date(), { locale: es })
//=> "el viernes pasado a las 19:26"

formatRelative(subDays(new Date(), 3), new Date(), { locale: ru })
//=> "в прошлую пятницу в 19:26"

moment:github

moment.locale('fr');
moment(1316116057189).fromNow(); // il y a une heure
moment.locale('en');
moment(1316116057189).fromNow(); // an hour ago

個人審美告訴我應該選擇moment,調用一次locale(),這以後的format都是基於該locale的。固然它也還支持每次單獨指定locale的:網絡

moment.duration(1, "minutes").locale("en").humanize(); // a minute
moment.duration(1, "minutes").locale("fr").humanize(); // une minute
moment.duration(1, "minutes").locale("es").humanize(); // un minuto

進一步學習發現moment的format和i18n國際化高度耦合。要用它的i18n意味着基本上也得用它的format。固然i18n也不是核心的moment庫做者寫的,他們也精通不了那麼多國家的語言,那都是github上許許多多人貢獻的。開源就有這好處。看下LICENCE是MIT的,代碼可用,抄。

now.js也是MIT協議的,負罪感少了點(其實MIT協議是至關寬鬆的,就算你拿它代碼去商業化也是沒有問題的)。何況我寫庫的主要目的是爲了學習。

開幹!雖然說是抄,畢竟代碼要整合到個人庫,直接複製粘貼是不行的。全部的代碼細節未必都須要全知道,但看懂總體運行的邏輯是必須的,下點功夫,整合成功,開源。工具

思惟腦圖

moment:

學習

固然,moment的東西不止上圖這些,我只取了一部分來畫。


now.js:

測試

now.js的Duration和moment的不同,如今還不支持單獨使用,只是給內部方法elapse使用,之後可能會支持單獨使用。this

對比

  1. moment是大而全,now.js是剛夠用。
  2. moment的parse至關強大,now.js就暫時不支持了,只支持和new Date(args)相同的args參數類型。不過format應該都基本上和moment的同樣,不過測試用例如今尚未寫太全,若是誰用了而且發現bug,能夠到github去提issues。不勝感激。
  3. moment是頁面一加載的時候會把全部的i18n都初始化了,這點我我的認爲很差,加載時間長,網絡狀況很差的時候,差很少須要10秒我才能在devtool上調試(固然這也包括官網加載的其餘不少東西)。now.js只加載默認的,須要的時候按需加載。
  4. moment作什麼操做前都要檢測一下date是否合法的(isvalid)。now.js在parse的時候若是不合法就直接拋出錯誤,以避免後續沒玩沒了的檢測。固然這可能損失了用戶友好性,可是對減小代碼量是頗有幫助的。

結語

這個庫不是我一我的寫的,是許多開源工做者共同完成的。感謝moment的全部開源貢獻者,我從中學習了不少東西。後續還會繼續研究moment的代碼細節,偷偷它的思想。


寫代碼什麼最重要?思想最重要!

相關文章
相關標籤/搜索