×

学习date-fns:轻量级JavaScript日期库

作者:Terry2020.09.18来源:Web前端之家浏览:20477评论:0
关键词:jsdate-fns

918,特殊的日子,希望一切安好。深圳最近奇怪的天气让人折腾,一会暴晒,一会下暴雨。请假在家休息,本来想睡个懒觉,但是一大早被电钻声吵醒,好吧,起床写点东西吧。今天跟大家分享下一款轻量级JavaScript日期库:date-fns。

500.jpg

在JavaScript中使用日期是一种痛苦。本地日期方法通常很冗长,有时也不一致 —这也使它们易于出错。但是,好消息就在眼前。有几个库可以消除过时的痛苦。这些库是JavaScript日期,而jQuery是本机DOM API。

让我举一个例子。这是对堆栈溢出问题的公认答案,该问题询问如何获取每月的最后一天:

var t = new Date();alert( new Date(t.getFullYear(), 
    t.getMonth() + 1, 0, 23, 59, 59) );

当然可以,但是后面的数字getMonth代表什么还不是很明显。现在,与更具可读性的对比一下:

const today = new Date();
console.log( lastDayOfMonth(today) );

lastDayOfMonth方法是date-fns提供的,date-fns是一个自称的综合工具集,用于在浏览器和Node.js中操纵JavaScript日期。

在本文中,我将向您展示如何启动和运行date-fns。阅读后,您将可以将其放入项目中,并利用其许多辅助方法轻松地操作日期。这将使代码t.getMonth() + 1, 0, 23, 59, 59成为过去。

那么,为什么不仅仅使用Moment.js?

Moment.js是一个出色的库,用于在JavaScript中处理日期-它具有许多出色的功能,并提供了大量有用的实用程序。但是,并非没有批评者。

许多人都引用Moment对象是可变的(例如add,诸如或subtract更改原始Moment对象的操作)的事实,这使开发人员感到困惑,并且导致了bug。

它的大尺寸也受到了抨击。Moment在现代的“摇树”算法中不能很好地发挥作用,如果您需要国际化或时区支持,则可以使用相当大的JavaScript包快速找到自己。

到目前为止,Chrome的开发工具突显了以下事实:使用Moment可能会导致性能下降。

所有这些都导致Moment维护人员将项目置于维护模式,并阻止Moment在以后的新项目中使用。

我们认识到许多现有项目可能会继续使用Moment,但是我们想阻止Moment在以后的新项目中使用。相反,我们想推荐当今在现代应用中使用的绝佳选择。

这使date-fns成为Moment.js的最佳替代产品之一。

安装

从库的第二版开始,安装date-fns的唯一方法是作为npm软件包。

npm install date-fns

或通过纱线:

yarn add date-fns

您可以将date-fns与CommonJS模块系统以及ES模块一起使用:

// CommonJSconst 
{ lastDayOfMonth } = require('date-fns');

要么:

// ES Modules
import { lastDayOfMonth } from 'date-fns';

不幸的是,当前没有可用的date-fns CDN版本。在本GitHub问题中讨论了将其删除和恢复的可能性。但是,这并不是说您不能在浏览器中使用它,只是需要在工作流程中引入捆绑步骤。

让我们看看现在如何做。

如何捆绑date-fns在浏览器中使用

我假设您在计算机上安装了Node和npm。如果没有,请查阅我们有关安装Node的教程。

接下来,安装Parcel。这是一个捆绑程序(类似于Webpack),它将允许您捆绑JavaScript并将其提供给浏览器。

npm install -g parcel-bundler

接下来,使用package.json文件创建一个新项目。

mkdir date-fns
cd date-fns
npm init -y

如上所述安装date-fns库:

npm install date-fns

现在创建两个文件,index.htmlindex.js

<!DOCTYPE html><html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>date-fns</title>
  </head>
  <body>
    <script src="index.js"></script>
  </body></html>
import { lastDayOfMonth } from 'date-fns';

const today = new Date();
console.log(lastDayOfMonth(today));

启动包裹的内置开发服务器:

parcel index.html

并导航到http:// localhost:1234。您不会在页面上看到任何显示,但是如果您打开浏览器的控制台。您应该已经记录了当月的最后一天。

关于部署,您可以运行:

parcel build index.js --experimental-scope-hoisting

使Parcel在dist文件夹中输出缩小且摇晃的捆绑包。

Date-fns基本用法

现在我们已经启动并运行,让我们看看date-fns可以做什么。

处理日期时最常见的任务之一是能够很好地格式化日期。我们可以使用date-fns 格式函数来做到这一点。

更改上面示例页面中的HTML,使其如下所示:

<body>
  <h1>The date today is <span></span></h1>
  <script src="index.js"></script></body>

index.js我们要导入的format函数中,我们可以传递今天的日期和格式字符串。然后,我们想将结果输出到页面。


import { format } from 'date-fns';

const today = new Date();
const formattedDate = format(today, 'dd.MM.yyyy');

document.querySelector('h1 > span').textContent = formattedDate;

当然,我们不限于一种dd.MM.yyyy格式,让我们尝试不同的方法:


const formattedDate = format(today, 'PPPP');

这将格式化像这样的输出:Wednesday, September 16th, 2020。您可以在docs中找到格式设置选项的完整列表。

变更地区

如果您拥有使用多种语言的网站,那么date-fns可使国际化日期和时间变得简单。让我们迎接德国客人:

<h1>Heute ist <span></span></h1>

在JavaScript文件中,我们可以导入德语语言环境并将其传递给format函数:


import { format } from 'date-fns';
import { de } from 'date-fns/locale';

const today = new Date();
const formattedDate = format(today, 'PPPP', { locale: de });

document.querySelector('h1 > span').textContent = formattedDate;

这将输出的东西沿着线:Heute ist Mittwoch, 16. September 2020

要求并以语言环境作为选项似乎很复杂,但与Moment.js缺省情况下使用所有语言环境使构建膨胀的方式不同,date-fns强制开发人员在需要时手动要求语言环境。

您可以通过查看node_modules/date-fns/locale项目中的文件夹来查看可用语言环境的列表。

不变性,纯正和简单

date-fns的卖点之一是其功能纯净,易于解释。这样可以使代码易于理解,并在出现问题时更易于调试。

让我使用Moment.js作为反示例进行演示。如前所述,Moment中的日期是可变的,这可能导致意外行为。

const moment = require('moment');
const now = new Date();
const mNow = moment(now);

mNow.add('day', 3);
console.log(mNow.toDate());
mNow.add(3, 'day');
console.log(mNow.toDate());

// 2020-09-19T10:08:36.999Z
// 2020-09-22T10:08:36.999Z

这里有几件事要注意。Moment的add函数对其接受其参数的顺序并不挑剔(尽管第一个方法现在将引发弃用警告)。但更令人困惑的是,如果add连续调用多次,将不会得到相同的结果,因为Moment对象是可变的:

mNow.add(3, 'day'); // add 3 days
mNow.add(3, 'day'); // adds 3 **more** days

现在,将其与date-fns进行比较,date-fns会将参数保持在一个顺序中,并且始终返回相同的结果,并Date为每次调用返回一个新对象。

import { isValid, parse } from 'date-fns';

const validDate = parse('29.02.2020', 'dd.MM.yyyy', new Date());
const invalidDate = parse('30.02.2020', 'dd.MM.yyyy', new Date());

console.log(validDate);
// Sat Feb 29 2020 00:00:00 GMT+0100 (Central European Standard Time)

console.log(invalidDate);
// Invalid Date

console.log(isValid(validDate));
// true

console.log(isValid(invalidDate));
// false

可以轻松地将其提取到一个小助手方法中,该方法对于例如验证表单中的用户输入很有用。

时区

date-fns的一个缺点是它目前没有像Moment.js那样的任何时区帮助程序功能,而是返回了代码在其上运行的本地时区。

这个堆栈溢出的答案提供了一些本机Date对象如何实际不存储“实时区域”数据的背景知识。在该线程中,您会注意到他们提到了一种在JavaScript中原生设置时区的方法。这不是一个全面的解决方案,但是它适用于仅需要输出转换(从UTC或本地时间到特定时区)的许多情况。

new Date().toLocaleString("en-US", {timeZone: "America/New_York"});

时区实际上是一个要解决的复杂问题,这就是为什么MomentJS有一个单独的库。有计划在date-fns中添加时区支持,但是在撰写本文时,这仍在进行中。

但是,npm上有一个可用的软件包(基于对date-fns的未合并提取请求),该软件包使用Intl API添加了对date-fns v2.0.0的时区支持。每周下载14万次,这似乎很受欢迎,但是在撰写本文时,它已经有几个月没有更新了。

就是说,这是您可能会使用的方式:

npm i date-fns-tz
import { format, utcToZonedTime } from 'date-fns-tz';

const today = new Date(); // Wed Sep 16 2020 13:25:16
const timeZone = 'Australia/Brisbane'; // Let's see what time it is Down Under
const timeInBrisbane = utcToZonedTime(today, timeZone);

console.log(`
  Time in Munich: ${format(today, 'yyyy-MM-dd HH:mm:ss')}
  Time in Brisbane: ${format(timeInBrisbane, 'yyyy-MM-dd HH:mm:ss')}
`);

// Time in Munich: 2020-09-16 13:26:48
// Time in Brisbane: 2020-09-16 21:26:48

结论

Date-fns是一个很棒的小程序库,它为您提供了很多帮助程序方法,可用于在JavaScript中使用日期和时间。目前正在积极开发中,并且Moment.js已进入维护模式,这使其成为Moment.js的理想替代品。

您的支持是我们创作的动力!
温馨提示:本文作者系Terry ,经Web前端之家编辑修改或补充,转载请注明出处和本文链接:
https://jiangweishan.com/article/date-fns12312412421.html

网友评论文明上网理性发言 已有0人参与

发表评论: