整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:

JavaScript还可以处理日期?你只需要这样做

JavaScript还可以处理日期?你只需要这样做

日期相关的问题与JavaScript一样古老。从理论上讲,如果不是因为API的许多弱点,可以使用JavaScript的date对象执行日期计算。幸运的是,有一些有用的库可以为我们节省很多工作。其中之一是date-fns。


一个问题,例如,是与日期对象不同的时区的处理,由于JavaScript使用当前系统时区为基础。这可能会导致困难,尤其是涉及跨多个时区的应用程序时。月份的表示形式是JavaScript中date对象的另一特性。例如,一月的值指定为0。但是,当涉及到日期和年份时,JavaScript会再次遵循预期的标准,因此,5 号用数字5表示。

当您实现一个使用日期值的应用程序时,您经常会发现必须创建,修改和输出它们的问题。使用机载JavaScript工具,可以轻松进行创建和输出。但是,如果日期被修改,例如,如果你想从一个日期减去两天了,这是不再可能。当然,您可以获取日期的时间戳,然后减去相应的毫秒数以达到目标日期。该解决方案不容易阅读和维护,或者特别优雅。由于这个问题,还有更多的问题,过去已经创建了许多库,以使您更轻松地处理JavaScript中的日期值。市场上最广泛的解决方案之一是Moment.js。不过,前一阵子已经成为了一个严重的竞争对手:

date-fns与Moment.js有何不同?

最重要的区别之一是项目名称,因为fns代表功能。日期FNS的功能,它允许您使用日期值的集合。
与此相反,Moment.js具有面向对象的方法。在这里,您创建一个瞬间 -instance和工作与此对象的方法。当然,这会影响包装尺寸。
Moment.js默认包含整个界面。您确实可以优化程序包,但这需要其他步骤。在date-fns中,您仅加载真正需要的功能。
不过,在带有Node.js的后端应用程序中,这无关紧要,因为软件包大小是一个小问题。您可以使用日期FNS就像Moment.js,在前端的浏览器。包装的大小在这里起决定性作用。

date-fns的开发人员不仅确保将项目划分为许多小的且很大程度上独立的功能,而且还确保这些功能是纯功能。例如,您传递一个日期对象和要添加到addHours函数的小时数。结果,您将获得一个新的日期对象,其中指定的小时数晚于您输入的日期。因此,没有副作用,例如直接修改输入。

如何安装日期FNS?

与大多数其他JavaScript库一样,date-fns可作为npm软件包提供,并可通过npm进行安装。在项目中使用命令npm install date-fns进行操作。该软件包将作为依赖项自动添加到您的package.json文件中。同样,您可以将纱线与纱线 添加日期-fns命令一起使用。

如何使用它?

您可以使用日期FNS包与CommonJS的模块系统都和也与ES模块。在下面的示例中,您使用格式函数输出当前日期。清单1显示了如何使用CommonJS模块系统。

清单1:通过CommonJS模块化系统集成date-fns

1个

2

3

4

5

const { format }=require('date-fns');

const date=new Date();

console.log(`Heute ist der: ${format(date, 'DD.MM.YYYY')}`);

Node.js的较新版本还支持关键字的进口和出口,以进口和出口分别模块。此时,您可以导入整个date-fns软件包并访问所需的功能,也可以利用每个功能在单独的文件中可用的事实,因此可以单独导入格式功能。你可以看到这是如何工作清单2所示。

清单2:将date-fns与ES模块一起使用

1个

2

3

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

const date=new Date();

console.log(`Heute ist der: ${format(date, 'DD.MM.YYYY')}`);

格式化日期值

使用格式,您已经学习了格式化日期值的最重要功能。
您可以使用格式字符串来指定要格式化日期的哪一部分以及如何格式化。
您可以在https://date-fns.org/docs/format中找到可以在格式字符串中使用的各个令牌的全面参考。

除此功能外,您还可以访问其他辅助功能,例如distanceInWords函数,该函数以可读形式输出两个日期值之间的差。

日期算术

已经提到的JavaScript中对象日期的漏洞是缺少对日期算术的支持。因此,事不宜迟地执行加法或减法。
date-fns为此提供了许多辅助功能。这些功能通常有一个统一的命名方案:首先,你指定的操作,其次是要与工作单位。
这将导致函数名称,例如addMinutes或subYears。此类别的所有函数都将日期对象作为第一个参数,将数字作为第二个参数表示要添加或减去的单位数。例如,在一个小时的四分之三添加到当前为止,你可以从清单3使用的代码。

清单3:使用date-fns的日期算术

1个

2

3

4

5

const { addMinutes, addHours, format }=require('date-fns');

const date=addMinutes(addHours(new Date(), 1), 45);

console.log(format(date, 'DD.MM.YYYY HH:mm'));

比较

日期FNS的比较功能也非常有帮助,在他们的帮助,你可以决定是否一个谎言日期之前或之后另一个,还是在某个日期在于未来或过去。清单4使用isAfter和isFuture函数作为示例来说明它们的用法。

清单4:wit dat-fns的比较

1个

2

3

4

5

6

const { isAfter, isFuture, addHours }=require('date-fns');

const date1=new Date();

const date2=addHours(new Date(), 5);

console.log(`Date1 is ${isAfter(date1, date2) ? 'after' : 'before'} Date2`);

console.log(`Date2 is ${isFuture(date2) ? 'not' : ''} in the past`);

进一步的操作

该日期FNS包为您提供不仅是简单的操作,如加,但也更复杂的操作,如areRangesOverlapping功能,你可以用它来确定两个时间跨度是否重叠。

随着最小和最大的功能,你可以找到一系列的日期值的最早或最晚日期。

借助compareAsc和compareDsc函数,您还可以对具有日期值的数组进行排序。该函数作为比较函数传递给数组的sort方法。清单5是这样的一个例子。

清单5:对日期值进行排序

1个

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

const { compareAsc }=require('date-fns');


const sortedDates=[

new Date(2001, 1, 1),

new Date(2003, 3, 3),

new Date(2002, 2, 2),

].sort(compareAsc);


console.log(sortedDates);

结论

Moment.js或date-fns之类的许多程序包都提供了,您也可以使用本机JavaScript来实现。但是,在这些情况下,源代码的可读性受到很大影响。除了更正JavaScript 日期对象的特性之外,这是支持使用这些库的最重要的论据之一。

这里显示的日期FNS的可能性仅代表库中的一小部分,并只给你这个库的功能范围的味道。有了众多扩展,并为应用程序的国际化提供了很好的支持,您下次确定一个应用程序的日期库时,至少应将date-fns入围。

最后,开发这么多年我也总结了一套学习Java的资料与面试题,如果你在技术上面想提升自己的话,可以关注我,私信发送领取资料或者在评论区留下自己的联系方式,有时间记得帮我点下转发让跟多的人看到哦。

内容是《Web前端开发之Javascript视频》的课件,请配合大师哥《Javascript》视频课程学习。

Date日期对象:用于处理日期和时间。

基本概念:

GMT:(Greenwich Mean Time)格林尼治标准时(格林威治),这个时间系统的概念在 1884 年确立,由英国伦敦的格林威治皇家天文台(即本初子午线的位置)计算并维护。

UTC:(Universal Time Code 通用时间),也叫格林尼治标准时间,(也称为:协调世界时、世界统一时间、世界标准时间、国际协调时间)。

时区:由于各国家与地区经度不同,地方时也有所不同; 1884年在华盛顿召开的一次国际经度会议,把全球划分为不同的时区,每隔经度15°划分一个时区,其被划分为24个时区,分为东12区和西12区。

夏令时:(Summer time),又称日光节约时、日光节约时间,是一种为节约能源而人为规定地方时间的制度,在这一制度实行期间所采用的统一时间称为“夏令时间”。

计算机元年(纪年):1970年1月1日0时0分0秒作为计算机元年,用于计时的开始。

时间戳:是一个自增的整数,它表示从1970年1月1日零时整的GMT时区开始的那一刻,到现在的毫秒数,时间戳可以精确地表示一个时刻,并且与时区无关。

Date使用的是UTC;是所有时区的基准标准时间,是1970年1月1日凌晨0点0分0秒开始经过的毫秒数保存日期;

在使用这种数据存储格式的条件下,Date()类型保存的日期能够精确到70年1月1日之前或之后的100 000 000天。

Date对象创建

使用Date()构造函数,语法:var now=Date();

var d = new Date();  //以当前日期和时间创建Date对象
var d = new Date(0);  //以距离1970.1.1:00:00:00的毫秒数创建Date对象
var d = new Date(2020,7,18);
console.log(d);

new Date()的参数很多种形式,每种都表示不同的含义;

如果传值为 0,会得到一个表示 1970年1月1日的Date 对象;

或者使用Date()函数,但本质上不一样,输出也不一样,实质上是一个转换函数;

说明:因为要传入是表示该日期的毫秒数(即从UTC时间70年1月1日前夜起到该日期止的毫秒数)。为了简化这一计算过程,ECMAScript提供了两个静态方法:Date.parse()和Date.UTC();

Date.parse()方法接受一个表示日期的字符串参数,返回一个时间戳(毫秒数);

日期字符串应该符合 RFC 2822 和 ISO 8061 这两个标准,ISO 8601扩展格式 YYYY-MM-DDTHH:mm:ss:ssssZ,如:2020-05-25T00:00:00;(yyyy4位年份、MM月份、DD天、HH时、mm分、ss秒、ssss毫秒)

通常见的日期格式:

mm/dd/yyyy 如: 3/21/2009,即月/日/年

yyyy/mm/dd 如: 2009/3/21

mmmm dd,yyyy 如: Apr 21,2009,即英文月名 日,年,即January 12,2010

英文星期几 月 日 年 时:分:秒 时区,如:Tue May 25 2020 00:00:00 GMT-0700

var d = Date.parse("May 25,2020");
Date.parse('2018-07-22')
Date.parse('2018-07')
Date.parse('2018')
Date.parse('07/22/2018')
Date.parse('2018/07/22')
Date.parse('2018/7/22')
Date.parse('July 22, 2018')
Date.parse('July 22, 2018 07:22:13')
Date.parse('2018-07-22 07:22:13')
Date.parse('2018-07-22T07:22:13')

注:如果传入Date.parse()方法的字符串不能表示日期,那么它会返回NaN;

根据parse()返回值创建Date对象;

var d = new Date(Date.parse("May 25, 2020"));

实际上,如果直接将表示日期的字符串传递给Date构造函数,也会在后台调用Date.parse(),两者是等价的,如:

var d = new Date("May 25, 2020");

注:日期对象在不同浏览器实现的并不统一,比如,传入了超出范围的值:

var d = new Date("January 33,2020");

在解析January 33,2020,有些浏览器返回:Invalid Date;IE返回:Sun Feb 02 2020(把超出的时间往后自动推算);

可以在月份或者日期字段添加或省略前导零;

console.log(new Date('2020-6-6'));
console.log(new Date('2020-06-06'));
console.log(new Date('2020-06-06 09:18:15'));
console.log(new Date('2020-06-06T09:18:15'));
console.log(new Date('2020-06'));
console.log(new Date('2020'));
console.log(new Date('06/07/2020'));
console.log(new Date('2020/06/07'));
console.log(new Date('2020/6/7'));
console.log(new Date('2020.6.7'));
console.log(new Date('2020.6.7 15:18:15'));
console.log(new Date('July 18, 2020'));
console.log(new Date('July 18, 2020 09:30:28'));
console.log(new Date('18 July 2020'));
console.log(new Date('18 July, 2020'));
console.log(new Date('18 July 2020 09:30:28'));
console.log(new Date('July 2020'));

其实Date在内部是使用时间戳实现的;

var d = new Date(1591866649132)
console.log(d);

UNIX 时间戳的原因以秒(seconds)为单位。JavaScript 以毫秒(milliseconds)为单位记录时间。

可在使用UNIX 时间戳去实例化Date 对象;

var timestamp = 1591866649;
var d = new Date(timestamp * 1000);
console.log(d);

Date.UTC()方法:

返回表示日期的毫秒数,但它与Date.parse()在构建值时使用不同的信息,即与当前所在的时区相关,生成的日期都相对于计算机的时区;

语法:Date.UTC(year, month[, date[, hrs[, min[, sec[, ms]]]]]);

其参数为日期中的年,月(基于0),日,小时(0到23),分,秒,毫秒,其中年月必选;如果没有提供日,默认为1,如果省略其他参数,则统统默认为0;

至少应该是3个参数,但是大多数 JavaScript 引擎都能解析 2 个或 1 个参数;

var d = Date.UTC(2020);
var d = Date.UTC(2020,6);  // 毫秒数1593561600000
var d=new Date(Date.UTC(2020,6)); 
var d = new Date(Date.UTC(2020,6,6,17,55,55)); // 自动添加时区,返回当地日期和时间
var d=new Date(2020,6,10); //月份从0开始,6即是7月
console.log(d);

如果没有任何关于时区的信息,会将日期视为 UTC ,并自动执行到当前计算机时区的转换;

可以直接把UTC参数传递给Date()构造函数,如:

var d=new Date(2020,6); // Wed Jul 01 2020 00:00:00 GMT+0800 
var d = new Date(2020,6,6,17,55,55); // 即为GMT时间
console.log(d);

时区:

当初始化一个 Date 对象时可以选择时区,可以通过添加 +HOURS 的格式,或者通过一个被圆括号包裹的时区名来描述一个时区:

console.log(new Date());
console.log(new Date('Jun 7,2020 13:51:01 +0700'));
console.log(new Date('Jun 7,2020 13:51:01 (CET)'));   // CET欧洲中部时间

如果你使用时区名的方式但在圆括号中定义了一个错误的时区名,JavaScript 将会静默地将时区设置为默认的 UTC。

如果你使用 +HOURS 的方式但传入的数字格式是错误的,JavaScript 将会抛出一个 “Invalid Date” 的 Error。

继承的方法:

与其他引用类型一样,Date类型也重写了toLocaleString()、toString()和valueOf()方法;但这些方法的返回值与其他类型中的方法不同。

valueOf()方法:返回日期的毫秒数;

toString()方法:通常返回带有时区信息的日期和时间;其中时间一般以军用时间(即小时从0到23);

toLocaleString():会按照与浏览器设置的地区相适应的格式返回日期和时间;即时间格式中会包含AM或PM,但不会包含时区信息;

var d=new Date(2020,6); // Wed Jul 01 2020 00:00:00 GMT+0800 
var d = new Date(2020,6,6,17,55,55); // 即为GMT时间
console.log(d);

注:真实场景中,toString()和toLocaleString()没有什么用,仅在调试代码时使用;

至于valueOf()方法,返回的是毫秒数,因此,可以方便的使用比较操作来比较日期,如:

console.log(new Date());
console.log(new Date('Jun 7,2020 13:51:01 +0700'));
console.log(new Date('Jun 7,2020 13:51:01 (CET)'));   // CET欧洲中部时间

注意日期比较的惯性思维,如2019.1.1早于2020.2.1日,但后者返回的毫秒数大。

Date对象方法:

  • Date():返回当日的日期和时间。
  • getDate():从 Date 对象返回一个月中的某一天 (1 ~ 31)。
  • getDay():从 Date 对象返回一周中的某一天 (0 ~ 6)。
  • getMonth():从 Date 对象返回月份 (0 ~ 11)。
  • getFullYear():从 Date 对象以四位数字返回年份。
  • getYear():请使用 getFullYear() 方法代替。
  • getHours():返回 Date 对象的小时 (0 ~ 23)。
  • getMinutes():返回 Date 对象的分钟 (0 ~ 59)。
  • getSeconds():返回 Date 对象的秒数 (0 ~ 59)。
  • getMilliseconds():返回 Date 对象的毫秒(0 ~ 999)。
  • getTime():返回 1970 年 1 月 1 日至今的毫秒数,与valueOf()返回值相同。
  • getTimezoneOffset():返回本地时间与格林威治标准时间 (GMT) 的分钟差。
  • getUTCDate():根据世界时从 Date 对象返回月中的一天 (1 ~ 31)。
  • getUTCDay():根据世界时从 Date 对象返回周中的一天 (0 ~ 6)。
  • getUTCMonth():根据世界时从 Date 对象返回月份 (0 ~ 11)。
  • getUTCFullYear():根据世界时从 Date 对象返回四位数的年份。
  • getUTCHours():根据世界时返回 Date 对象的小时 (0 ~ 23)。
  • getUTCMinutes():根据世界时返回 Date 对象的分钟 (0 ~ 59)。
  • getUTCSeconds():根据世界时返回 Date 对象的秒钟 (0 ~ 59)。
  • getUTCMilliseconds():根据世界时返回 Date 对象的毫秒(0 ~ 999)。
  • parse():返回1970年1月1日午夜到指定日期(字符串)的毫秒数。
  • setDate():设置 Date 对象中月的某一天 (1 ~ 31)。
  • setMonth():设置 Date 对象中月份 (0 ~ 11)。
  • setFullYear():设置 Date 对象中的年份(四位数字)。
  • setYear():请使用 setFullYear() 方法代替。
  • setHours():设置 Date 对象中的小时 (0 ~ 23)。
  • setMinutes():设置 Date 对象中的分钟 (0 ~ 59)。
  • setSeconds():设置 Date 对象中的秒钟 (0 ~ 59)。
  • setMilliseconds():设置 Date 对象中的毫秒 (0 ~ 999)。
  • setTime():以毫秒设置 Date 对象。
  • setUTCDate():根据世界时设置 Date 对象中月份的一天 (1 ~ 31)。
  • setUTCMonth():根据世界时设置 Date 对象中的月份 (0 ~ 11)。
  • setUTCFullYear():根据世界时设置 Date 对象中的年份(四位数字)。
  • setUTCHours():根据世界时设置 Date 对象中的小时 (0 ~ 23)。
  • setUTCMinutes():根据世界时设置 Date 对象中的分钟 (0 ~ 59)。
  • setUTCSeconds():根据世界时设置 Date 对象中的秒钟 (0 ~ 59)。
  • setUTCMilliseconds():根据世界时设置 Date 对象中的毫秒 (0 ~ 999)。
  • toSource():返回该对象的源代码。
  • toString():把 Date 对象转换为字符串。
  • toTimeString():把 Date 对象的时间部分转换为字符串。
  • toDateString():把 Date 对象的日期部分转换为字符串。
  • toGMTString():请使用 toUTCString() 方法代替。
  • toUTCString():根据世界时,把 Date 对象转换为字符串。
  • toLocaleString():根据本地时间格式,把 Date 对象转换为字符串。
  • toLocaleTimeString():根据本地时间格式,把 Date 对象的时间部分转换为字符串。
  • toLocaleDateString():根据本地时间格式,把 Date 对象的日期部分转换为字符串。
  • toISOString():返回对应的UTC时间的 ISO8601 写法,如2012-12-31T16:00:00.000Z,
  • toJSON():返回值同toISOString()
  • UTC():根据世界时返回 1970 年 1 月 1 日 到指定日期的毫秒数。
  • valueOf():返回 Date 对象的原始值。

以上方法大概分为三种:to方法、get方法和set方法。

to方法-日期格式化方法:

date()类型还有一些专门用于将日期格式化为字符串的方法,如:

  • toString():
  • toDateString():以特定于实现的格式显示星期几、月、日和年;
  • toTimeString():以特定于实现的格式显示时、分、秒和时区;
  • toLocaleDateString():以特定于地区的格式显示星期几、月、日和年;
  • toLocaleTimeString():在特定于地区的格式显示 时、分、秒;
  • toUTCString():以特定于实现的格式显示UTC日期;
  • toISOString():返回ISO表示的日期;
  • toGMTString()方法,这是一个与toUTCString()等价的方法,其存在的目的在于确保向后兼容;不过ECMAScript推荐使用toUTCString()方法;

getter方法:

用于获取当前日期时间信息;

var d = new Date();
console.log(d.getDate()); //18
console.log(d.getDay());  //4
console.log(d.getFullYear()); //2020
console.log(d.getMonth()); //5 (starts from 0)
console.log(d.getHours()); //17
console.log(d.getMinutes()); //30
console.log(d.getSeconds()) //13
console.log(d.getMilliseconds()); //765
console.log(d.getTime()) //1591868420160
console.log(d.getTimezoneOffset()); //-480 返回以分钟为单位表示的时区差异

getTimezoneOffset()方法用于说明某个时区与UTC时间的关系,该方法返回当前时区比UTC提前或落后的分钟数; 还可以用于判断该时区是否使用夏令时:

var d1=new Date(2020, 0, 1);
var d2=new Date(2020, 6, 1);
console.log(d1.getTimezoneOffset());  // -480 / 60 = -8小时
var b=d1.getTimezoneOffset() != d2.getTimezoneOffset();  // 判断夏令时
console.log(b);

这些方法有等效的UTC版本,它们返回UTC值而不是适合您当前时区的值

var d = new Date();
console.log(d.getUTCDate()); //18
console.log(d.getUTCDay());  //4
console.log(d.getUTCFullYear()); //2020
console.log(d.getUTCMonth()); //5 (starts from 0)
console.log(d.getUTCHours()); //9
console.log(d.getUTCMinutes()); //30
console.log(d.getUTCSeconds()) //13
console.log(d.getUTCMilliseconds()); //765

setter方法:

var d = new Date();
d.setDate(6);
d.setFullYear(2022);
d.setMonth(4);
d.setHours(4);
d.setMinutes(4);
d.setSeconds(4);
d.setMilliseconds(123);
d.setTime(1598765678999);
console.log(d);

注:setDate 和 setMonth 从 0 开始编号;

这些方法基本是跟getter方法一一对应的,但是没有setDay方法,因为星期几是计算出来的,而不是设置的;

set方法中的参数如果超出它的范围,会进位,称为冒泡,如:date.setHours(48),这也会将日期数变大;

var date = new Date();
date.setFullYear(2022,1,18);
// date.setMonth(24);
date.setMonth(2,8);
date.setHours(16,18,28,208);
console.log(date.toLocaleString());

如果参数是负数,表示从上个月的最后一天开始减去相应的单位数:

以上的方法都有一个相对应的 UTC set方法:

var d = new Date();
d.setUTCDate(6);
d.setUTCFullYear(2022);
d.setUTCMonth(4);
d.setUTCHours(4);
d.setUTCMinutes(4);
d.setUTCSeconds(4);
d.setUTCMilliseconds(123);
console.log(d);

获取当前时间戳:

console.log(new Date().getTime());
console.log(Date.now());

Date.now()方法返回表示调用这个方法时的日期和时间的毫秒数;其简化了Date.getTime()方法,如:

var start = Date.now();
for(var i=0;i<100000;i++){} // 模拟其他处理代码
var stop = Date.now();
var result = stop-start;
alert(result);

如果有些浏览器不支持Date.now(),可以使用+操作符获取Date对象的时间戳,如:

var start = +new Date();
for(var i=0;i<100000;i++){} // 模拟其他处理代码
var stop = +new Date();
var result = stop-start;
alert(result);

日期的计算:

直接加减或通过 Date.getTime() 的值来比较两个 Date 对象:

var d1 = new Date("2020-06-18");
var d2 = new Date("2020-06-19");
console.log(d1 - d2);  // -86400000
console.log(d1 + d2);  // 返回两个日期的字符串拼接
// 或
var d1 = new Date('July 18,2020 14:10:18');
var d2 = new Date('July 19,2020 14:10:18');
var diff = d2.getTime() - d1.getTime();
console.log(diff);

注:getTime() 方法返回以毫秒计的数字,所以需要将当日时刻计入;如:July 18, 2020 14:14:14 不等于July 18, 2020。在这种情况下,可以使用 setHours(0, 0, 0, 0) 来重置当日时刻;

计算本年度还剩下多少天:

function leftDays() {
  var today = new Date();
  var endYear = new Date(today.getFullYear(), 11, 31, 23, 59, 59, 999);
  var msPerDay = 24 * 60 * 60 * 1000;
  return Math.round((endYear.getTime() - today.getTime()) / msPerDay);
}
console.log(leftDays());

小练习:

// 中文月份和星期
var d = new Date();
var month = d.getMonth();
var week = d.getDay();
var monthArr = ['一月','二月','三月','四月','五月','六月','七月','八月','九月','十月','十一月','十二月'];
var weekArr = ['星期日','星期一','星期二','星期三','星期四','星期五','星期六'];
console.log(monthArr[month]);
console.log(weekArr[week]);
 
// 获取日期部分信息
Date.prototype.datePart = function(part){
    if(!part)
        part = 'd';
    var weekArr = ['日','一','二','三','四','五','六'];
    switch(part){
        case 'Y':
        case 'y': 
            return this.getFullYear(); 
            break;
        case 'M': 
            return this.getMonth + 1;
            break;
        case 'W':
        case 'w':
            return weekArr[this.getDay()];
            break;
        case 'D':
        case 'd':
            return this.getDate();
            break;
        case 'H':
        case 'h':
            return this.getHours();
            break;
        case 'm':
            return this.getMinutes();
            break;
        case 's':
            return this.getSeconds();
            break;
        default:
            return this.getDate();
    }
    return this.getDate();
}
console.log(new Date().datePart('d'));

还有多长时间退休:

// 一个人到退休还有多长时间
function retireDays(birthday,age){
    var d1 = new Date(birthday).getFullYear();
    var d2 = new Date().getFullYear();
    var old = d2 - d1;
    console.log("现在你的年龄是:" + old,",将于" + (d1 + age) + "退休");
    if(age - old > 0){
        console.log("还差"+(age - old)+"年退休")
    }else{
        console.log("你已经退休啦,好好享受老年生活吧");
    }
}
retireDays('2020.6.6',60);

倒计时:

<!-- 网页时钟 -->
<p id="mydate"></p>
<script>
function checkTime(i){
    if(i<10)
        i = '0' + i;
    return i;
}
function startTime(){
    var d = new Date();
    var h = d.getHours();
    var m = checkTime(d.getMinutes());
    var s = checkTime(d.getSeconds());
    document.getElementById('mydate').innerHTML = h + ':' + m + ':' + s;
    timer = setTimeout('startTime()', 1000);
}
startTime();
 
// 倒计时
function getCountDown(d){
    var d1 = new Date();
    var d2 = new Date(d);  // 
    var diff = d2 - d1;     // 相差毫秒数
    var o = {};
    if(diff >= 0){
        var day = Math.floor(diff / 1000 / 60 / 60 / 24);  // 剩下多少天
        var hour = Math.floor(diff / 1000 / 60 / 60 % 24);   // 剩下多少小时
        var minute = Math.floor(diff / 1000 / 60 % 60);     // 剩下多少分
        var second = Math.floor(diff / 1000 % 60);  // 剩下多少秒
        o.stop = false;
        o.str = "距离"+d+",还剩下"+day+"天"+hour+"小时"+minute+"分"+second+"秒";
    }else{
        o.stop = true;
        o.str = "已时结束";
    }
    return o;
}
var timer = setInterval(function(){
    var mydate = document.getElementById('mydate');
    mydate.innerHTML = getCountDown('2020.6.8').str;
    if(getCountDown('2020.6.8').stop) clearInterval(timer);
},1000);

计算某个日期加上天数:

// 计算加几天后的日期,days可以使用负数
// 如果计算月份,是一样的原理
function addDate(date,days){
    var d = new Date(date);
    d.setDate(d.getDay() + days);
    var month = d.getMonth() + 1;
    var day = d.getDate();
    if(month < 10)
        month = "0" + month;
    if(day < 10)
        day = "0" + day;
    var value = d.getFullYear() + "-" + month + "-" + day;
    return value;
}
console.log(addDate('2020-6-6',50));
console.log(addDate('2020-6-6',-6));

小练习:

// 判断闰年:四年一闰,百年不闰,四百年再闰
Date.prototype.isLeapYear = function(){
    return (this.getFullYear() % 4 == 0 && ((this.getFullYear() % 100 !=0) || (this.getFullYear() % 400 == 0)));
}
var d = new Date();
console.log(d.isLeapYear());
d.setFullYear(2019);
console.log(d.isLeapYear());
 
// 计算两个日期的天数差
function daysDiff(dateOne,dateTwo){
    var oneMonth = dateOne.substring(5, dateOne.lastIndexOf('-'));
    var oneDay = dateOne.substring(dateOne.length,dateOne.lastIndexOf('-') + 1);
    var oneYear = dateOne.substring(0, dateOne.indexOf('-'));
    var twoMonth = dateTwo.substring(5, dateTwo.lastIndexOf('-'));
    var twoDay = dateTwo.substring(dateTwo.length, dateTwo.lastIndexOf('-') + 1);
    var twoYear = dateTwo.substring(0, dateTwo.indexOf('-'));
    var diff = ((Date.parse(oneMonth+'/'+oneDay+'/'+oneYear) - Date.parse(twoMonth+'/'+twoDay+'/'+twoYear)) / 86400000);
    return diff;
}
console.log(daysDiff('2020-6-6','2020-5-30'));

格式化输出:

Date.prototype.format = function(fmt){
    var o = {
        "M+" : this.getMonth() + 1,
        "d+" : this.getDate(),
        "h+" : this.getHours(),
        "m+" : this.getMinutes(),
        "s+" : this.getSeconds(),
        "q+" : Math.floor((this.getMonth() + 3) / 3),
        "S"  : this.getMilliseconds()
    };
    if(/(y+)/.test(fmt)){
        fmt = fmt.replace(RegExp.$1,
            (this.getFullYear() + "").substr(4 - RegExp.$1.length));
    }
    for(var k in o){
        if(new RegExp("(" + k + ")").test(fmt)){
            fmt = fmt.replace(RegExp.$1,
                RegExp.$1.length ===1
                    ? o[k]
                    : ("00" + o[k]).substr(("" + o[k]).length));
        }
    }
    return fmt;
};
var d = new Date(2020,6,6,0,0,0);
console.log(d);
console.log(d.format('yyyy年MM月dd日'));  // 2020年07月06日
console.log(d.format('yyyy年MM月d日 hh:mm:ss'));  // 2020年07月6日 00:00:00

Intl对象:

Intl 对象是 ECMAScript 国际化 API 的一个命名空间,它提供了精确的字符串对比(Collator ),数字格式化(NumberFormat),日期和时间格式化(DateTimeFormat)等对象。

var date = new Date();
console.log(date);
console.log(Intl.DateTimeFormat().format(date));  // 2020/7/22
console.log(new Intl.DateTimeFormat('en-US').format(date));  // 6/7/2020

Intl对象的属性:

  • Intl.Collator:collators的构造函数,用于启用对语言敏感的字符串比较的对象。
  • Intl.DateTimeFormat:用于启用语言敏感的日期和时间格式的对象的构造函数。
  • Intl.ListFormat:启用语言敏感列表格式的对象的构造函数。
  • Intl.NumberFormat:用于启用语言敏感数字格式的对象的构造函数。
  • Intl.PluralRules:用于启用多种敏感格式和多种语言语言规则的对象的构造函数。
  • Intl.RelativeTimeFormat:对象的构造函数,该对象启用对语言敏感的相对时间格式。

Intl.DateTimeFormat:

语法:

new Intl.DateTimeFormat([locales[, options]])
Intl.DateTimeFormat([locales[, options]])

参数:

locales:可选,缩写语言代码(BCP 47 language tag),如:cmn-Hans-CN)的字符串或者这些字符串组成的数组;

两种扩展的格式:language[-scripts][-region]-u-nu-* 和 language[-scripts][-region]-u-ca-* ;例如:zh-u-nu-hanidec(表示中文十进制数字) 和 zh-u-ca-chinese(表示中国日历,比如壬辰年冬月8日) ,也可以 nu 和 ca 组合使用,如使用:zh-u-ca-chinese-nu-hanidec 格式化Date.now()的返回值类似于"丙申年冬月九日";

nu:编号系统,可能的值包括:

"arab", "arabext", "bali", "beng", "deva", "fullwide", "gujr", "guru", "hanidec", "khmr", "knda", "laoo", "latn", "limb", "mlym", "mong", "mymr", "orya", "tamldec", "telu", "thai", "tibt".

ca:日历,可能的值包括:

"buddhist", "chinese", "coptic", "ethioaa", "ethiopic", "gregory", "hebrew", "indian", "islamic", "islamicc", "iso8601", "japanese", "persian", "roc".

var date = new Date();
// 韩国使用 year-month-day 格式
console.log(new Intl.DateTimeFormat('ko-KR').format(date));
// 2020. 6. 18
 
//大部分阿拉伯国家使用阿拉伯字母(real Arabic digits)
console.log(new Intl.DateTimeFormat('ar-EG').format(date));
// "???/???/????"
 
//在日本,应用可能想要使用日本日历,
//2020 是平成32年(平成是是日本天皇明仁的年号,由1989年1月8日起开始计算直至现在)
console.log(new Intl.DateTimeFormat('ja-JP-u-ca-japanese').format(date));
// 类似"平成32/6/20"
 
//当请求一个语言可能不支持,如巴厘(ban),若有备用的语言印尼语(id),
//那么将使用印尼语(id)
console.log(new Intl.DateTimeFormat(['ban', 'id']).format(date));
// "20/6/2020"
 
console.log(new Intl.DateTimeFormat('zh-CN').format(date));  // 2020/6/11
console.log(new Intl.DateTimeFormat('zh-u-nu-hanidec').format(date)); //二〇二〇/六/一一
console.log(new Intl.DateTimeFormat('zh-u-ca-chinese').format(date));//37/闰4/20
console.log(new Intl.DateTimeFormat('zh-u-ca-chinese-nu-hanidec').format(date));//三七/闰四/二〇

options参数:

可选,自定义输出,包含一些或所有的下面属性:

localeMatcher:

使用的local的匹配算法. 可能的值有"lookup"和"best fit"; 默认值 "best fit";

timeZone:

使用的时区. 这唯一的值实现必须被标准世界时间(UTC)所识别。默认值是运行时的默认时区. IANA time zone database中的时区名称可能会被识别, 例如"Asia/Shanghai", "Asia/Kolkata", "America/New_York";

hour12:

是否使用12小时时间制(而不是24小时的时间),值是true 或 false; 默认值是根据locale来自动决定的(中国地区的默认值为true);

formatMatcher:

format的匹配算法,值有"basic"和"best fit",默认值是"best fit";

日期时间插件被格式化输出时可以使用的属性集合描述。实现需要支持是以下子集中的其中一个:

  • weekday, year, month, day, hour, minute, second
  • weekday, year, month, day
  • year, month, day
  • year, month
  • month, day
  • hour, minute, second
  • hour, minute

实现可能支持其他的子集,并通过对所有可用的子集对比找到最匹配的子集。通过 formatMatcher属性可以设置两种算法用于对比和选择子集: 完全匹配"basic"算法和一种依赖于“best fit”算法的实现;

  • weekday:工作日的展现方式.可能的值有 "narrow", "short", "long".
  • era:纪元的展现方式. 可能的值有 "narrow", "short", "long".
  • year:年的展现方式. 可能的值有 "numeric", "2-digit".
  • month:月的展现方式. 可能的值有 "numeric", "2-digit", "narrow", "short", "long".
  • day:日的展现方式.可能的值有 "numeric", "2-digit".
  • hour:时的展现方式.可能的值有 "numeric", "2-digit".
  • minute:分钟的展现方式.可能的值有 "numeric", "2-digit".
  • second:秒的展现方式. 可能的值有"numeric", "2-digit".
  • timeZoneName:时区名称的展现方式.可能的值有 "short", "long".

每个日期时间组件属性的默认值都是undefined,但是若所有的组件属性都是undefined,那么year, month和day的值就都被认为是"numeric";

var date = new Date();
var options = {year:'numeric',month:'numeric',day:'numeric',hour:'numeric',minute:'numeric',second:'numeric'};
console.log(new Intl.DateTimeFormat('en-US').format(date));  // 6/7/2020
console.log(new Intl.DateTimeFormat('en-US',options).format(date));  // 6/7/2020, 3:07:31 PM
console.log(new Intl.DateTimeFormat('it-IT').format(date));  // 7/6/2020
console.log(new Intl.DateTimeFormat('it-IT',options).format(date));  // 7/6/2020, 15:08:34
 
var date = new Date(Date.UTC(2020, 6, 18, 6, 30, 18));
 
//请求参数(options)中包含参数星期(weekday),并且该参数的值为长类型(long)
var options = { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric' };
console.log(new Intl.DateTimeFormat('zh-CN', options).format(date));
console.log(new Intl.DateTimeFormat('de-DE', options).format(date));
// Samstag, 18. Juli 2020
 
// 一个应用使用 世界标准时间(UTC),并且UTC使用短名字(short)展示
options.timeZone = 'UTC';
//若不写这一行那么仍然显示的是世界标准时间;但是UTC三个字母不会显示
options.timeZoneName = 'short';
console.log(new Intl.DateTimeFormat('en-US', options).format(date));
// Saturday, July 18, 2020, UTC
 
// 更精确的定义
options = {
  hour: 'numeric', minute: 'numeric', second: 'numeric',
  timeZoneName: 'short'
};
console.log(new Intl.DateTimeFormat('en-US', options).format(date));
// 12:30:18 PM GMT+8
 
// 使用24小时制
options = {
  year: 'numeric', month: 'numeric', day: 'numeric',
  hour: 'numeric', minute: 'numeric', second: 'numeric',
  hour12: false
};
console.log(date.toLocaleString('en-US', options));  // 7/18/2020, 14:30:18
console.log(date.toLocaleString('zh-CN', options));  // 2020/7/18 14:30:18

日期插件库:

Datejs 是一个开源的JavaScript库,用来解析、格式化和处理日期数据,支持多种语言的日期格式处理;官网:www.datejs.com/

Moment.js 是一个简单易用的轻量级JavaScript日期处理类库,提供了日期格式化、日期解析等功能。它支持在浏览器和NodeJS两种环境中运行;

date-fns库:现代 JavaScript 日期实用程序库。date-fns 提供了最全面,最简单和一致的工具集,用于在浏览器和 Node.js 中操作 JavaScript 日期;官网:date-fns.org

Prettydate 是一个 jQuery 用来显示一些用户友好的日期格式的插件,例如Posted 2 days ago by John Resig;

Countdown是jQuery的一个用于显示倒计时的插件;

XDate是一个对Javascirpt本地Date对象的轻度包装,它提供对日期的解析、格式化以及其他操作的较强功能;

DP_DateExtensions库继承了JavaScript的Date对象,并添加了一些新特性和功能;

组件类:

layDate 日期与时间组件,layDate 是 layui 独立维护的三大组件之一;官网:www.layui.com/laydate/。


Web前端开发之Javascript-零点程序员-王唯

CMAScript 提供了 Date 类型来处理时间和日期。 Date 类型内置一系列获取和设置日期时间信息的方法。


一. Date 类型

ECMAScript 中的 Date 类型是在早期 Java 中 java.util.Date 类基础上构建的。 为此, Date类型使用 UTC (Coordinated Universal Time,国际协调时间[又称世界统一时间]) 1970 年 1 月1 日午夜(零时)开始经过的毫秒来保存日期。在使用这种数据存储格式的条件下,Date 类型保存的日期能够精确到 1970 年 1 月 1 日之前或之后的 285616 年。

创建一个日期对象,使用 new 运算符和 Date 构造方法(构造函数)即可。

var box=new Date(); //创建一个日期对象

在调用 Date 构造方法而不传递参数的情况下, 新建的对象自动获取当前的时间和日期。

alert(box); //不同浏览器显示不同

ECMAScript 提供了两个方法,Date.parse()和 Date.UTC()。Date.parse()方法接收一个表示日期的字符串参数,然后尝试根据这个字符串返回相应的毫秒数。

Date.parse()应该支持哪种日期格式,因此方法的行为因实现而异,因地区而异。默认通常接收的日期格式如下:

1.'月/日/年',如 6/13/2011;

2.'英文月名 日, 年',如 May 25, 2004;

3.'英文星期几 英文月名 日 年 时:分:秒 时区', 如 Tue May 25 2004 00:00:00 GMT-070

alert(Date.parse('6/13/2011')); //1307894400000

如果 Date.parse()没有传入或者不是标准的日期格式,那么就会返回 NaN。

alert(Date.parse()); //NaN

如果想输出指定的日期,那么把 Date.parse()传入 Date 构造方法里。

var box=new Date(Date.parse('6/13/2011'));//Mon Jun 13 2011 00:00:00 GMT+0800

var box=new Date('6/13/2011'); //直接传入,Date.parse()后台被调用

Date.UTC()方法同样也返回表示日期的毫秒数, 但它与 Date.parse()在构建值时使用不同的信息。 (年份, 基于 0 的月份[0 表示 1 月, 1 表示 2 月], 月中的哪一天[1-31], 小时数[0-23] ,分钟,秒以及毫秒)。只有前两个参数是必须的。如果没有提供月数,则天数为 1;如果省略其他参数,则统统为 0.

alert(Date.UTC(2011,11)); //1322697600000

如果 Date.UTC()参数传递错误,那么就会出现负值或者 NaN 等非法信息。

alert(Date.UTC()); //负值或者 NaN

如果要输出指定日期,那么直接把 Date.UTC()传入 Date 构造方法里即可。

var box=new Date(Date.UTC(2011,11, 5, 15, 13, 16));

二. 通用的方法

与其他类型一样,Date 类型也重写了 toLocaleString()、toString()和 valueOf()方法;但这些方法返回值与其他类型中的方法不同。

var box=new Date(Date.UTC(2011,11, 5, 15, 13, 16));

alert('toString:' + box.toString());

alert('toLocaleString:' + box.toLocaleString()); //按本地格式输出

注:这两个方法在不同浏览器显示的效果又不一样,但不用担心,这两个方法只是在调试比较有用,在显示时间和日期上,没什么价值。valueOf()方法显示毫秒数。

三. 日期格式化方法

Date 类型还有一些专门用于将日期格式化为字符串的方法。

var box=new Date();

alert(box.toDateString()); //以特定的格式显示星期几、月、日和年

alert(box.toTimeString()); //以特定的格式显示时、分、秒和时区

alert(box.toLocaleDateString()); //以特定地区格式显示星期几、月、日和年

alert(box.toLocaleTimeString()); //以特定地区格式显示时、分、秒和时区

alert(box.toUTCString()); //以特定的格式显示完整的 UTC 日期。

四. 组件方法

组件方法,是为我们单独获取你想要的各种时间/日期而提供的方法。需要注意的时候 ,这些方法中,有带 UTC 的,有不带 UTC 的。UTC 日期指的是在没有时区偏差的情况下的日期值。

alert(box.getTime()); //获取日期的毫秒数,和 valueOf()返回一致

alert(box.setTime(100)); //以毫秒数设置日期,会改变整个日期

alert(box.getFullYear()); //获取四位年份

alert(box.setFullYear(2012)); //设置四位年份,返回的是毫秒数

alert(box.getMonth()); //获取月份,没指定月份,从 0 开始算起

alert(box.setMonth(11)); //设置月份

alert(box.getDate()); //获取日期

alert(box.setDate(8)); //设置日期,返回毫秒数

alert(box.getDay()); //返回星期几,0 表示星期日,6 表示星期六

alert(box.setDay(2)); //设置星期几

alert(box.getHours()); //返回时

alert(box.setHours(12)); //设置时

alert(box.getMinutes()); //返回分钟

alert(box.setMinutes(22)); //设置分钟

alert(box.getSeconds()); //返回秒数

alert(box.setSeconds(44)); //设置秒数

alert(box.getMilliseconds()); //返回毫秒数

alert(box.setMilliseconds()); //设置毫秒数

alert(box.getTimezoneOffset()); //返回本地时间和 UTC 时间相差的分钟数

注: 以上方法除了 getTimezoneOffset(), 其他都具有 UTC 功能, 例如 setDate()及 getDate()获取星期几,那么就会有 setUTCDate()及 getUTCDate()。表示世界协调时间。

最后附上代码