Moment.js中文文档系列之一安装使用与日期时间解析

 2015年10月13日    17810     声明


Moment.js是一个JavaScript的日期、时间处理工具类,其对于JavaScript的日期时间处理功能非常强悍和全面。可以用在浏览器环境中使用,也可以在Node.js中。在IE8以上及其它浏览器的最新版本中都可以使用,具有良好的跨浏览器及跨系统的兼容性。本篇主要介绍Moment.js的安装使用与Moment.js日期时间解析功能。

  1. Moment.js的安装使用
  2. 使用Moment.js解析日期时间


1. Moment.js的安装使用

Moment.js支持的安装方式非常多,你可以在Node.js中通过npm命令安装、可以浏览器中直接引用、可以通过包管理工具Bower安装使用、也可以在Require.js中配置使用……

1.1 在Node.js中安装使用

Node.js中通过npm安装后,require引用即可。

npm install moment
var moment = require('moment');
moment().format();


1.2 在浏览器中使用

Node.js中通过npm安装后,require引用即可。

<script src="moment.js"></script>
<script>
    moment().format();
</script>


1.3 通过Bower安装

Bower是一个前端包管理工具,通过Bower可以方便的安装管理Moment.js

bower install --save moment


1.4 在Require.js中使用

Require.js中,你可以将Moment.js配置为一个全局对象:

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

也可以按非全局的方式配置:

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


除上述应该环境外,Moment.js还可以在NuGetspmmeteor等环境中使用。


2. 使用Moment.js解析日期时间

Moment.js对Date对象的扩展不是使用Date.prototype的方式,页是对Date对象创建一个包装对象。通过moment()方法可以获取这个包装对象,并且可以在调用时传入一个支持的输入参数。

Moment的原型方法通过moment.fn的方式暴露,你也可以通过这种方式添加自己的需要的方法。


2.1 初始化为当前时间

moment();

获取当前日期时间,使用moment()方法即可,无需传入任何参数:

var now = moment();

上面的方法等价于moment(new Date())


2.2 使用一个String参数进行初始化

moment()方法可以通过一个字符串参数,初始化时间,使用格式如下:

moment(String);

传入一个字符串参数时,moment()会首先按ISO 8601进行格式匹配,之后会调用new Date(string)构造函数

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

注意浏览器端支持的格式化类型比较有限,详细参考:date-formats。使用非ISO 8601格式进行初始化,可以使用String + Format参数的形式


支持的ISO 8601字符串

ISO 8601字符串必须要有一个日期部分:

2013-02-08  # 日历日期形式
2013-W06-5  # 周日期
2013-039    # 日期序列t

时间部分也可以包含在格式化字符串中:

2013-02-08T09            # 通过T分隔时间部分
2013-02-08 09            # 通过空格分隔时间部分
2013-02-08 09:30         # 同时设置时和分钟
2013-02-08 09:30:26      # 同时设置时、分、秒
2013-02-08 09:30:26.123  # 同时设置时、分、秒、毫秒
2013-02-08 24:00:00.000  # 设置小时24,分、秒、毫秒为0

所有设置日期的格式都可以同时设置时间:

2013-02-08 09
2013-W06-5 09
2013-039 09t

设置时间部分时,可以同时包含和UTC时间的时差,像+-HH:mm+-HHmmZ

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

设置初始化字符串参数后,可以通过isValid()方法检测设置格式是否正确:

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


2.3 使用String + Format参数进行初始化

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

如果已知输入的字符串字符串的格式,你可以这样将其转为一个Moment对象:

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

以下两种设置形式会返回相同的值,因为转换器会忽略非文数字:

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


年、月、日,标识符

输入 示例 说明
YYYY 2014 4或2位年
YY 14 2位年r
Q 1..4 季度。设置每季度的第一个月
M MM 1..12 表示月的数字
MMM MMMM Jan..December 月份名
D DD 1..31 每月的第几天
Do 1st..31st 每月的第几天的序数
DDD DDDD 1..365 每年的第几天
X 1410715640.579 Unix时间戳
x 1410715640579 Unix时间戳(毫秒级)


周年、周、周日,标识符

输入 示例 说明
gggg 2014 本地 4位周年
gg 14 本地 2位周年
w ww 1..53 本地 年中第几周
e 1..7 本地 一周中的第几天
ddd dddd Mon...Sunday 本地星期名
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 上午和下午
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+-HHmmZ表示


如果不显式的标明时区,那么设置的将是本地时间:

moment("2010-10-20 4:30",       "YYYY-MM-DD HH:mm");   // 本地时间 4:30
moment("2010-10-20 4:30 +0000", "YYYY-MM-DD HH:mm Z"); // UTC时间 4:30

如果设置的时间为非法时间,使用isValid()方法验证,将返回false:

moment("2010 13",           "YYYY MM").isValid();     // false (不存在的月)
moment("2010 11 31",        "YYYY MM DD").isValid();  // false (不存在的天)
moment("2010 2 29",         "YYYY MM DD").isValid();  // false (不是润年)
moment("2010 notamonth 29", "YYYY MMM DD").isValid(); // false (不存在的月名)

2.0.0版后,你要可以通过moment()方法的第三个参数或moment.utc()方法将其设置为UTC时间:

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


2.4 使用String + Formats参数进行初始化

moment(String, String[], String, Boolean);

String + Format类似,String + Formats会在已知输入日期字符串的情况在,在指定1到多种格式之间进行匹配。

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

当你指定的多个匹配格式时,Moment会按以下顺序匹配:

  • 优先使用匹配较多的格式
  • 匹配度相同时,优先使用最先匹配到的格式
moment("29-06-1995", ["MM-DD-YYYY", "DD-MM", "DD-MM-YYYY"]); // 使用最后一个格式
moment("05-06-1995", ["MM-DD-YYYY", "DD-MM-YYYY"]);          // 使用第一个格式

初始化时,可能也会指定本地时间和严格匹配参数:

moment("29-06-1995", ["MM-DD-YYYY", "DD-MM-YYYY"], 'fr');       // 指定 'fr' 本地时间
moment("29-06-1995", ["MM-DD-YYYY", "DD-MM-YYYY"], true);       // 指定严格匹配模式
moment("05-06-1995", ["MM-DD-YYYY", "DD-MM-YYYY"], 'fr', true); // 指定 'fr' 本地时间和严格匹配模式


2.5 使用Special Formats特殊字符串进行初始化

moment(String, moment.CUSTOM_FORMAT, [String], [Boolean]);
moment(String, [..., moment.ISO_8601, ...], [String], [Boolean]);

在指定格式化参数时,可以指定一个表示匹配格式的Moment枚举常量。Moment支持ISO-8601标准的时间格式,指定moment.ISO_8601后,Moment就会按ISO-8601标准格式进行时间初始化。

moment("2010-01-01T05:06:07", moment.ISO_8601);
moment("2010-01-01T05:06:07", ["YYYY", moment.ISO_8601]);


2.6 使用Object对象进行初始化

moment({unit: value, ...});

你可以使用表示时间单位的对象来创建Moment,如下:

moment({ hour:15, minute:10 });
moment({ y    :2010, M     :3, d   :5, h    :15, m      :10, s      :3, ms          :123});
moment({ year :2010, month :3, day :5, hour :15, minute :10, second :3, millisecond :123});
moment({ years:2010, months:3, days:5, hours:15, minutes:10, seconds:3, milliseconds:123});
moment({ years:2010, months:3, date:5, hours:15, minutes:10, seconds:3, milliseconds:123});


2.7 使用Unix 偏移量(毫秒)进行初始化

moment(Number);

Moment支持使用一个表示Unix 标准时间的毫秒级的整数进行初始化(开始自:Jan 1 1970 12AM UTC),类似于new Date(Number)

moment(1318781876406);


2.8 使用Unix 时间戳(秒)进行初始化

moment.unix(Number)

Moment还支持使用 Unix时间戳(秒级 Unix 标准时间)进行初始化,这实际是调用了moment(timestamp * 1000)方法。

var day = moment.unix(1318781876);


2.9 使用JSDate对象进行初始化

moment(Date);

你可以从一个已经存在的JavaScript Date对象初始化Moment

var day = new Date(2011, 9, 16);
var dayWrapper = moment(day);


2.10 使用整数Array进行初始化

moment(Number[]);

Moment还支持从一个整数数组初始化,该方法是new Date()的镜像方法:

[year, month, day, hour, minute, second, millisecond]
moment([2010, 1, 14, 15, 25, 50, 125]); // February 14th, 3:25:50.125 PM

构造函数默认使用当前时区,如果需要UTC时间则调用moment.utc(Number[])方法:

moment.utc([2010, 1, 14, 15, 25, 50, 125]);


2.11 Moment对象复制

moment(Moment);

Moment对象可以进行复制,你可显式或隐式的调用moment()方法进行复制。

var a = moment([2012]);
var b = moment(a);
a.year(2000);
b.year(); // 2012

或显示的调用moment.clone()方法进行复制:

var a = moment([2012]);
var b = a.clone();
a.year(2000);
b.year(); // 2012


2.12 对UTC时间的支持

moment.utc();
moment.utc(Number);
moment.utc(Number[]);
moment.utc(String);
moment.utc(String, String);
moment.utc(String, String[]);
moment.utc(String, String, String);
moment.utc(Moment);
moment.utc(Date);

默认情况下,Moment使用本地时间进行转换和显示。如果要使用UTC标准时间进行转换和显示,需要使用moment.utc()方法代替moment()。这就是Moment.jsUTC模式

UTC模式下,所有显示时间的方法都会使用UTC时间代替本地时间。

moment().format();     // 2013-02-04T10:35:24-08:00
moment.utc().format(); // 2013-02-04T18:35:24+00:00

UTC模式下,所有getterssetters都会使用Date.getUTC*Date.setUTC*方法代替Date.get*Date.set*方法:

moment.utc().seconds(30) === new Date().setUTCSeconds(30);
moment.utc().seconds() === new Date().getUTCSeconds();

注意utc()方法只会在显示上使用UTC时间,二者本质上还是相同的时间。

var a = moment();
var b = moment.utc();
a.format();  // 2013-02-04T10:35:24-08:00
b.format();  // 2013-02-04T18:35:24+00:00
a.valueOf(); // 1360002924000
b.valueOf(); // 1360002924000

任何使用moment.utc()方法创建的Moment对象,将会使用UTC 模式,而使用moment()方法创建的将不会。

var a = moment.utc([2011, 0, 1, 8]);
a.hours(); // 8 UTC
a.local();
a.hours(); // 0 PST


2.13 使用parseZone转换时区

moment.parseZone(String)

Moment默认使用本地时间,或使用moment.utc()方法初始化为UTC时间。当输入的时间字符串本身包含时区信息时,需要使用parseZone()方法进行时区设置。

moment.parseZone("2013-01-01T00:00:00-13:00").zone(); // 780

moment.parseZone相当于使用moment.zone进行时区转换:

var s = "2013-01-01T00:00:00-13:00";
moment(s).zone(s);

注意:这个方法只有在一个字符串参数时使用


2.14 有效性验证

Moment使用比Date构造函数更严格的初始化规则:

new Date(2013, 25, 14).toString(); // "Sat Feb 14 2015 00:00:00 GMT-0500 (EST)"
moment([2015, 25, 35]).format();   // 'Invalid date'

你可以使用moment.isValid方法检测输入的初始化时间是否合法,该方法会返回一个表示是否有效的布尔值。如果想查看转换详细结果,可以使用moment.parsingFlags方法,该方法会返回一个包含以下值的对象:

  • overflow:是否有溢出,如:13th月、月中的第32天
  • invalidMonth:是否有效的月名
  • empty:转入的字符串是否不可转换,如:输入moment('this is nonsense');则为true
  • nullInput:是否输入了空值
  • invalidFormat:是否无效的输入格式
  • userInvalidated:是否创建成功,相当于moment.invalid()

当转换失败时,可以调用moment#invalidAt方法,查看失败位置:

var m = moment("2011-10-10T10:20:90");
m.isValid(); // false
m.invalidAt(); // 5 表示秒出错

返回值含义如下:

  • 0. 年
  • 1. 月
  • 2. 天
  • 3. 时
  • 4. 分
  • 5. 秒
  • 6. 毫秒


2.15 使用默认值

moment("15", "hh")

创建Moment时,可以只指定一些时间单位,其它的会使用当前时间的日、时、分、秒等。

使用当前时间

moment();  // current date and time

还可以这样使用

moment(5, "HH");  // today, 5:00:00.000
moment({hour: 5});  // today, 5:00:00.000
moment({hour: 5, minute: 10});  // today, 5:10.00.000
moment({hour: 5, minute: 10, seconds: 20});  // today, 5:10.20.000
moment({hour: 5, minute: 10, seconds: 20, milliseconds: 300});  // today, 5:10.20.300

或这样使用

moment(5, "DD");  // 本月的第5天
moment("4 05:06:07", "DD hh:mm:ss");  // 本月的第4天, 05:06:07.000

或这样使用

moment(3, "MM");  // 今年的第4个月 (April)
moment("Apr 4 05:06:07", "MMM DD hh:mm:ss");  // 今年4月的第5天, 05:06:07.000