now.js 0.1.0 发布了

now.js是什么

now.js是一个javascript的时间操作小工具,类似date-fnsmoment

长啥样

简单的把示例放这,更多用法请到github去发现。

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

now = new Now() // "2017-11-20 22:23:00.285"

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版的就显得很容易。很快我就写完了除了ParseMustParse之外的所有方法。跟原库对比一下。觉得now.js就是个玩具。这不怪我,javascript对时间处理的支持远不如go。比如go原生支持format、字符串解析成时间以及Duration等等。

想着加上format。该怎么去写?立马就想到的方法是平时经常写的根据不同条件做字符串拼接。确实是个方法。但得多少switch case才能涵盖所有情况,想想都可怕。显然这是最蠢也是工作量最大的方法。

不会,那就借鉴别人的。github上发现了date-fns和moment,支持i18n国际化。

date-fns:

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:

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:

image

当然,moment的东西不止上图这些,我只取了一部分来画。

now.js:

image

now.js的Duration和moment的不一样,现在还不支持单独使用,只是给内部方法elapse使用,以后可能会支持单独使用。

对比

  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的代码细节,偷偷它的思想。


写代码什么最重要?思想最重要!

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,001评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,210评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,874评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,001评论 1 291
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,022评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,005评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,929评论 3 416
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,742评论 0 271
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,193评论 1 309
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,427评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,583评论 1 346
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,305评论 5 342
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,911评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,564评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,731评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,581评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,478评论 2 352

推荐阅读更多精彩内容

  • 中文翻译 ng help ng build 构建您的应用程序并将其放入输出路径(dist /默认情况下)。 别名:...
    4ea0af17fd67阅读 2,030评论 0 0
  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 172,050评论 25 707
  • 一束阳光,暖心窝; 一掠清风,伴相随; 一泡温茶,君共饮; 心爽神怡,春光聚; 你若安好,皆向阳。
    钊哥百货阅读 278评论 0 1