资讯专栏INFORMATION COLUMN

now.js 0.1.0 发布了

philadelphia / 3410人阅读

摘要:显然这是最蠢也是工作量最大的方法。上发现了和,支持国际化。况且我写库的主要目的是为了学习。在的时候如果不合法就直接抛出错误,以免后续没玩没了的检测。当然这可能损失了用户友好性,但是对减少代码量是很有帮助的。

now.js是什么

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

长啥样

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

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("ffffdd, MMMM Do YYYY, h:mm:ss a") // "Monday, November 20th 2017, 10:23:00 pm"

now.locale("zh-cn") // support 118 languages
now.format("ffffdd, 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("ffffd, 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国际化。

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:

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


now.js:

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

对比

moment是大而全,now.js是刚够用。

moment的parse相当强大,now.js就暂时不支持了,只支持和new Date(args)相同的args参数类型。不过format应该都基本上和moment的一样,不过测试用例现在还没有写太全,如果谁用了并且发现bug,可以到github去提issues。不胜感激。

moment是页面一加载的时候会把所有的i18n都初始化了,这点我个人认为不好,加载时间长,网络情况不好的时候,差不多需要10秒我才能在devtool上调试(当然这也包括官网加载的其他很多东西)。now.js只加载默认的,需要的时候按需加载。

moment做什么操作前都要检测一下date是否合法的(isvalid)。now.js在parse的时候如果不合法就直接抛出错误,以免后续没玩没了的检测。当然这可能损失了用户友好性,但是对减少代码量是很有帮助的。

结语

这个库不是我一个人写的,是许多开源工作者共同完成的。感谢moment的所有开源贡献者,我从中学习了很多东西。后续还会继续研究moment的代码细节,偷偷它的思想。


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

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/90178.html

相关文章

  • now.js 迷你版发布

    摘要:迷你版迷你版即版。版没加新功能,只增加内容和修正上的一些错误。这个版本国际化默认只支持英文和中文。如果想支持全部种语言,需要引入或者压缩版。版本大小比较月月月月可以看出,比小,降低。完全可以放心在生产环境中使用而不担心加载速度问题。 迷你版 迷你版即0.3.0版。0.2.0版没加新功能,只增加eadme内容和修正package.json上的一些错误。0.3.0同样没加新功能,但是却是非...

    Caizhenhao 评论0 收藏0
  • iKcamp|基于Koa2搭建Node.js实战(含视频)☞ 记录日志

    沪江CCtalk视频地址:https://www.cctalk.com/v/15114923883523 showImg(https://segmentfault.com/img/remote/1460000012932474?w=1606&h=968); log 日志中间件 最困难的事情就是认识自己。 在一个真实的项目中,开发只是整个投入的一小部分,版本迭代和后期维护占了极其重要的部分。项目上线...

    stefan 评论0 收藏0
  • 让工作与音乐(Vue)相伴

    摘要:前言最近在自学打算自己仿一个项目来实战一下,由于本人很喜欢听歌,所以就选择了网易云音乐,在这与大家分享一下自己所遇到的问题,其中也有些不足之处也希望大家提一些宝贵的意见,互相学习,一起进步。 showImg(https://segmentfault.com/img/remote/1460000015805758); 前言 最近在自学vue,打算自己仿一个项目来实战一下,由于本人很喜欢听...

    jemygraw 评论0 收藏0
  • JavaScript EventEmitter

    摘要:事件删除可有可无。创建了一个类,然后在构造函数里初始化一个类的属性,这个属性不需要要继承任何东西,所以用了。但这不是必要的,因为实例化一个都会调用构造函数,皆为初始状态,应该是不可能已经定义了的,可去掉。成功执行结束后返回。 GitHub地址:JavaScript EventEmitter博客地址:JavaScript EventEmitter 水平有限,欢迎批评指正 2个多月前把 ...

    lovXin 评论0 收藏0
  • 如何设计npm包的开发和发布流程

    摘要:所以此版本号在这里的作用并不是用来区分版本的,小版本号才是真正用来做版本区分的,那么在引用这个就要这么来控制版本号,举个栗子锁定大版本号和小版本号,不管我们开发过程中提交了多少次,我们引用都是最新的。 最近在把公司内部用的一个库发布到内网的npm私服上,仅仅是发布的话是比较简单的,但这个库是由多个人一起维护的,而且npm私服只有一套,所以生产环境和开发环境,用的是同一个,那么,我们的需...

    qieangel2013 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<