Moment

作者:高天阳

邮箱:13683265113@163.com

更改历史

* 2018-09-25        高天阳      添加.diff()方法文档
* 2018-08-15        高天阳      初始化文档

1. 简介

1.1 什么是Moment

Moment旨在在浏览器和Node.js中工作。

目前,以下浏览器用于ci系统:Windows 7上的IE8,IE9,Windows XP上的稳定Chrome, Mac上的Safari 10.8和Linux上的稳定Firefox。

所有代码都适用于这两种环境。所有单元测试都在两种环境中运行。

moment.js不依赖任何第三方库,支持字符串、Date、时间戳以及数组等格式, 可以像PHP的date()函数一样,格式化日期时间,计算相对时间,获取特定时间后的日期时间等等。

2. 安装和使用

2.1 安装

2.1.1 Node.js

npm install moment
var moment = require('moment');
moment().format();
  • 注意:在2.4.0版本,不推荐使用全局导出的时刻对象。它将在下一个主要版本中删除。

2.1.2 script标签引入

<script src="moment.js"></script>
<script>
    moment().format();
</script>
  • 注意:Moment.js可在cdnjs.com上找到。但请记住将他们的script标签串联以最小化http请求。

2.1.3 Bower

bower install --save moment
  • 注意:moment.js,locale/*.js和min/moment-with-locales.js。

2.1.4 Require.js

require.config({
    paths: {
        "moment": "path/to/moment",
    }
});
define(["moment"], function (moment) {
    moment().format();
});

Moment仍将创建一个moment全局,这对插件和其他第三方代码很有用。如果您希望压缩全局,请使用noGlobal模块配置中的选项。

require.config({
    config: {
        moment: {
            noGlobal: true
        }
    }
});

如果未指定,noGlobal则全局导出的时刻将打印弃用警告。从下一个主要版本开始,如果你想要这种行为,你必须自己导出它。

对于版本2.5.x,如果您使用其他依赖Moment但不兼容AMD的插件,则可能需要添加wrapShim: truer.js配置中。

  • 注意:要允许在requirejs环境中加载moment.js插件,请将时刻创建为命名模块。正因为如此,时刻必须被加载完全一样的"moment",用paths确定的目录。需要时刻与路径一样"vendor\moment"将返回undefined。

  • 注意:从版本2.9.0开始,将自身导出为匿名模块,因此如果您只使用核心(没有区域设置/插件),那么如果将其放在非标准位置,则不需要配置。

2.1.5 NuGet

Install-Package Moment.js

2.1.6 spm

spm install moment --save

2.1.7 meteor

meteor add momentjs:moment

2.2 使用

Date.prototypeMoment.js 不是修改本机日期,而是为Date对象创建一个包装器。 要获取此包装器对象,只需moment()使用其中一种受支持的输入类型进行调用即可。

Moment原型是通过暴露moment.fn。如果你想添加自己的功能,那就是你要放置它们的地方。

为便于参考,Moment.prototype将在文档中引用任何方法moment#method。 所以Moment.prototype.format=== moment.fn.format=== moment#format

2.2.1 当前时间 1.0.0+

moment();

要获取当前日期和时间,只需moment()使用无参数调用即可。

var now = moment();

这与调用moment(new Date())基本相同。

var year1995 = moment("1995-12-25");

格式化日期1995-12-25

2.2.2 字符串 1.0.0+

moment(String);

从字符串创建时刻时,我们首先检查字符串是否与已知的ISO 8601格式匹配, 然后在new Date(string)找不到已知格式时返回。

var day = moment("1995-12-25");
  • 警告:浏览器对解析字符串支持不一致

    由于没有关于应支持哪种格式的规范,因此在某些浏览器中有效的功能将无法在其他浏览器中使用。

为了解析除ISO 8601字符串以外的任何其他内容的一致结果, 您应该使用String + Format

支持的ISO 8601字符串

ISO 8601字符串需要日期部分。

2013-02-08  # A calendar date part
2013-W06-5  # A week date part
2013-039    # An ordinal date part

还可以包括时间部分,通过空格或大写T与日期部分分开。

2013-02-08T09            # An hour time part separated by a T
2013-02-08 09            # An hour time part separated by a space
2013-02-08 09:30         # An hour and minute time part
2013-02-08 09:30:26      # An hour, minute, and second time part
2013-02-08 09:30:26.123  # An hour, minute, second, and millisecond time part
2013-02-08 24:00:00.000  # hour 24, minute, second, millisecond equal 0 means next day at midnight

任何日期部分都可以包含时间部分。

2013-02-08 09  # A calendar date part and hour time part
2013-W06-5 09  # A week date part and hour time part
2013-039 09    # An ordinal date part and hour time part

如果一个时间部分被包括,一个从UTC偏移量也可被包括为+-HH:mm+-HHmm,或Z

2013-02-08 09+07:00            # +-HH:mm
2013-02-08 09-0100             # +-HHmm
2013-02-08 09Z                 # Z
2013-02-08 09:30:26.123+07:00  # +-HH:mm
  • 注意:1.5.0版中添加了自动跨浏览器ISO-8601支持。版本2.3.0中添加了对星期和序数格式的支持。

    如果字符串与上述任何格式都不匹配且无法解析Date.parsemoment#isValid则返回false。

moment("not a real date").isValid(); // false

2.2.3 字符串+格式 1.0.0+

moment(String, String);
moment(String, String, String);
moment(String, String, Boolean);
moment(String, String, String, Boolean);

如果您知道输入字符串的格式,可以使用它来解析片刻。

moment("12-25-1995", "MM-DD-YYYY");

解析器忽略非字母数字字符,因此以下两个都将返回相同的内容。

moment("12-25-1995", "MM-DD-YYYY");
moment("12/25/1995", "MM-DD-YYYY");

解析令牌类似于使用的格式化令牌moment#format

年,月,日缩写

输入

输出

描述

YYYY

2014

4或2位数年份

YY

14

2位数年份

Q

1..4

一年四分之一。将季度设置为季度的第一个月。

M MM

1..12

月份编号

MMM MMMM

Jan..December

设置的语言环境中的月份名称 moment.locale()

D DD

1..31

一个月的一天

Do

1st..31st

有序的月份日

DDD DDDD

1..365

一年的一天

X

1410715640.579

Unix时间戳

x

1410715640579

Unix ms时间戳

YYYY从版本2.10.5支持2位数年份,并将它们转换为2000年附近的一年(相同YY)。

周年,周和工作日缩写

对于这些,小写标记使用区域设置感知周开始日期,而大写标记使用ISO周日期开始日期。

输入

输出

描述

gggg

2014

Locale 4位数周

gg

14

Locale 2位数周

w ww

1..53

一年中的地方周

e

1..7

区域日期

ddd dddd

Mon...Sunday

设置的语言环境中的月份名称 moment.locale()

GGGG

2014

ISO 4位数周

GG

14

ISO 2位数周

W WW

1..53

ISO周一年

E

1..7

ISO星期几

小时,分钟,秒,毫秒和偏移缩写

输入

输出

描述

H HH

0..23

24小时的时间

h hh

1..12

使用12小时的时间a A。

a A

am pm

张贴或赌注meridiem

m mm

0..59

分钟

s ss

0..59

S

0..9

十分之一秒

SS

0..99

百分之一秒

SSS

0..999

千分之一秒

SSSS

0000..9999

毫秒

Z ZZ

+12:00

从UTC偏移量+-HH:mm,+-HHmm或Z

从版本2.10.5:小数秒标记长度4到9可以解析任意数量的数字,但只考虑前3(毫秒)。如果您有时间打印了许多小数位并想要消耗输入,请使用。

还可以使用区域设置感知日期和时间格式LT LTS L LL LLL LLLL。它们是在2.2.1版本中添加的,除了LTS增加了 2.8.4

Z ZZ在版本中添加1.2.0

S SS SSS在版本中添加1.6.0

X在版本中添加2.0.0

除非指定时区偏移量,否则解析字符串将在当前时区中创建日期。

moment("2010-10-20 4:30",       "YYYY-MM-DD HH:mm");   // parsed as 4:30 local time
moment("2010-10-20 4:30 +0000", "YYYY-MM-DD HH:mm Z"); // parsed as 4:30 UTC

如果由解析的输入产生的时刻不存在,moment#isValid则返回false。

moment("2010 13",           "YYYY MM").isValid();     // false (not a real month)
moment("2010 11 31",        "YYYY MM DD").isValid();  // false (not a real day)
moment("2010 2 29",         "YYYY MM DD").isValid();  // false (not a leap year)
moment("2010 notamonth 29", "YYYY MMM DD").isValid(); // false (not a real month name)

从版本开始2.0.0,可以将区域设置键作为第三个参数传递给moment()moment.utc()

moment('2012 juillet', 'YYYY MMM', 'fr');
moment('2012 July',    'YYYY MMM', 'en');

Moment的解析器非常宽容,这可能会导致不良行为。从版本开始2.3.0,您可以为最后一个参数指定一个布尔值, 以使Moment使用严格的解析。严格的解析要求格式和输入完全匹配。

moment('It is 2012-05-25', 'YYYY-MM-DD').isValid();       // true
moment('It is 2012-05-25', 'YYYY-MM-DD', true).isValid(); // false
moment('2012-05-25',       'YYYY-MM-DD', true).isValid(); // true

您可以同时使用区域设置和严格性。

moment('2012-10-14', 'YYYY-MM-DD', 'fr', true);

解析两位数年份

默认情况下,68岁以上的两位数年份假定为1900年,68年或以下年份假定为2000年。可以通过替换moment.parseTwoDigitYear方法来更改此设置。

2.2.4 格式化时间 1.0.0+

moment().format();
moment().format(String);
var day = moment().format()  // 2018-08-17T08:41:34+08:00
var dayMMDoYYYYHHmmssa = moment().format('MMMM Do YYYY, h:mm:ss a')  // 八月 17日 2018, 8:41:34 早上 
var daydddd = moment().format('dddd')  // 星期五
var dayMMMDoYY = moment().format('MMM Do YY')  // 8月 17日 18
var dayYYYYescapedYYYY = moment().format('YYYY [escaped] YYYY')  // 2018 escaped 2018

描述

输入

输出

Month

M

1 2 ... 11 12

Month

Mo

1st 2nd ... 11th 12th

Month

MM

01 02 ... 11 12

Month

MMM

Jan Feb ... Nov Dec

Month

MMMM

January February ... November December

Quarter

Q

1 2 3 4

Day of Month

D

1 2 ... 30 31

Day of Month

Do

1st 2nd ... 30th 31st

Day of Month

DD

01 02 ... 30 31

Day of Year

DDD

1 2 ... 364 365

Day of Year

DDDo

1st 2nd ... 364th 365th

Day of Year

DDDD

001 002 ... 364 365

Day of Week

d

0 1 ... 5 6

Day of Week

do

0th 1st ... 5th 6th

Day of Week

dd

Su Mo ... Fr Sa

Day of Week

ddd

Sun Mon ... Fri Sat

Day of Week

dddd

Sunday Monday ... Friday Saturday

Day of Week (Locale)

e

0 1 ... 5 6

Day of Week (ISO)

E

1 2 ... 6 7

Week of Year

w

1 2 ... 52 53

Week of Year

wo

1st 2nd ... 52nd 53rd

Week of Year

ww

01 02 ... 52 53

Week of Year (ISO)

W

1 2 ... 52 53

Week of Year (ISO)

Wo

1st 2nd ... 52nd 53rd

Week of Year (ISO)

WW

01 02 ... 52 53

Year

YY

70 71 ... 29 30

Year

YYYY

1970 1971 ... 2029 2030

Week Year

gg

70 71 ... 29 30

Week Year

gggg

1970 1971 ... 2029 2030

Week Year (ISO)

GG

70 71 ... 29 30

Week Year (ISO)

GGGG

1970 1971 ... 2029 2030

AM/PM

A

AM PM

AM/PM

a

am pm

Hour

H

0 1 ... 22 23

Hour

HH

00 01 ... 22 23

Hour

h

1 2 ... 11 12

Hour

hh

01 02 ... 11 12

Minute

m

0 1 ... 58 59

Minute

mm

00 01 ... 58 59

Second

s

0 1 ... 58 59

Second

ss

00 01 ... 58 59

Fractional Second

S

0 1 ... 8 9

Fractional Second

SS

00 01 ... 98 99

Fractional Second

SSS

000 001 ... 998 999

Fractional Second

SSSS ... SSSSSSSSS

000[0..] 001[0..] ... 998[0..] 999[0..]

Timezone

z or zz

EST CST ... MST PST Note: as of 1.6.0, the z/zz format tokens have been deprecated. Read more about it here.

Timezone

Z

-07:00 -06:00 ... +06:00 +07:00

Timezone

ZZ

-0700 -0600 ... +0600 +0700

Unix Timestamp

X

1360013296

Unix Millisecond Timestamp

x

1360013296123

2.2.5 时差(之前,现在为基准) 1.0.0+

moment().fromNow();
moment().fromNow(Boolean);

显示时间的常用方法由处理moment#fromNow。这有时被称为timeago或相对时间。

var dayYYYYMMDD = moment("20111031", "YYYYMMDD").fromNow(); // 7 年前
var dayYYYYMMDD2 = moment("20120620", "YYYYMMDD").fromNow(); // 6 年前

如果通过true,则可以获得不带后缀的值。

var dayYear = moment([2007, 0, 29]).fromNow(true);       // 4 年

描述

输入

输出

0 to 45 seconds

s

a few seconds ago

45 to 90 seconds

m

a minute ago

90 seconds to 45 minutes

mm

2 minutes ago ... 45 minutes ago

45 to 90 minutes

h

an hour ago

90 minutes to 22 hours

hh

2 hours ago ... 22 hours ago

22 to 36 hours

d

a day ago

36 hours to 25 days

dd

2 days ago ... 25 days ago

25 to 45 days

M

a month ago

45 to 345 days

MM

2 months ago ... 11 months ago

345 to 545 days (1.5 years)

y

a year ago

546 days+

yy

2 years ago ... 20 years ago

2.2.6 时差(之前) 1.0.0+

moment().from(Moment|String|Number|Date|Array);
moment().from(Moment|String|Number|Date|Array, Boolean);

您可能希望显示与现在不同的时间相关的时刻。在这种情况下,您可以使用moment#from

var a = moment([2007, 0, 28]);
var b = moment([2007, 0, 29]);
a.from(b) // "a day ago"

第一个参数是您可以传递给的任何参数moment()或实际参数Moment

var a = moment([2007, 0, 28]);
var b = moment([2007, 0, 29]);
a.from(b);                     // "a day ago"
a.from([2007, 0, 29]);         // "a day ago"
a.from(new Date(2007, 0, 29)); // "a day ago"
a.from("2007-01-29");          // "a day ago"

比如moment#fromNow,传递true第二个参数返回没有后缀的值。只要您需要具有人类可读的时间长度,这就非常有用。

var start = moment([2007, 0, 5]);
var end   = moment([2007, 0, 10]);
end.from(start);       // "in 5 days"
end.from(start, true); // "5 days"

2.2.7 时差(毫秒) 1.0.0+

moment().diff(Moment|String|Number|Date|Array);
moment().diff(Moment|String|Number|Date|Array, String);
moment().diff(Moment|String|Number|Date|Array, String, Boolean);

要获得以毫秒为单位的差异,请moment#diff像使用一样使用moment#from

var a = moment([2007, 0, 29]);
var b = moment([2007, 0, 28]);
a.diff(b) // 86400000

为了获得另一个测量单位的差异,将该测量值作为第二个参数传递。

var a = moment([2007, 0, 29]);
var b = moment([2007, 0, 28]);
a.diff(b, 'days') // 1

支持的测量包括年,月,周,日,小时,分钟和秒。为了便于开发,从2.0.0开始支持单数形式。版本1.1.1中提供了毫秒以外的度量单位。

默认情况下,moment#diff将向下舍入数字。如果需要浮点数,则传递true为第三个参数。 在2.0.0之前,moment#diff返回舍入的数字,而不是向下舍入的数字。

var a = moment([2008, 6]);
var b = moment([2007, 0]);
a.diff(b, 'years');       // 1
a.diff(b, 'years', true); // 1.5

如果时刻早于您传递的时刻moment.fn.diff,则返回值将为负数。

var a = moment();
var b = moment().add(1, 'seconds');
a.diff(b) // -1000
b.diff(a) // 1000

想到这一点的简单方法是用.diff(减号运算符替换。

          // a < b
a.diff(b) // a - b < 0
b.diff(a) // b - a > 0

月和年的差异

moment#diff有一些特殊的处理月和年差异。它经过优化,可确保相同日期的两个月始终是一个整数。

所以1月15日到2月15日应该是1个月。

2月28日至3月28日应该是1个月。

2011年2月28日至2012年2月28日应该是1年。

请在此处查看有关月份和年度差异的更多讨论

月份和年份差异的变化是在2.0.0中进行的。截至2.9.0版本,差异也支持季度单位。

2.2.8 操纵时间(加法) 1.0.0+

通过增加时间来改变原始时刻。

这是一个非常强大的功能,可以为现有时刻增加时间。要添加时间,请传递要添加的时间键以及要添加的金额。

moment().add(Number, String);
moment().add(Duration);
moment().add(Object);

如果你涉及整个简洁的事情,也有一些速记键。

moment().add(7, 'days');
moment().add(7, 'd');

描述

输入

years

y

quarters

Q

months

M

weeks

w

days

d

hours

h

minutes

m

seconds

s

milliseconds

ms

如果要同时添加多个不同的键,可以将它们作为对象文字传递。

moment().add(7, 'days').add(1, 'months'); // with chaining
moment().add({days:7,months:1}); // with object literal

金额没有上限,因此您可以重载任何参数。

moment().add(1000000, 'milliseconds'); // a million milliseconds
moment().add(360, 'days'); // 360 days

几个月和几年的特殊考虑

如果原始日期的月份日期大于最后一个月的天数,则该月的日期将更改为最后一个月的最后一天。

moment([2010, 0, 31]);                  // January 31
moment([2010, 0, 31]).add(1, 'months'); // February 28

在添加跨越夏令时的时间时,还要特别注意。如果您要添加年,月,周或天,则原始小时将始终与添加的小时相匹配。

var m = moment(new Date(2011, 2, 12, 5, 0, 0)); // the day before DST in the US
m.hours(); // 5
m.add(1, 'days').hours(); // 5

如果要添加小时,分钟,秒或毫秒,则假设您需要精确到小时,并且将导致不同的小时。

var m = moment(new Date(2011, 2, 12, 5, 0, 0)); // the day before DST in the US
m.hours(); // 5
m.add(24, 'hours').hours(); // 6

或者,您可以使用持续时间添加到时刻。

var duration = moment.duration({'days' : 1});
moment([2012, 0, 31]).add(duration); // February 1

在版本之前2.8.0moment#add(String, Number)还支持语法。它已经被弃用了moment#add(Number, String)

moment().add('seconds', 1); // Deprecated in 2.8.0
moment().add(1, 'seconds');

2.2.9 操纵时间(减法) 1.0.0+

moment().subtract(Number, String);
moment().subtract(Duration);
moment().subtract(Object);

通过减去时间来改变原始时刻。

这与完全相同moment#add,只是减去时间,而不是增加时间。

moment().subtract(7, 'days');

在版本之前2.8.0moment#subtract(String, Number)还支持语法。它已经被弃用了moment#subtract(Number, String)

moment().subtract('seconds', 1); // Deprecated in 2.8.0
moment().subtract(1, 'seconds');

2.2.10 开始时间 1.7.0+

moment().startOf(String);

通过将其设置为单位时间的开始来突变原始时刻。

moment().startOf('year');    // set to January 1st, 12:00 am this year
moment().startOf('month');   // set to the first of this month, 12:00 am
moment().startOf('quarter');  // set to the beginning of the current quarter, 1st day of months, 12:00 am
moment().startOf('week');    // set to the first day of this week, 12:00 am
moment().startOf('isoWeek'); // set to the first day of this week according to ISO 8601, 12:00 am
moment().startOf('day');     // set to 12:00 am today
moment().startOf('hour');    // set to now, but with 0 mins, 0 secs, and 0 ms
moment().startOf('minute');  // set to now, but with 0 seconds and 0 milliseconds
moment().startOf('second');  // same as moment().milliseconds(0);

这些快捷方式基本上与以下内容相同。

moment().startOf('year');
moment().month(0).date(1).hours(0).minutes(0).seconds(0).milliseconds(0);
moment().startOf('hour');
moment().minutes(0).seconds(0).milliseconds(0)

从版本2.0.0开始,moment#startOf('day')替换moment#sod

注意: moment#startOf('week')在2.0.0版中添加了。

从版本2.1.0开始,moment#startOf('week')使用区域设置感知周开始日。

注意: moment#startOf('isoWeek')在2.2.0版中添加了。

2.2.11 结束时间 1.7.0+

moment().endOf(String);

通过将其设置为单位时间的结尾来突变原始时刻。

这与moment#startOf仅设置为单位时间的开始,而不是设置为单位时间的结束。

moment().endOf("year"); // set the moment to 12-31 11:59:59.999 pm this year

从版本2.0.0开始,moment#endOf('day')替换moment#eod

注意: moment#endOf('week')在2.0.0版中添加了。

从版本2.1.0开始,moment#endOf('week')使用区域设置感知周开始日。

参考资料

Last updated