Luxon-一个新的库,用于处理来自Moment.js团队的日期



似乎,为什么要有一个著名的Moment库,为什么我们需要另一个库来处理日期和时间? 更有趣的是,替代方案是由Moment团队本身提出的。

Luxon库被声明为功能强大,现代且方便的工具,可用于在JavaScript中处理日期和时间。 该库由Isaac Cambron创建,他自2013年以来就是Moment开发团队的成员。

作者有许多开发Moment的想法,这是他在现有代码框架内无法做到的。 这是我要实现的要点:

  • 尝试一些有关如何使API更具逻辑性的想法(但是这些想法与Moment采用的方法不兼容),
  • 在没有附加扩展的情况下,对时区实施“开箱即用”的工作,
  • 考虑到Intl API的出现,完全重新考虑了国际化的工作,
  • 切换到一套现代的工具和方法以形成JS代码。

因此,他决定从头开始编写所有内容,大约花费了两年时间。
结果是Moment的一种现代化版本。
最终的版本对整个Moment开发团队来说都很有趣,因此决定在团队的主持下推广新库。

卢森堡原则


  1. 呼叫链,如片刻。
  2. 所有类型都是不可变的。
  3. 更清晰明了的API:针对不同的对象-具有明确定义的参数的不同方法。
  4. 国际化的Intl API(如果浏览器不支持Intl API,则回滚到英文版本)。
  5. 用于时区的Intl API。
  6. 对工期的更全面支持。
  7. 本机间隔支持。
  8. 内联代码文档。

这些原则导致以下改进:

  • Luxon代码更容易理解和调试。
  • 使用内置的浏览器功能进行国际化可以改善库的行为,并且使调试更加容易。
  • 时区支持比其他任何JS库都实现得更好。
  • Luxon提供了一个简单而功能强大的工具来进行持续时间处理。
  • 该库具有良好的文档。

但是,卢森堡有其缺点:

  • 强调使用浏览器的内置功能导致在支持较旧的浏览器方面遇到困难。
  • 库中未实现某些浏览器尚不支持的国际化功能(您应该希望此支持出现在浏览器中)。
  • 不同浏览器中Intl API的实现可能会有所不同,Luxon的行为也将有所不同。

安装方式


Luxon为所有现代JavaScript平台提供模块。

该文档包含应用程序限制的受支持浏览器的完整列表 。 对于不具有Intl支持或具有有限Intl支持的浏览器,建议使用多文件(特别是,这适用于IE 10或11)。

使用Node.js(6+)时,如果需要使用语言环境,则需要另外安装full-icu软件包并设置环境变量以启用该软件包。

npm的标准安装方法:
npm install-保存luxon

Luxon同时支持TypeScript和Flow,还有一个ES6格式的模块。

快速复习


Luxon库包含五个主要类:

DateTime-带有时区和显示设置的日期和时间,以及相关方法。
持续时间 -一段时间(持续时间),例如“ 2个月”或“ 1天3小时”。
信息 -获取时间和日期常规数据的静态方法。
间隔 -时间间隔及其使用方法。
设置是静态方法,用于定义Luxon的一般行为。

import {DateTime, Duration, Info, Interval, Settings} from 'luxon'; 

您的第一个约会时间


Luxon中最重要的类是DateTime。 DateTime代表日期+时间以及时区和语言环境。 您可以通过以下方法在当地时区设置2017年5月15日08:30:

 var dt = DateTime.local(2017, 5, 15, 8, 30); 

这是确定当前时间的电话:

 var now = DateTime.local(); 

从对象创建


 DateTime.fromObject({ month:12, day: 22, hour: 12, minutes: 20, zone: 'Europe/Kaliningrad' }); //=> 2018-12-22T12:20:00.000+02:00 

从ISO 8601格式的字符串创建


 DateTime.fromISO("2017-05-15"); //=> May 15, 2017 at 0:00 DateTime.fromISO("2017-05-15T08:30:00"); //=> May 15, 2017 at 8:30 

转换为字符串时,Luxon还返回ISO 8601格式的字符串:

 DateTime.local().toString(); //=> "2018-12-18T20:58:29.995+03:00" 

获取单个组件:


 var dt = DateTime.local(); dt.year; //=> 2018 dt.month; //=> 12 dt.day; //=> 18 dt.second; //=> 27 dt.weekday; //=> 2 dt.zoneName; //=> "Europe/Moscow" dt.offset; //=> 180 dt.daysInMonth; //=> 31 

格式化输出


Luxon有许多将DateTime转换为字符串的方法,其中两种最重要的是LocaleString和toISO,第一种转换为考虑到浏览器漆的格式,第二种准备文本以进行编程处理(例如,用于传输到服务器):

 dt.toLocaleString(); //=> "18.12.2018" dt.toLocaleString(DateTime.DATETIME_MED); //=> "18 . 2018 ., 21:46" dt.toISO(); //=> "2018-12-18T21:46:55.013+03:00" 

Luxon有两打现成的“预设”用于格式化输出(例如DATETIME_MED和TIME_WITH_LONG_OFFSET)。

您还可以基于令牌创建自己的格式化选项:

 dt.setLocale('ru').toFormat('d MMMM tt - ZZZZZ'); //=> "18  21:46:55 - ,  " 

日期时间转换


重要说明:Luxon对象是不可变的,即 应用于它们的任何修改方法都将返回修改后的副本,而不更改原始对象。 因此,本文中的所有术语(如Luxon文档中的术语),例如“更改”,“安装”,“重新定义”都应理解为“使用其他属性创建新实例”。

数学转换


 var dt = DateTime.local(2018, 12, 18, 20, 30); //=> "18.12.2018, 20:30" dt.plus({hours: 3, minutes: 2}); //=> "18.12.2018, 23:32" dt.minus({days: 7}); //=> "11.12.2018, 20:30" dt.startOf('day'); //=> "18.12.2018, 0:00" dt.endOf('hour'); //=> "18.12.2018, 20:00" 

覆盖单个参数


 var dt = DateTime.local(); dt.set({hour: 3}).hour //=> 3 

国际转换


Luxon支持几种不同的Intl转换,其中最重要的一种是针对不同区域设置的格式:

 var dt = DateTime.local(); var f = {month: 'long', day: 'numeric'}; dt.setLocale('fr').toLocaleString(f); //=> "18 décembre" dt.setLocale('en-GB').toLocaleString(f); //=> "18 December" dt.setLocale('en-US').toLocaleString(f); //=> "December 18" 

Info类可以返回给定语言环境中月份和星期几的列表:

 Info.months('long', {locale: 'it'}); //=> ["gennaio", "febbraio", "marzo", ...] Info.weekdays ('short', {locale: 'de'}); //=> ["Mo", "Di", "Mi", ...] 

时区


Luxon支持时区。 如果创建的DateTime没有显式指定时区,则默认情况下将选择本地时区。 如果您为现有的DateTime更改时区,则将考虑时区之间的时差重新计算时间和日期。

 var dt = DateTime.local(2018, 12, 18, 20, 00); //=> 2018-12-18T20:00:00.000+03:00 dt.zone.name; //=> "Europe/Moscow" dt.setZone('Asia/Vladivostok'); //=> 2018-12-19T03:00:00.000+10:00 

Luxon还支持使用UTC格式处理日期和时间:

 DateTime.utc(2018, 5, 15); //=> 2018-05-15T00:00:00.000Z DateTime.utc(); //=> 2018-12-18T17:58:29.995Z DateTime.local().toUTC(); //=> 2018-12-18T17:58:29.995Z DateTime.utc().toLocal(); //=> 2018-12-18T20:58:29.995+03:00 

持续时间


Duration类提供了以例如“ 2小时7分钟”的持续时间工作的能力。 您可以这样创建一个持续时间:

 var dur = Duration.fromObject({hours: 2, minutes: 7}); 

持续时间可以相加或相减。 持续时间可能具有负值。

 dur.minus(dur).minus(dur); //=> {hours: -2, minutes: -7} 

同样,可以从DateTime中添加或减去持续时间。

 DateTime.local().plus(dur); 

持续时间具有吸气剂(类似于DateTime吸气剂):

 dur.hours; //=> 2 dur.minutes; //=> 7 dur.seconds; //=> 0 dur.zone; //=> undefined 

持续时间还有其他有用的方法:

 dur.as('seconds'); //=> 7620 dur.toObject(); //=> { hours: 2, minutes: 7 } dur.toISO(); //=> 'PT2H7M' 

间隔


间隔定义为两个时间点之间的时间间隔; Interval类用于处理它们。 间隔中包括开始时间,但不包括结束时间:因此,转换为字符串时,开始处用方括号标记,结束处用圆括号标记。

 var today = DateTime.local(2018, 12, 18); var later = DateTime.local(2020, 10, 12); var interval = Interval.fromDateTimes(today, later); interval.toString(); //=> "[2018-12-18T00:00:00.000+03:00 – 2020-10-12T00:00:00.000+03:00)" interval.toISO(); //=> "2018-12-18T00:00:00.000+03:00/2020-10-12T00:00:00.000+03:00" interval.length(); //=> 57369600000 interval.length('years', true); //=> 1.8169398907103824 interval.contains(DateTime.local(2019)); //=> true 

间隔可以相互比较,也可以相互组合:

 var nextYear = Interval.after(DateTime.local(), {year: 1}); var prevYear = Interval.before(DateTime.local(), {year: 1}); prevYear.overlaps(nextYear); //false prevYear.abutsStart(nextYear); //true nextYear.union(prevYear).length('years'); //=> 2 

卢克森与时刻


Luxon库“存在”于“ Moment”项目中,但不能完全替代Moment库。 Luxon不能提供Moment的全部功能,例如, 相对日期格式最近才在Chrome浏览器71版中实现,尚未在其他浏览器中使用,并且在Luxon中尚未实现对它的支持(尽管可以预期)。 但是,即使浏览器支持所需的功能,您也必须了解,只有在这些新环境中才能使用该功能。 在较旧的浏览器中,Luxon可以解决问题,而Moment则可以随时随地使用。

此外,Luxon API已经过重新设计,与Moment API完全不同。

注意Moment和Luxon之间的主要区别。

豁免权


Luxon对象是不可变的,但Moment不是。
在下面的示例中,m1和m2是通过add方法修改的同一对象。

 var m1 = moment(); var m2 = m1.add(1, 'hours'); m1 === m2; //=> true 

对于Luxon,plus方法将返回一个新的d2对象,而不更改原始d1。

 var d1 = DateTime.local(); var d2 = d1.plus({ hours: 1 }); d1 === d2; //=> false d1.valueOf() === d2.valueOf(); //=> false 

因此,Luxon不需要Moment用于在不更改原始值的情况下获取副本的特殊副本构造函数或克隆方法。

关键功能差异


  1. Luxon中的月份倒计时从1开始,而不是像Moment(和Date js对象本身)从头开始。
  2. 本地化和时区使用本地Intl API(或polyphile)实现,并且未内置在库中。
  3. Luxon具有内置类型“持续时间”和“间隔”。
  4. Luxon尚不支持相对日期格式。
  5. Luxon还没有人性化方法以“人性化”风格(例如“几秒钟”)来表示持续时间。

API样式差异


  • 在Luxon API方法中,可选参数通常位于最后。
  • 与Moment不同,Luxon具有许多用于创建对象的单独方法(例如fromISO),Moment为此具有一个功能,并且对象的类型由参数设置。
  • 卢森堡有非常严格的解析器,而Moment有更自由的解析器,即 如果输入字符串的格式与标准格式不同,则Luxon将立即给出错误,Moment将尝试更正格式中的某些错误。
  • Luxon使用getter(dt.year,dt.isValid)来获取内部字段的值,而不是像Moment(m.year(),m.isValid())之类的方法。
  • Luxon允许一种方法立即设置所有必需的参数dt.set({year:2016,month:4}),在Moment中,它们一次只能设置一个-调用链m.year(2016).month(4)。
  • Luxon中的Duration是一个单独的顶级Duration类。

否则,Luxon从Moment借来了很多想法,文档甚至包含Moment和Luxon方法的等效表。

库文件大小


卢森堡(v。1.8.2)
luxon.min.js-61 KB

时刻(v。2.23.0)
moment.min.js-51 KB
moment.min.js +语言环境/ ru.js-59 KB
moment-with-locales.min.js-323 KB

如您所见,在没有Moment语言环境的情况下,其大小比Luxon小10 KB,但是在添加了多个语言环境后,大小变得大致相等。

如果在所有地区都需要立即提供支持,那么Luxon将会带来巨大收益。

总结


该库已完全可以使用,作者承诺将提供支持。 该库在github上已经有7k颗星,并且它的受欢迎程度还在增长。 不仅作者自己在代码中进行提交,而且至少还有6个开发人员。

我将假定Luxon库是对浏览器中对Intl API支持的出现的回应。 片刻开发人员了解,使用Web上的日期可能会发生重大变化,因此他们正在为这些变化做准备。 但是他们无法准确预测网络的发展以及随之而来的新项目(他们自己称为Moment实验室项目)。 Luxon的想法会移植到Moment 3吗? 大多数用户会在某个时候从Moment转到Luxon吗? 也许卢森堡会更名为Moment? 开发人员自己承认他们现在无法回答这些问题。

Source: https://habr.com/ru/post/zh-CN433850/


All Articles