Moment.js 文档

Moment 被设计为在浏览器和 Node.js 中都能工作。

所有的代码都应该在这两种环境中都可以工作,并且所有的单元测试都应该在这两种环境中运行。

CI 系统当前使用以下的浏览器:Windows XP 上的 Chrome,Windows 7 上的 IE 8、9 和 10,Windows 10 上的 IE 11,Linux 上最新的 Firefox,OSX 10.8 和 10.11 上最新的 Safari。

如果您想尝试以下的示例代码,则只需打开浏览器的控制台并输入即可。

Node.js

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

注意:在 2.4.0 中,全局的 moment 对象已被废弃。 它将会在下一个主版本中被删除。

浏览器

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

Moment.js 在 cdnjs.comjsDelivr 上可用。

Bower

bower

bower install --save moment

值得注意的文件是 moment.jslocale/*.jsmin/moment-with-locales.js

Require.js

如果你打算将 moment 与 Require.js 结合使用,则强烈建议你阅读此内容。 另外,请升级到 2.14.0 或更高版本以获得最佳体验。

首先,你可能需要通过 bower 或 node_modules 或其他方式将 moment.js 以及语言环境目录放置在基层文件夹中来获取 moment。 然后,你可以使用 adapt-pkg-main 之类的工具、或者手动使用包配置

requirejs.config({
  packages: [{
    name: 'moment',
    // 此位置是相对于 baseUrl 的。 
    // 选择 bower_components 还是 node_modules 取决于具体的安装方式。
    location: '[bower_components|node_modules]/moment'
    main: 'moment'
  }]
});

通过上述的设置,你可以使用 moment 引入核心模块、使用 moment/locale/de 引入 de 语言环境。

// 只需要核心模块。
define(['moment'], function (moment) {
    console.log(moment().format('LLLL'));  // 'Friday, June 24, 2016 1:42 AM'
});

// 具有单一语言环境的核心模块。
define(['moment', 'moment/locale/de'], function (moment) {
    moment.locale('de');
    console.log(moment().format('LLLL')); // 'Freitag, 24. Juni 2016 01:42'
});

// 具有所有语言环境的核心模块。
define(['moment/min/moment-with-locales'], function (moment) {
    moment.locale('de');
    console.log(moment().format('LLLL')); // 'Freitag, 24. Juni 2016 01:42'
});

// 异步加载语言环境。
define(['require', 'moment'], function(require, moment) {
  // 检测到语言环境之后,在某个模块内部。 
  // 这是在模块加载时间之前不知道语言环境的情况。
  require(['moment/locale/de'], function(localeModule) {
    // 此处已加载语言环境,但尚未使用。
    console.log(moment().format('LLLL'));  // 'Friday, June 24, 2016 1:42 AM'

    moment.locale('de');
    // 已经正确地设置了语言环境之后使用 moment。
    console.log(moment().format('LLLL')); // 'Freitag, 24. Juni 2016 01:42'
  })
});

对于更复杂的用例,请阅读 @jrburke 的出色解释

Moment 仍将会创建全局的 moment,这对于插件和其他第三方代码很有用。 如果需要制止该全局变量,则在模块配置上使用 noGlobal 选项。

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

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

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

为了使 moment.js 插件可以在 requirejs 环境中被加载,moment 会被创建为一个命名模块。 因此,必须使用 paths 来确定目录,将 moment 完全按 "moment" 加载。 使用 "vendor\moment" 之类的路径引入 moment 将会返回 undefined

2.9.0 版本开始,moment 会将自身导出为匿名模块,因此,如果仅使用核心模块(不使用语言环境或插件),则将其放置在非标准位置时不需要配置。

Browserify

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

注意,有一个 bug 会导致无法加载 moment.locale

var moment = require('moment');
moment.locale('cs');
console.log(moment.locale()); // en

使用下面的解决方法。

var moment = require('moment');
require('moment/locale/cs');
console.log(moment.locale()); // cs

为了包含所有的语言环境。

var moment = require('moment');
require("moment/min/locales.min");
moment.locale('cs');
console.log(moment.locale()); // cs

Webpack

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

默认情况下,webpack 会打包所有的 Moment.js 语言环境(在 Moment.js 2.18.1 中,最小为 160 KB)。 若要剥离不必要的语言环境且仅打包使用的语言环境,则添加 moment-locales-webpack-plugin

// webpack.config.js
const MomentLocalesPlugin = require('moment-locales-webpack-plugin');

module.exports = {
    plugins: [
        // 剥离除 “en” 以外的所有语言环境。
        new MomentLocalesPlugin(),

        // 或者:剥离除 “en”、“es-us” 和 “ru” 以外的所有语言环境。
        //(“en” 内置于 Moment 中,无法移除)
        new MomentLocalesPlugin({
            localesToKeep: ['es-us', 'ru'],
        }),
    ],
};

还有其他资源可以使用 webpack 优化 Moment.js,例如该资源

Typescript 2.13.0+

2.13.0 版本开始,Moment 会包含一个 typescript 定义文件。

通过NPM安装。

npm install moment

导入并在你的 Typescript 文件中使用。

import * as moment from 'moment';

let now = moment().format('LLLL');

如果你在导入时遇到麻烦。

对于 Typescript 2.x,则尝试在 tsconfig.json 文件中的 compileOptions 中添加 "moduleResolution": "node",然后使用以下任何语法:

import * as moment from 'moment';
import moment = require('moment');

对于 Typescript 1.x,则尝试在 tsconfig.json 文件中的 compileOptions 中添加 "allowSyntheticDefaultImports": true,然后使用语法:

import moment from 'moment';

语言环境导入

若要使用 moment.locale,则首先需要导入要使用的语言。

import * as moment from 'moment';
import 'moment/locale/pt-br';

console.log(moment.locale()); // en
moment.locale('fr');
console.log(moment.locale()); // en
moment.locale('pt-BR');
console.log(moment.locale()); // pt-BR

System.js

若要加载 moment,则将其放置在 baseURL 配置中的 System.config 指定的路径中。 然后将其导入页面。

<script src="system.js"></script>
<script>
  System.config({
    baseURL: '/app'
  });

  System.import('moment.js');
 </script>

如果需要将 moment 加载为全局变量,则可以使用元配置:

System.config({
  meta: {
    'moment': { format: 'global' }
  }
});

另外,若要将 Moment 作为全局仅提供给特定的依赖项,则可以如下操作:

System.config({
  meta: {
    'path/to/global-file.js': {
      globals: {
        moment: 'moment'
      }
    }
  }
});

疑难杂症

如果你有任何麻烦,则首先查看指南

如果找不到你要找的东西,则尝试使用 momentjs 标签在 Stack Overflow 上提问。

注意:这篇博客文章可以解答 Stack Overflow 上超过一半的问题。

你还可以使用 GitHub 问题跟踪器查找相关问题或发起新的问题。

此外,Moment 有一个 Gitter,内部团队经常使用。

对于一般的故障排除帮助,首选 Stack Overflow。 Moment 的维护者与其他一些博学的用户一样,在 Stack Overflow 上非常活跃。 最快的响应将会在那里。

Moment.js 会为 Date 对象创建封装器,而不是修改本地的 Date.prototype。 若要获取此封装器对象,则只需使用一种受支持的输入类型调用 moment() 即可。

Moment 原型通过 moment.fn 公开。 如果要添加自己的函数,则可以在其中放置它们。

为了便于参考,Moment.prototype 上的任何方法都将会在文档中称为 moment#method。 因此 Moment.prototype.format == moment.fn.format == moment#format

请阅读:

  • moment(...) 是本地模式。不明确的输入(无偏移量)会被假定为本地时间。明确的输入(带偏移量)会被调整为本地时间。
  • moment.utc(...) 是 utc 模式。不明确的输入会被假定为 UTC。明确的输入会被调整为 UTC。
  • moment.parseZone() 会保持输入的区域被传入。如果输入不明确,则与本地模式相同。
  • moment.tz(...) 使用 moment-timezone 插件可以以特定的时区来解析输入。

记住,时区和时区偏移是两件事。 -08:00 的偏移量不一定意味着你处于美国太平洋时区。

有关其他信息,参见解析指南

moment() 1.0.0+

moment();
moment(undefined);
// 从 2.14.0 开始,也受支持。
moment([]);
moment({});

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

var now = moment();

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

2.14.0 版本开始,moment([])moment({}) 也返回当前时间。 在 2.14.0 之前,它们默认为今天开始,但这是随意的,因此已更改。

函数参数在未传入时默认为 undefined。 Moment 会将 moment(undefined) 视作 moment()

var x = undefined;
moment(x).isSame(moment(), 'second'); // true

moment(String) 1.0.0+

moment(String);

当从字符串创建 moment 时,需要首先检查字符串是否与已知的 ISO 8601 格式匹配,如果未找到已知的格式,则在降维到 new Date(string) 之前检查字符串是否与 RFC 2822 日期时间格式匹配。

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

注意,浏览器对于解析字符串的支持是不一致的。 因为没有关于应该支持哪种格式的规范,所以在某些浏览器中有效的格式在其他浏览器中可能无效。

为了在解析 ISO 8601 以外的字符串时获得一致的结果,应使用字符串 + 格式

支持的 ISO 8601 字符串

ISO 8601 字符串需要日期片段。

2013-02-08  # 日历日期片段。
2013-W06-5  # 星期日期片段。
2013-039    # 序数日期片段。

20130208    # 基本的完整日期(短)。
2013W065    # 基本的星期、工作日(短)。
2013W06     # 仅基本的星期(短)。
2013050     # 基本的序数日期(短)。

还可以包括时间片段,与日期片段之间使用空格或大写字母 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 表示第二天午夜。

20130208T080910,123      # 短的日期和时间,精确到毫秒,以逗号分隔。
20130208T080910.123      # 短的日期和时间,精确到毫秒。
20130208T080910          # 短的日期和时间,精确到秒钟。
20130208T0809            # 短的日期和时间,精确到分钟。
20130208T08              # 短的日期和时间,仅有小时。

任何的日期片段都可以有时间片段。

2013-02-08 09  # 日历日期片段和小时时间片段。
2013-W06-5 09  # 星期日期片段和小时时间片段。
2013-039 09    # 序数日期片段和小时时间片段。

如果包含时间片段,则还可以将 UTC 的偏移量包含为 +-HH:mm+-HHmm+-HHZ

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
2013-02-08 09:30:26.123+07     # +-HH

注意:在版本 2.3.0 中添加了对星期和序数格式的支持。

如果字符串与以上任何格式都不匹配,并且无法使用 Date.parse 进行解析,则 moment#isValid 将会返回 false。

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

RFC 2822 日期时间格式

在解析 RFC 2822 日期时间之前,将会清理字符串以删除所有的注释和换行符。 其他的字符虽然在格式上合法,但对创建有效的 moment 实例没有任何作用。

清理之后,该字符串会在以下使用空格分隔的部分中进行验证,全部使用英语:

6 Mar 17 21:22 UT
6 Mar 17 21:22:23 UT
6 Mar 2017 21:22:23 GMT
06 Mar 2017 21:22:23 Z
Mon 06 Mar 2017 21:22:23 z
Mon, 06 Mar 2017 21:22:23 +0000
  1. 星期几(三个字母),后面跟随一个可选的逗号。(可选的)
  2. 月份中的某天(1 或 2 位数字),后面跟随三个字母的月份和 2 或 4 位数字的年份。
  3. 两位数字的小时和分钟,以冒号(:)分隔,后面可选地跟随另一个冒号和 2 位数字的秒钟。
  4. 时区或偏移量采用以下格式之一:
  5. UT : +0000
  6. GMT : +0000
  7. EST | CST | MST | PST | EDT | CDT | MDT | PDT : 美国时区*
  8. A - I | K - Z : 军事时区*
  9. 时间偏移 +/-9999

[*] 有关详细信息,参阅规范的 4.3 章节

解析器还会确认星期(当包含时)与日期一致。

moment(String) 带格式 1.0.0+

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");

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

年份、月份、日期的令牌

令牌区分大小写。

输入示例描述
YYYY20144 或 2 位数字的年份
YY142 位数字的年份
Y-25带有任意数字和符号的年份
Q1..4年份的季度。将月份设置为季度的第一个月
M MM1..12月份数字
MMM MMMMJan..December语言环境中的月份名称,由 moment.locale() 设置
D DD1..31月的某天
Do1st..31st月的某天,带序数
DDD DDDD1..365年的某天
X1410715640.579Unix 时间戳
x1410715640579Unix 毫秒时间戳

从版本 2.10.5 开始,YYYY 支持 2 位数字的年份,且会将其转换为接近 2000 的年份(与 YY 相同)。

Y 新增于 2.11.1 中。 它将会匹配任何数字,有符号或无符号。 对于非 4 位数字或公元前的年份很有用。 它可以用于任何年份。

周年、星期、工作日的令牌

对于这些,小写字母令牌使用语言环境感知的星期开始天数,而大写字母令牌使用 ISO 星期日期开始天数。

令牌区分大小写。

输入示例描述
gggg2014语言环境的 4 位数字的周年
gg14语言环境的 2 位数字的周年
w ww1..53语言环境的年的第几周
e0..6语言环境的星期几
ddd ddddMon...Sunday语言环境的星期几的名称,由 moment.locale() 设置
GGGG2014ISO 的 4 位数字的周年
GG14ISO 的 2 位数字的周年
W WW1..53ISO 的年的第几周
E1..7ISO 的星期几

语言环境感知的格式

使用 LT LTS L LL LLL LLLL 也可以使用语言环境感知的日期和时间格式。 它们新增于 2.2.1 版本,其中 LTS 新增于 2.8.4

令牌区分大小写。

输入示例描述
L04/09/1986日期(以本地格式)
LLSeptember 4 1986月份名称、月份日期、年份
LLLSeptember 4 1986 8:30 PM月份名称、月份日期、年份、时间
LLLLThursday, September 4 1986 8:30 PM星期几、月份名称、月份日期、年份、时间
LT08:30 PM时间(不含秒钟)
LTS08:30:00 PM时间(含秒钟)

小时、分钟、秒种、毫秒、偏移量的令牌

令牌区分大小写。

输入示例描述
H HH0..23小时(24 小时制)
h hh1..12小时(使用 a A 的 12 小时制)
k kk1..24小时(从 1 到 24 的 24 小时制)
a Aam pm上午或下午(单一字符 a p 也被视为有效)
m mm0..59分钟
s ss0..59秒钟
S SS SSS0..999带分数的秒钟
Z ZZ+12:00从 UTC 偏移为 +-HH:mm+-HHmmZ

2.10.5 版本开始:长度为 4 到 9 位的带分数的秒钟令牌可以解析任意数量的数字,但只会考虑前 3 个数(毫秒)。 如果需要打印带有多位分数且想要消耗输入的时间,则使用它。

注意,仅在严格模式中解析时,提供的 S 字符的数量才有意义。 在标准模式中,SSSSSSSSSS 均等效,并解释为几分之一秒。 例如,.12 始终为 120 毫秒,传入 SS 不会导致其被解释为 12 毫秒。

Z ZZ 新增于 1.2.0 版本。

S SS SSS 新增于 1.6.0 版本。

X 新增于 2.0.0 版本。

k kk 新增于 2.18.0 版本。

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

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。

如果 moment 解析的输入结果不存在,则 moment#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()

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

Moment 的解析器非常宽松,这可能会导致不期望或意外的行为。

例如,可以观察到以下行为:

moment('2016 is a date', 'YYYY-MM-DD').isValid() //true, 2016 被匹配。

2.13.0 之前,解析器会表现出以下行为。 这已得到纠正。

moment('I am spartacus', 'h:hh A').isValid();     //true - 'am' 和 'A' 标志匹配。

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.05.25',       'YYYY-MM-DD', true).isValid(); // false

可以同时使用语言环境和严格性。

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

严格的解析通常是最好的解析选项。 有关选择严格还是宽松解析的更多信息,参阅解析指南

解析两位数字的年份

默认情况下,68 之前的两位数字的年份会被假定是 1900 年代,而 68 或之后的年份则会被假定是 2000 年代。 可以通过替换 moment.parseTwoDigitYear 方法来更改。 该方法的唯一参数是包含用户输入的两位年份的字符串,并且应以整数形式返回年份。

moment.parseTwoDigitYear = function(yearString) {
    return parseInt(yearString) + 2000;
}

解析胶合的小时和分钟

2.11.0 版本开始,支持解析 hmmHmmhmmssHmmss

moment("123", "hmm").format("HH:mm") === "01:23"
moment("1234", "hmm").format("HH:mm") === "12:34"

moment(String) 多个格式 1.0.0+

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

如果不知道输入字符串的确切格式,但是知道它可能是多种格式之一,则可以使用格式数组。

这与字符串 + 格式相同,只是它将会尝试将输入匹配为多种格式。

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

2.3.0 版本开始,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' 语言环境和严格的解析。

注意:解析多种格式比解析单一格式要慢得多。 如果可以避免,则解析单一格式要快得多。

moment(String) 特殊格式 2.7.0+

moment(String, moment.CUSTOM_FORMAT, [String], [Boolean]);
moment(String, moment.HTML_FMT.DATETIME_LOCAL, [String], [Boolean]); // 从 2.20.0 开始。
moment(String, [..., moment.ISO_8601, ...], [String], [Boolean]);

ISO-8601 是时间和时长显示的标准。 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.20.0 版本开始,可以使用以下 HTML5 格式:

常量格式示例输入类型
moment.HTML5_FMT.DATETIME_LOCALYYYY-MM-DDTHH:mm2017-12-14T16:34<input type="datetime-local" />
moment.HTML5_FMT.DATETIME_LOCAL_SECONDSYYYY-MM-DDTHH:mm:ss2017-12-14T16:34:10<input type="datetime-local" step="1" />
moment.HTML5_FMT.DATETIME_LOCAL_MSYYYY-MM-DDTHH:mm:ss.SSS2017-12-14T16:34:10.234<input type="datetime-local" step="0.001" />
moment.HTML5_FMT.DATEYYYY-MM-DD2017-12-14<input type="date" />
moment.HTML5_FMT.TIMEHH:mm16:34<input type="time" />
moment.HTML5_FMT.TIME_SECONDSHH:mm:ss16:34:10<input type="time" step="1" />
moment.HTML5_FMT.TIME_MSHH:mm:ss.SSS16:34:10.234<input type="time" step="0.001" />
moment.HTML5_FMT.WEEKYYYY-[W]WW2017-W50<input type="week" />
moment.HTML5_FMT.MONTHYYYY-MM2017-12<input type="month" />

moment(Object) 2.2.1+

moment({unit: value, ...});
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});
moment({ years:'2010', months:'3', date:'5', hours:'15', minutes:'10', seconds:'3', milliseconds:'123'});  // 从 2.11.0 开始。

可以通过指定对象中的某些单位来创建 moment。

省略的单位默认为 0 或当前的日期、月份和年份。

daydate 键均表示月份的某天。

date 新增于 2.8.4

2.11.0 版本开始,支持字符串值(如最后一行示例所示)。

注意,像 moment(Array)new Date(year, month, date) 一样,月份从 0 开始索引。

unix() 1.6.0+

moment.unix(Number)

若要从 Unix 时间戳(自 Unix 纪元以来的秒数)创建 moment,则使用 moment.unix(Number)

var day = moment.unix(1318781876);

这实现为 moment(timestamp * 1000),因此在输入时间戳中包含了部分秒数。

var day = moment.unix(1318781876.721);

注意:尽管 Unix 时间戳是基于 UTC 的,但是此函数在本地模式中创建了 moment 对象。 如果需要 UTC,则可以随后调用 .utc(),如下所示:

var day = moment.unix(1318781876).utc();

moment(Date) 1.0.0+

moment(Date);

可以使用预先存在的原生 Javascript Date 对象来创建 Moment

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

这会克隆 Date 对象,Date 的后续更改不会影响 Moment,反之亦然。

moment(Number[]) 1.0.0+

moment(Number[]);

可以使用数值的数组(映射传给 new Date() 的参数)来创建 moment。

[year, month, day, hour, minute, second, millisecond]

moment([2010, 1, 14, 15, 25, 50, 125]); // February 14th, 3:25:50.125 PM

年份之后的任何值都是可选的,并且默认为可能的最小值。

moment([2010]);        // January 1st
moment([2010, 6]);     // July 1st
moment([2010, 6, 10]); // July 10th

使用数组的构造将会在当前时区中创建一个日期。 若要从 UTC 数组创建日期,则使用 moment.utc(Number[])

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

注意:因为这映射了原生的 Date 参数,所以月份,小时,分钟,秒钟、毫秒都是零索引的。 年份、月份的日期则是 1 索引的。

这通常是混乱的原因,尤其是月份,因此请注意!

如果数组代表的日期不存在,则 moment#isValid 将会返回 false。

moment([2010, 12]).isValid();     // false(不是真实的月份)
moment([2010, 10, 31]).isValid(); // false(不是真实的日期)
moment([2010, 1, 29]).isValid();  // false(不是闰年)

moment(JSONDate) 1.3.0+

moment(String);

默认情况下,Microsoft Web API 会以正确的 ISO-8601 格式返回 JSON 日期,但较早的 ASP.NET 技术可能以 /Date(1198908717056)//Date(1198908717056-0700)/ 的形式返回 JSON 日期。

如果传入与此格式匹配的字符串,则它将会被正确地解析。

moment("/Date(1198908717056-0700)/"); // 2007-12-28T23:11:57.056-07:00

moment(Moment) 1.2.0+

moment(Moment);

所有的 moment 都是可变的。 如果想要克隆 moment,则可以隐式或显式地操作。

在 moment 上调用 moment() 将会克隆它。

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

此外,也可以调用 moment#clone 克隆 moment。

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

utc() 1.5.0+

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(String, String, Boolean);
moment.utc(String, String, String, Boolean);
moment.utc(Moment);
moment.utc(Date);

默认情况下,moment 会解析并以本地时间显示。

如果要解析或以 UTC 显示 moment,则可以使用 moment.utc() 而不是 moment()

这为我们带来了 Moment.js 的有趣的特性。 UTC 模式。

在 UTC 模式中,所有的显示方法都将会以 UTC 时间(而非本地时间)显示。

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

此外,在 UTC 模式中,所有的 getter 和 setter 都将会在内部使用 Date#getUTC*Date#setUTC* 方法,而不是 Date#get*Date#set* 方法。

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

重要的是要注意,尽管上面的显示有所不同,但它们在同一时间都是相同的 moment。

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() 创建的任何 moment 则不会。

若要从 UTC 切换到本地时间,则可以使用 moment#utcmoment#local

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

parseZone() 2.3.0+

moment.parseZone()
moment.parseZone(String)
moment.parseZone(String, String)
moment.parseZone(String, [String])
moment.parseZone(String, String, Boolean)
moment.parseZone(String, String, String, Boolean)

Moment 的字符串解析函数(例如 moment(string)moment.utc(string))接受偏移量的信息(如果提供),但会将生成的 Moment 对象转换为本地或 UTC 时间。 相比之下,moment.parseZone() 解析字符串,但会将生成的 Moment 对象保持在固定偏移量的时区中(使用字符串中提供的偏移量)。

moment.parseZone("2013-01-01T00:00:00-13:00").utcOffset(); // -780 (总分钟数 "-13:00")
moment.parseZone('2013 01 01 05 -13:00', 'YYYY MM DD HH ZZ').utcOffset(); // -780  (总分钟数 "-13:00")
moment.parseZone('2013-01-01-13:00', ['DD MM YYYY ZZ', 'YYYY MM DD ZZ']).utcOffset(); // -780  (总分钟数 "-13:00");

它还允许传入语言环境和严格性参数。

moment.parseZone("2013 01 01 -13:00", 'YYYY MM DD ZZ', true).utcOffset(); // -780  (总分钟数 "-13:00")
moment.parseZone("2013-01-01-13:00", 'YYYY MM DD ZZ', true).utcOffset(); // NaN (未通过严格性检查)
moment.parseZone("2013 01 01 -13:00", 'YYYY MM DD ZZ', 'fr', true).utcOffset(); // -780 (带有语言环境和严格性参数)
moment.parseZone("2013 01 01 -13:00", ['DD MM YYYY ZZ', 'YYYY MM DD ZZ'], 'fr', true).utcOffset(); // -780 (带有语言环境和严格性参数以及格式的数组)

moment.parseZone 等效于解析字符串并使用 moment#utcOffset 解析区域。

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

isValid() 1.7.0+

moment().isValid();

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 是否被视为无效的日期。 可以使用 moment#parsingFlags 查看 #isValid 使用的指标,该指标返回一个对象。

无效的日期会返回以下的解析标志:

  • overflow: 日期字段的溢出,例如第 13 个月、月份的第 32 天(或非闰年的 2 月 29 日)、年份的第 367 天等。 overflow 会包含匹配 #invalidAt(参阅下文)的无效单位的索引,-1 表示没有溢出。
  • invalidMonth: 无效的月份名称,例如 moment('Marbruary', 'MMMM');。 会包含无效的月份字符串本身或 null。
  • empty: 包含无法解析任何内容的输入字符串,例如 moment('this is nonsense');。布尔值。
  • nullInput: 输入 null,例如 moment(null);。布尔值。
  • invalidFormat: 空的格式列表,例如 moment('2013-05-25', [])。布尔值。
  • userInvalidated: 显式地创建为无效的日期,例如 moment.invalid()。布尔值。

除上述内容外,从 2.13.0 开始,meridiem 和 parsedDateParts 标志也可以一起判断日期的有效性。

  • meridiem: 表明解析的子午线(AM/PM),如果有的话。字符串。
  • parsedDateParts: 返回按降序解析的日期片段的数组,即 parsedDateParts[0] === 年份。 如果没有片段,但子午线有值,则日期无效。数组。

此外,如果在严格模式中解析 Moment,则这些标志必须为空才能使 Moment 有效:

  • unusedTokens: 在输入的字符串中找不到格式数组的子字符串。
  • unusedInput: 输入的子字符串数组与格式字符串不匹配。

注意:Moment 的有效性概念在 2.22.3 之间变得更加严格和一致。 注意:有效性在创建 moment 时确定。 修改的 moment(即 moment().hour(NaN))将会保持有效。

此外,可以使用 moment#invalidAt 来确定溢出的是哪个日期单位。

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

返回值具有以下含义:

  1. 年份
  2. 月份
  3. 日期
  4. 小时
  5. 分钟
  6. 秒钟
  7. 毫秒

注意:如果有多个错误的单位,则返回第一个单位(例如,由于日期的有效性可能取决于月份)。

无效的 Moment

如果 moment 无效,则在浮点运算中的行为类似于 NaN。

以下所有的都会生成无效的 moment:

  • invalid.add(unit, value)
  • another.add(invalid)
  • invalid.clone()
  • invalid.diff(another)
  • invalid.endOf(unit)
  • invalid.max(another)
  • another.max(invalid)
  • invalid.min(another)
  • another.min(invalid)
  • invalid.set(unit, value)
  • invalid.startOf(unit)
  • invalid.subtract(unit, value)

以下会生成 'InvalidDate' 的本地化版本:

  • invalid.format(anyFmt) 在当前语言环境中导致 'Invalid Date'
  • invalid.from(another)
  • another.from(invalid)
  • invalid.fromNow(suffix)
  • invalid.to(another)
  • another.to(invalid)
  • invalid.toNow(suffix)
  • invalid.toISOString() (在 2.18.0 之前)
  • invalid.toString()

以下会返回 false

  • invalid.isAfter(another)
  • invalid.isAfter(invalid)
  • another.isAfter(invalid)
  • invalid.isBefore(another)
  • invalid.isBefore(invalid)
  • another.isBefore(invalid)
  • invalid.isBetween(another, another)
  • invalid.isBetween(invalid, invalid)
  • invalid.isSame(another)
  • invalid.isSame(invalid)
  • another.isSame(invalid)
  • invalid.isSameOrAfter(another)
  • invalid.isSameOrAfter(invalid)
  • another.isSameOrAfter(invalid)
  • invalid.isSameOrBefore(another)
  • invalid.isSameOrBefore(invalid)
  • another.isSameOrBefore(invalid)

这些会返回具有某些结构的 nullNaN

  • invalid.get(unit) 返回 null,就像其他所有命名的 getter 一样。
  • invalid.toArray() === [NaN, NaN, NaN, NaN, NaN, NaN]
  • invalid.toObject() 的所有值都被设置为 NaN
  • invalid.toDate() 返回无效的 Date 对象。
  • invalid.toJSON() 返回 null。
  • invalid.unix() 返回 null。
  • invalid.valueOf() 返回 null。
  • invalid.toISOString() 返回 null(从 2.18.0 开始)。

creationData() 2.11.0+

moment().creationData();

创建 moment 对象之后,可以使用 creationData() 方法访问所有的输入:

moment("2013-01-02", "YYYY-MM-DD", true).creationData() === {
    input: "2013-01-02",
    format: "YYYY-MM-DD",
    locale: 语言环境对象,
    isUTC: false,
    strict: true
}

默认值 2.2.1+

moment("15", "hh")

可以创建一个 moment 对象,仅指定一些单位,其余的将会默认为当前的日期、月份、年份,小时、分钟、秒钟和毫秒默认为 0 。

当没传入任何值时,默认为现在时间:

moment();  // 当前的日期和时间。

当仅传入小时、分钟、秒钟和毫秒时,默认为今天:

moment(5, "HH");  // 今天 5:00:00.000
moment({hour: 5});  // 今天 5:00:00.000
moment({hour: 5, minute: 10});  // 今天 5:10.00.000
moment({hour: 5, minute: 10, seconds: 20});  // 今天 5:10.20.000
moment({hour: 5, minute: 10, seconds: 20, milliseconds: 300});  // 今天 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");  // 今年第三个月(三月)
moment("Apr 4 05:06:07", "MMM DD hh:mm:ss");  // 今年四月的第 4 天 05:06:07.000

Moment.js 使用重载的 getter 和 setter 方法。 此模式类似与其在 jQuery 中的使用。

不带参数调用这些方法会作为 getter,而带参数调用则会作为 setter。

这些会映射到原生 Date 对象上的相应函数。

moment().seconds(30).valueOf() === new Date().setSeconds(30);
moment().seconds()   === new Date().getSeconds();

如果处于 UTC 模式中,则它们将会映射到 UTC 的等效项。

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

为了方便起见,从 2.0.0 版本开始,单数和复数的方法名称都会存在。

注意:当作为 setter 使用时,所有这些方法在都会改变原始的 moment。

注意:从 2.19.0 开始,将 NaN 传给任何 setter 都是没有操作的。 在 2.19.0 之前,它以错误的方式使 moment 无效。

millisecond() 1.3.0+

moment().millisecond(Number);
moment().millisecond(); // 数字
moment().milliseconds(Number);
moment().milliseconds(); // 数字

获取或设置毫秒。

接受 0 到 999 之间的数字。 如果超出范围,则它将会冒泡到秒钟。

second() 1.0.0+

moment().second(Number);
moment().second(); // 数字
moment().seconds(Number);
moment().seconds(); // 数字

获取或设置秒钟。

接受 0 到 59 之间的数字。 如果超出范围,则它将会冒泡到分钟。

minute() 1.0.0+

moment().minute(Number);
moment().minute(); // 数字
moment().minutes(Number);
moment().minutes(); // 数字

获取或设置分钟。

接受 0 到 59 之间的数字。 如果超出范围,则它将会冒泡到小时。

hour() 1.0.0+

moment().hour(Number);
moment().hour(); // 数字
moment().hours(Number);
moment().hours(); // 数字

获取或设置小时。

接受 0 到 23 之间的数字。 如果超出范围,则它将会冒泡到日期。

date() 1.0.0+

moment().date(Number);
moment().date(); // 数字
moment().dates(Number);
moment().dates(); // 数字

获取或设置月份的日期。

接受 1 到 31 之间的数字。 如果超出范围,则它将会冒泡达到月份。

注意:Moment#date 是月份的日期,而 Moment#day 是星期几。

注意:如果链接多个操作以构造一个日期,则应从年份、月份、日期等依次开始。 否则,可能会得到意外的结果,例如,当 day=31 并且当前月份只有 30 天时(同样适用于原生 JavaScript Date 的操作),返回的日期将会为当前月份的 30 号(有关详情,参阅月份)。

错误:moment().date(day).month(month).year(year)

正确:moment().year(year).month(month).date(day)

2.16.0 起废弃使用 moment().dates()。 改用 moment().date()

day() 1.3.0+

moment().day(Number|String);
moment().day(); // 数字
moment().days(Number|String);
moment().days(); // 数字

获取或设置星期几。

此方法可用于设置星期几,其中星期日为 0、星期六为 6。

如果给定的值是 0 到 6,则结果的日期将会在当前(星期日至星期六)的星期。

如果超出范围,则它将会冒泡到其他星期。

moment().day(-7); // 上个星期日 (0 - 7)
moment().day(0); // 这个星期日 (0)
moment().day(7); // 下个星期日 (0 + 7)
moment().day(10); // 下个星期三 (3 + 7)
moment().day(24); // 从现在起第 3 个星期三 (3 + 7 + 7 + 7)

注意:Moment#date 是月份的日期,而 Moment#day 是星期几。

2.1.0 版开始,还支持星期名称。 这是在 moment 当前的语言环境中解析的。

moment().day("Sunday");
moment().day("Monday");

weekday() 2.1.0+

moment().weekday(Number);
moment().weekday(); // 数字

根据语言环境获取或设置星期几。

如果语言环境将星期一指定为一周的第一天,则 moment().weekday(0) 将会是星期一。 如果星期日是一周的第一天,则 moment().weekday(0) 将会是星期日。

moment#day 一样,如果超出范围,则它将会冒泡到其他星期。

// 当星期一是一周的第一天时。
moment().weekday(-7); // 上个星期一
moment().weekday(7); // 下个星期一
// 当星期日是一周的第一天时。
moment().weekday(-7); // 上个星期日
moment().weekday(7); // 下个星期日

isoWeekday() 2.1.0+

moment().isoWeekday(Number);
moment().isoWeekday(); // 数字

获取或设置 ISO 星期几,其中 1 是星期一、7 是星期日。

moment#day 一样,如果超出范围,则它将会冒泡到其他星期。

moment().isoWeekday(1); // 星期一
moment().isoWeekday(7); // 星期日

还支持星期名称。 这是在 moment 当前的语言环境中解析的。

moment().isoWeekday("Sunday");
moment().isoWeekday("Monday");

dayOfYear() 2.0.0+

moment().dayOfYear(Number);
moment().dayOfYear(); // 数字

获取或设置年份的日期。

接受 1 到 366 之间的数字。 如果超出范围,则它将会冒泡到年份。

week() 2.0.0+

moment().week(Number);
moment().week(); // 数字
moment().weeks(Number);
moment().weeks(); // 数字

获取或设置年份的星期。

由于不同的语言环境对年份中的星期的编号的定义不同,因此 Moment.js 添加了 moment#week 以获取/设置年份的本地化星期。

年份的星期取决于哪一天是星期的第一天(星期日、星期一等),以及哪一周是年份的第一周。

例如,在美国,星期日是星期的第一天。 1 月 1 日所在的星期是年份的第一周。

在法国,星期一是星期的第一天,且 1 月 4 日是年份的第一周。

moment#week 的输出将会取决于 moment 的语言环境

当设置年份的星期时,将会保留星期几。

isoWeek() 2.0.0+

moment().isoWeek(Number);
moment().isoWeek(); // 数字
moment().isoWeeks(Number);
moment().isoWeeks(); // 数字

获取或设置年份的 ISO 星期

当设置年份的星期时,将会保留星期几。

month() 1.0.0+

moment().month(Number|String);
moment().month(); // 数字
moment().months(Number|String);
moment().months(); // 数字

获取或设置月份。

接受 0 到 11 之间的数字。 如果超出范围,则它将会冒泡到年份。

注意:月份是零索引的,因此一月是月份 0。

2.1.0 版本开始,还支持月份名称。 这是在 moment 的当前语言环境中解析的。

moment().month("January");
moment().month("Feb");

2.1.0 版本之前,如果 moment 更改了月份,且新的月份没有足够的天数来保留该月份的当前日期,则它将会溢出到下个月份。

2.1.0 版本开始,已将其更改为限制在目标月份的月末。

// 2.1.0 之前
moment([2012, 0, 31]).month(1).format("YYYY-MM-DD"); // 2012-03-02
// 2.1.0 之后
moment([2012, 0, 31]).month(1).format("YYYY-MM-DD"); // 2012-02-29

2.16.0 废弃使用 moment().months()。 改用 moment().month()

quarter() 2.6.0+

moment().quarter(); // 数字
moment().quarter(Number);
moment().quarters(); // 数字
moment().quarters(Number);

获取季度(1 到 4)。

moment('2013-01-01T00:00:00.000').quarter() // 1
moment('2013-04-01T00:00:00.000').subtract(1, 'ms').quarter() // 1
moment('2013-04-01T00:00:00.000').quarter() // 2
moment('2013-07-01T00:00:00.000').subtract(1, 'ms').quarter() // 2
moment('2013-07-01T00:00:00.000').quarter() // 3
moment('2013-10-01T00:00:00.000').subtract(1, 'ms').quarter() // 3
moment('2013-10-01T00:00:00.000').quarter() // 4
moment('2014-01-01T00:00:00.000').subtract(1, 'ms').quarter() // 4

设置季度(1 到 4)。

moment('2013-01-01T00:00:00.000').quarter(2) // '2013-04-01T00:00:00.000'
moment('2013-02-05T05:06:07.000').quarter(2).format() // '2013-05-05T05:06:07-07:00'

year() 1.0.0+

moment().year(Number);
moment().year(); // 数字
moment().years(Number);
moment().years(); // 数字

获取或设置年份。

接受 -270,000 至 270,000 之间的数字。

2.6.0 废弃使用 moment().years()。 改用 moment().year()

weekYear() 2.1.0+

moment().weekYear(Number);
moment().weekYear(); // 数字

根据语言环境获取或设置周年。

因为第一周的第一天并不总是在一年的第一天,所以有时周年与月年会有所不同。

例如,在美国,包含 1 月 1 日的星期始终是第一周。 在美国,星期也从星期日开始。 如果 1 月 1 日是星期一,则 12 月 31 日与 1 月 1 日属于同一周,因此与 1 月 1 日的周年相同。 12 月 30 日则与 12 月 31 日是不同的周年。

isoWeekYear() 2.1.0+

moment().isoWeekYear(Number);
moment().isoWeekYear(); // 数字

获取或设置 ISO 周年

weeksInYear() 2.6.0+

moment().weeksInYear();

根据语言环境获取当前 moment 年份的周数。

get() 2.2.1+

moment().get('year');
moment().get('month');  // 0 至 11
moment().get('date');
moment().get('hour');
moment().get('minute');
moment().get('second');
moment().get('millisecond');

字符串 getter。 一般来说:

moment().get(unit) === moment()[unit]()

单位不区分大小写,且支持复数形式和缩写形式: year (years, y)、month (months, M)、date (dates, D)、hour (hours, h)、minute (minutes, m)、second (seconds, s)、millisecond (milliseconds, ms)。

set() 2.2.1+

moment().set(String, Int);
moment().set(Object(String, Int));

通用 setter,接受单位作为第一个参数、值作为第二个:

moment().set('year', 2013);
moment().set('month', 3);  // 四月
moment().set('date', 1);
moment().set('hour', 13);
moment().set('minute', 20);
moment().set('second', 30);
moment().set('millisecond', 123);

moment().set({'year': 2013, 'month': 3});

单位不区分大小写,且支持复数形式和缩写形式: year (years, y)、month (months, M)、date (dates, D)、hour (hours, h)、minute (minutes, m)、second (seconds, s)、millisecond (milliseconds, ms)。

对象解析新增于 2.9.0

max() 2.7.0+

moment.max(Moment[,Moment...]);
moment.max(Moment[]);

返回给定的 moment 实例的最大值(最远的未来)。

例如:

var a = moment().subtract(1, 'day');
var b = moment().add(1, 'day');
moment.max(a, b);  // b

var friends = fetchFriends(); /* [{name: 'Dan', birthday: '11.12.1977'}, {name: 'Mary', birthday: '11.12.1986'}, {name: 'Stephan', birthday: '11.01.1993'}]*/
var friendsBirthDays = friends.map(function(friend){
    return moment(friend.birthday, 'DD.MM.YYYY');
});
moment.max(friendsBirthDays);  // '11.01.1993'

不带参数的函数会返回带有当前时间的 moment 实例。

2.10.5 版本开始,如果其中一个参数是无效的 moment ,则结果为无效的 moment。

moment.max(moment(), moment.invalid()).isValid() === false
moment.max(moment.invalid(), moment()).isValid() === false
moment.max([moment(), moment.invalid()]).isValid() === false
moment.max([moment.invalid(), moment()]).isValid() === false

min() 2.7.0+

moment.min(Moment[,Moment...]);
moment.min(Moment[]);

返回给定的 moment 实例的最小值(最远的过去)。

例如:

var a = moment().subtract(1, 'day');
var b = moment().add(1, 'day');
moment.min(a, b);  // a
moment.min([a, b]); // a

不带参数的函数会返回带有当前时间的 moment 实例。

2.10.5 版本开始,如果其中一个参数是无效的 moment ,则结果为无效的 moment。

moment.min(moment(), moment.invalid()).isValid() === false
moment.min(moment.invalid(), moment()).isValid() === false
moment.min([moment(), moment.invalid()]).isValid() === false
moment.min([moment.invalid(), moment()]).isValid() === false

一旦有了 Moment,则可能需要以某些方式对其进行操作。 有很多方法可以帮助处理此需求。

Moment.js 使用流式的接口模式,也称为方法链。 这使得可以执行以下疯狂的操作。

moment().add(7, 'days').subtract(1, 'months').year(2009).hours(0).minutes(0).seconds(0);

注意:moment 是可变的。 调用任何一种操作方法都会改变原始的 moment。

如果要创建副本并对其进行操作,则应在操作 moment 之前使用 moment#clone查看有关克隆的更多信息

add() 1.0.0+

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

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

这是一个相当稳健的功能,可以为现有的 moment 增加时间。 若要增加时间,则传入要增加的时间的键、以及要增加的数量。

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'); // 链式
moment().add({days:7,months:1}); // 对象字面量

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

moment().add(1000000, 'milliseconds'); // 一百万毫秒
moment().add(360, 'days'); // 360 天

月份和年份的特殊考虑

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

moment([2010, 0, 31]);                  // 一月 31 号
moment([2010, 0, 31]).add(1, 'months'); // 二月 28 号

当增加跨越夏时制时间的时间时,还需要记住一些特殊的注意事项。 如果要增加年份、月份、周、或天,则原始的小时将始终与增加的小时匹配。

增加一个月会将指定的月数增加到日期。

moment([2010, 1, 28]);                 // 二月 28 号
moment([2010, 1, 28]).add(1, 'month'); // 三月 28 号
var m = moment(new Date(2011, 2, 12, 5, 0, 0)); // 美国夏令时开始的前一天
m.hours(); // 5
m.add(1, 'days').hours(); // 5

如果要增加小时、分钟、秒钟或毫秒,则会假设期望精确到小时,这将会导致不同的小时。

var m = moment(new Date(2011, 2, 12, 5, 0, 0)); // 美国夏令时开始的前一天
m.hours(); // 5
m.add(24, 'hours').hours(); // 6(但可能需要先设置时区)

另外,可以使用时长来增加时间。

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

2.8.0 版本之前,还支持 moment#add(String, Number) 语法。 不推荐使用它,而使用 moment#add(Number, String)

moment().add('seconds', 1); // 废弃于 2.8.0
moment().add(1, 'seconds');

2.12.0 版本开始,当为日期和月份传入小数时,它们会被四舍五入到最接近的整数。 星期、季度、年份会被转换到日期或月份,然后四舍五入到最接近的整数。

moment().add(1.5, 'months') == moment().add(2, 'months')
moment().add(.7, 'years') == moment().add(8, 'months') //.7*12 = 8.4,取整到 8

subtract() 1.0.0+

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

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

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

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

2.8.0 版本之前,还支持 moment#subtract(String, Number) 语法。 不推荐使用它,而使用 moment#subtract(Number, String)

moment().subtract('seconds', 1); // 废弃于 2.8.0
moment().subtract(1, 'seconds');

2.12.0 版本开始,当为日期和月份传入小数时,它们会被四舍五入到最接近的整数。 星期、季度、年份会被转换到日期或月份,然后四舍五入到最接近的整数。

moment().subtract(1.5, 'months') == moment().subtract(2, 'months')
moment().subtract(.7, 'years') == moment().subtract(8, 'months') //.7*12 = 8.4,取整到 8

注意,为了使操作 moment.add(-.5, 'days')moment.subtract(.5, 'days') 等价,-。5、-1.5、-2.5 等都向下舍入。

startOf() 1.7.0+

moment().startOf(String);

通过将原始的 moment 设置为时间单位的开头来对其进行更改。

moment().startOf('year');    // 设置为今年一月1日上午 12:00
moment().startOf('month');   // 设置为本月1日上午 12:00
moment().startOf('quarter');  // 设置为当前季度的开始,即每月的第一天上午 12:00
moment().startOf('week');    // 设置为本周的第一天上午 12:00
moment().startOf('isoWeek'); // 根据 ISO 8601 设置为本周的第一天上午 12:00
moment().startOf('day');     // 设置为今天上午 12:00
moment().startOf('date');     // 设置为今天上午 12:00
moment().startOf('hour');    // 设置为当前时间,但是 0 分钟、0 秒钟、0 毫秒
moment().startOf('minute');  // 设置为当前时间,但是 0 秒钟、0 毫秒
moment().startOf('second');  // 与 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 版本。

注意:moment#startOf('date') 作为 day 的别名新增于 2.13.0

endOf() 1.7.0+

moment().endOf(String);

通过将原始的 moment 设置为时间单位的末尾来对其进行更改。

这与 moment#startOf 相同,只是将其设置为时间单位的末尾,而不是设置为时间单位的开头。

moment().endOf("year"); // 将 moment 设置为今年的 12 月 31 日 23:59:59.999

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

注意:moment#endOf('week') 新增于 2.0.0 版本。

2.1.0 版本开始,moment#endOf('week') 使用语言环境敏感的星期开始日期。

max() 新增于 2.1.0,废弃于 2.7.0

moment().max(Moment|String|Number|Date|Array);

Note: This function has been deprecated in 2.7.0. Consider moment.min instead.


Limits the moment to a maximum of another moment value. So a.max(b) is the same as a = moment.min(a, b) (note that max is converted to min).

Sometimes, server clocks are not quite in sync with client clocks. This ends up displaying humanized strings such as "in a few seconds" rather than "a few seconds ago". You can prevent that with moment#max():

This is the counterpart for moment#min.

var momentFromServer = moment(input);
var clampedMoment = momentFromServer.max();

You can pass anything to moment#max that you would pass to moment().

moment().max(moment().add(1, 'd'));
moment().max("2013-04-20T20:00:00+0800");
moment().max("Jan 1 2001", "MMM D YYYY");
moment().max(new Date(2012, 1, 8));

min() 新增于 2.1.0,废弃于 2.7.0

moment().min(Moment|String|Number|Date|Array);

Note: This function has been deprecated in 2.7.0. Consider moment.max instead.


Limits the moment to a minimum of another moment value. So a.min(b) is the same as a = moment.max(a, b) (note that min is converted to max).

This is the counterpart for moment#max.

moment().min("2013-04-20T20:00:00+0800");

This can be used in conjunction with moment#max to clamp a moment to a range.

var start  = moment().startOf('week');
var end    = moment().endOf('week');
var actual = moment().min(start).max(end);

local() 1.5.0+

moment().local();

在原始的 moment 上设置标记,以使用本地时间(而不是原始的 moment 时间)显示 moment。

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

也可以用于转换出固定的偏移模式:

moment.parseZone('2016-05-03T22:15:01+02:00').local().format(); // "2016-05-03T15:15:01-05:00"

有关 UTC 模式的更多信息,参阅 moment.utc()

utc() 1.5.0+

moment().utc();

在原始的 moment 上设置标记,以使用 UTC(而不是原始的 moment 时间)显示 moment。

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

也可以用于转换出固定的偏移模式:

moment.parseZone('2016-05-03T22:15:01+02:00').utc().format(); //"2016-05-03T20:15:01Z"

有关 UTC 模式的更多信息,参阅 moment.utc()

utcOffset() 2.9.0++

moment().utcOffset();
moment().utcOffset(Number|String);
moment().utcOffset(Number|String, Boolean);

获取 UTC 偏移量(以分钟为单位)。

注意:与 moment.fn.zone 不同,此函数返回 UTC 的实际偏移量,而不是反向偏移量(类似 Date.prototype.getTimezoneOffset 返回的)。

获取当前对象的 utcOffset

moment().utcOffset(); // (-240、-120、-60、0、60、120、240 等)

通过提供分钟数来设置 UTC 偏移量。 在调用 utcOffset() 的 moment 对象上设置偏移量。 如果想要全局地设置偏移量,则尝试使用 moment-timezone。 注意,一旦设置了偏移量,则它便会固定且不会单独更改(即没有 DST 规则)。 如果想要一个实际的时区(特定位置的时间),例如 America/Los_Angeles,则考虑使用 moment-timezone

moment().utcOffset(120);

如果输入小于 16 且大于 -16,则会将输入解释为小时。

// 这些是等效的。
moment().utcOffset(8);  // 设置小时偏移
moment().utcOffset(480);  // 设置分钟偏移 (8 * 60)

也可以设置字符串的 UTC 偏移量。

// 这些是等效的。
moment().utcOffset("+08:00");
moment().utcOffset(8);
moment().utcOffset(480);

moment#utcOffset 会在字符串中搜索 +00:00 +0000 -00:00 -0000 Z 的第一个匹配项,因此甚至可以传入 ISO8601 格式的字符串,且 moment 将会更改为 UTC 偏移量。

注意,如果字符串不是 'Z',则必须以 +- 字符开头。

moment().utcOffset("2013-03-07T07:00:00+08:00");

utcOffset 函数具有可选的第二个参数,该参数接受一个布尔值,该布尔值表明是否保留日期中的现有时间。

  • 传入 false(默认)将会在世界标准时间中保持不变,但本地时间将会改变。

  • 传入 true 将保留相同的本地时间,但要以在世界标准时间中选择其他时间为代价。

此特性的一种用法是,如果只想使用数字型输入值来构造具有特定时区偏移量的 moment:

moment([2016, 0, 1, 0, 0, 0]).utcOffset(-5, true) // 等效于 "2016-01-01T00:00:00-05:00"

zone() 新增于 1.2.0,废弃于 2.9.0

moment().zone();
moment().zone(Number|String);

Note: This function has been deprecated in 2.9.0. Consider moment.fn.utcOffset instead.

Get the time zone offset in minutes.

moment().zone(); // (60, 120, 240, etc.)

As of version 2.1.0, it is possible to set the offset by passing in the number of minutes offset from GMT.

moment().zone(120);

If the input is less than 16 and greater than -16, it will interpret your input as hours instead.

// these are equivalent
moment().zone(480);
moment().zone(8);

It is also possible to set the zone from a string.

moment().zone("-08:00");

moment#zone will search the string for the first match of +00:00 +0000 -00:00 -0000, so you can even pass an ISO8601 formatted string and the moment will be changed to that zone.

moment().zone("2013-03-07T07:00:00-08:00");

一旦解析和操作完成后,需要某些方式来显示 moment。

format() 1.0.0+

moment().format();
moment().format(String);

这是最稳健的显示选项。 它接受一串令牌并将其替换为其相应的值。

moment().format();                                // "2014-09-08T08:02:17-05:00" (ISO 8601,无小数秒钟)
moment().format("dddd, MMMM Do YYYY, h:mm:ss a"); // "Sunday, February 14th 2010, 3:25:50 pm"
moment().format("ddd, hA");                       // "Sun, 3PM"
moment('gibberish').format('YYYY MM DD');         // "Invalid date"
令牌 输出
月份 M 1 2 ... 11 12
Mo 1st 2nd ... 11th 12th
MM 01 02 ... 11 12
MMM Jan Feb ... Nov Dec
MMMM January February ... November December
季度 Q 1 2 3 4
Qo 1st 2nd 3rd 4th
月份的日期 D 1 2 ... 30 31
Do 1st 2nd ... 30th 31st
DD 01 02 ... 30 31
年份的日期 DDD 1 2 ... 364 365
DDDo 1st 2nd ... 364th 365th
DDDD 001 002 ... 364 365
星期几 d 0 1 ... 5 6
do 0th 1st ... 5th 6th
dd Su Mo ... Fr Sa
ddd Sun Mon ... Fri Sat
dddd Sunday Monday ... Friday Saturday
星期几(语言环境) e 0 1 ... 5 6
星期几(ISO) E 1 2 ... 6 7
年份的星期 w 1 2 ... 52 53
wo 1st 2nd ... 52nd 53rd
ww 01 02 ... 52 53
年份的星期(ISO) W 1 2 ... 52 53
Wo 1st 2nd ... 52nd 53rd
WW 01 02 ... 52 53
年份 YY 70 71 ... 29 30
YYYY 1970 1971 ... 2029 2030
Y 1970 1971 ... 9999 +10000 +10001
注意:对于 9999 年以后的日期,这符合 ISO 8601 标准。
周年 gg 70 71 ... 29 30
gggg 1970 1971 ... 2029 2030
周年(ISO) GG 70 71 ... 29 30
GGGG 1970 1971 ... 2029 2030
子午线 A AM PM
a am pm
小时 H 0 1 ... 22 23
HH 00 01 ... 22 23
h 1 2 ... 11 12
hh 01 02 ... 11 12
k 1 2 ... 23 24
kk 01 02 ... 23 24
分钟 m 0 1 ... 58 59
mm 00 01 ... 58 59
秒钟 s 0 1 ... 58 59
ss 00 01 ... 58 59
小数秒钟 S 0 1 ... 8 9
SS 00 01 ... 98 99
SSS 000 001 ... 998 999
SSSS ... SSSSSSSSS 000[0..] 001[0..] ... 998[0..] 999[0..]
时区 z or zz EST CST ... MST PST
注意:从 1.6.0 版本开始,z/zz 格式的令牌已从普通的 moment 对象中弃用。 在此处了解更多信息。 但是,如果将特定时区与 moment-timezone 插件一起使用,它们会起作用。
Z -07:00 -06:00 ... +06:00 +07:00
ZZ -0700 -0600 ... +0600 +0700
Unix 时间戳 X 1360013296
Unix 毫秒时间戳 x 1360013296123

X 新增于 2.0.0

e E gg gggg GG GGGG 新增于 2.1.0

x 新增于 2.8.4

SSSSSSSSSSSSS 新增于 2.10.5。 它们会显示 3 位有效数字,其余部分用零填充。

kkk 新增于 2.13.0

本地化格式

由于首选的格式会根据语言环境而有所不同,因此有一些令牌可用于根据语言环境格式 moment。

同一格式有大小写变体。 小写版本旨在作为大写版本的简化版本。

时间 LT 8:30 PM
带秒钟的时间 LTS 8:30:25 PM
月份数字,月份日期,年份 L 09/04/1986
l 9/4/1986
月份名称,月份日期,年份 LL September 4, 1986
ll Sep 4, 1986
月份名称,月份日期,年份,时间 LLL September 4, 1986 8:30 PM
lll Sep 4, 1986 8:30 PM
月份名称,月份日期,星期几,年份,时间 LLLL Thursday, September 4, 1986 8:30 PM
llll Thu, Sep 4, 1986 8:30 PM

l ll lll llll2.0.0 中可用。 LTS 新增于 2.8.4

转义字符

要转义格式字符串中的字符,可以将字符包装在方括号中。

moment().format('[今天] dddd'); // '今天 Sunday'

与 LDML 的异同

注意:虽然这些日期格式与 LDML 日期格式非常相似,但是在月份的日期、年份的日期、星期几等方面存在一些细微的差异。

有关跨不同语言环境的一些不同的日期格式令牌的详细信息,参阅日期格式令牌的图表

格式化速度

要与其他库比较 Moment.js 的格式化速度,请差异与其他库的比较

其他令牌

如果更习惯使用 strftime 而不是类似 LDML 的解析令牌,则可以使用 Ben Oakes 的插件 benjaminoakes/moment-strftime

默认的格式

不使用格式调用 moment#format 将会默认为 moment.defaultFormat。 开箱即用的 moment.defaultFormat 是 ISO8601 格式 YYYY-MM-DDTHH:mm:ssZ

2.13.0 版本开始,当在 UTC 模式中时,默认的格式由 moment.defaultFormatUtc 管理的,其格式是 YYYY-MM-DDTHH:mm:ss[Z]。 这会返回 Z 作为偏移量,而不是 +00:00

在某些情况下,本地时区(例如 Atlantic/Reykjavik)可能具有零偏移量,且将会被视为 UTC。 在这种情况下,将 moment.defaultFormatmoment.defaultFormatUtc 设置为使用相同的格式可能很有用。

更改 moment.defaultFormat 的值仅会影响格式化,而不会影响解析。 例如:

moment.defaultFormat = "DD.MM.YYYY HH:mm";
// 使用 .toDate() 解析。
moment('20.07.2018 09:19').toDate() // Invalid date
// 使用新的 defaultFormat 格式化日期字符串,然后解析。
moment('20.07.2018 09:19', moment.defaultFormat).toDate() // Fri Jul 20 2018 09:19:00 GMT+0300

fromNow() 1.0.0+

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

显示时间的常用方法是通过 moment#fromNow 处理。 有时称为时间间隔或相对时间。

moment([2007, 0, 29]).fromNow(); // 4 年前

If you pass true, you can get the value without the suffix. 如果传入 true,则可以获得不带后缀的值。

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

基本的字符串由当前的语言环境自定义。 时间会舍入到最接近的秒数。

下表概述了每个时间长度显示的字符串的细分。

范围 样本输出
0 至 44 秒 s 几秒前
未设定 ss 44 秒前
45 至 89 秒 m 1 分钟前
90 秒至 44 分钟 mm 2 分钟前 ... 44 分钟前
45 至 89 分钟 h 1 小时前
90 分钟至 21 小时 hh 2 小时前 ... 21 小时前
22 至 35 小时 d 1 天前
36 小时至 25 天 dd 2 天前 ... 25 天前
26 至 45 天 M 1 个月前
45 至 319 天 MM 2 个月前 ... 10 个月前
320 至 547 天 (1.5 年) y 1 年前
548 天+ yy 2 年前 ... 20 年前

注意:从 2.10.3 版本开始,如果目标 moment 对象无效,则结果为本地化的无效日期字符串。

注意:ss 键新增于 2.18.0。 这是一个可选的阈值。 除非用户手动设置 ss 阈值,否则它将永远不会显示。 在设置 ss 阈值之前,它默认为 s 阈值减去 1(因此对用户不可见)的值。

from() 1.0.0+

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

可能想要显示 moment 与现在以外的时间的相对时间。 在这种情况下,可以使用 moment#from

var a = moment([2007, 0, 28]);
var b = moment([2007, 0, 29]);
a.from(b) // "1 天前"

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

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

moment#fromNow 一样,将 true 用作第二个参数会返回不带后缀的值。 无论何时需要有可读的时间长度,这都非常有用。

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

2.10.3 版本开始,如果任一端点无效,则结果为本地化的无效日期字符串。

toNow() 2.10.3+

moment().toNow();
moment().toNow(Boolean);

显示时间的常用方法是通过 moment#toNow 处理。 有时称为时间间隔或相对时间。

这类似于 moment.fromNow,但给出相反的间隔:a.fromNow() = - a.toNow()

这类似于 moment.to,但在当前时间有特殊情况。 如果要控制间隔的两个端点,则使用 moment.to

moment([2007, 0, 29]).toNow(); // 4 年内

如果传入 true,则可以获取不带前缀的值。

moment([2007, 0, 29]).toNow();     // 4 年内
moment([2007, 0, 29]).toNow(true); // 4 年

基本的字符串由当前的语言环境自定义

下表概述了每个时间长度显示的字符串的细分。

范围 样本输出
0 至 44 秒 s 几秒内
45 至 89 秒 m 1 分钟内
90 秒至 44 分钟 mm 2 分钟内 ... 44 分钟内
45 至 89 分钟 h 1 小时内
90 分钟至 21 小时 hh 2 小时内 ... 21 小时内
22 至 35 小时 d 1 天内
36 小时至 25 天 dd 2 天内 ... 25 天内
26 至 45 天 M 1 个月内
45 至 319 天 MM 2 个月内 ... 10 个月内
320 至 547 天 (1.5 年) y 1 年内
548 天+ yy 2 年内 ... 20 年内

2.10.3 版本开始,如果目标 moment 对象无效,则结果为本地化的无效日期字符串。

to() 2.10.3+

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

可能想要显示 moment 与现在以外的时间的相对时间。 在这种情况下,可以使用 moment#to

var a = moment([2007, 0, 28]);
var b = moment([2007, 0, 29]);
a.to(b) // "1 天内"

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

var a = moment([2007, 0, 28]);
var b = moment([2007, 0, 29]);
a.to(b);                     // "1 天内"
a.to([2007, 0, 29]);         // "1 天内"
a.to(new Date(2007, 0, 29)); // "1 天内"
a.to("2007-01-29");          // "1 天内"

moment#toNow 一样,将 true 用作第二个参数会返回不带后缀的值。 无论何时需要有可读的时间长度,这都非常有用。

var start = moment([2007, 0, 5]);
var end   = moment([2007, 0, 10]);
end.to(start);       // "5 天前"
end.to(start, true); // "5 天"

2.10.3 版本开始,如果任一端点无效,则结果为本地化的无效日期字符串。

calendar() 1.3.0+

moment().calendar();
moment().calendar(referenceTime);
moment().calendar(referenceTime, formats);  // 从 2.10.5 开始

日历时间显示相对于给定的 referenceTime 的时间(默认为现在),但与 moment#fromNow 略有不同。

moment#calendar 会根据日期与 referenceTime 的日期(默认为今天)的接近程度,使用不同的字符串格式化日期。

上个星期 上星期一 2:30
前一天 昨天 2:30
同一天 今天 2:30
下一天 明天 2:30
下个星期 星期日 2:30
其他 7/10/2011

这些字符串是本地化的,可以自定义

2.10.5 开始,moment 支持指定每次调用的日历输出格式:

moment().calendar(null, {
    sameDay: '[今天]',
    nextDay: '[明天]',
    nextWeek: 'dddd',
    lastDay: '[昨天]',
    lastWeek: '[上个] dddd',
    sameElse: 'DD/MM/YYYY'
});

当 moment 与 referenceTime 相距超过一周时,则将 sameElse 用作格式。

注意:从 2.14.0 版本开始,日历的格式参数可以是一个在 moment 上下文中使用单个参数执行的回调:

moment().calendar(null, {
  sameDay: function (now) {
    if (this.isBefore(now)) {
      return '[今天将会发生]';
    } else {
      return '[今天已发生]';
    }
    /* ... */
  }
});

diff() 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#from 一样使用 moment#diff

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

要获取两个时刻之间的差值的时长,则可以将 diff 作为参数传给 moment#duration。 有关更多信息,参阅 moment#duration 上的文档。

支持的度量有 yearsmonthsweeksdayshoursminutesseconds。 为了便于开发,从 2.0.0 版本开始支持单数形式。 1.1.1 版本中提供了毫秒以外的度量单位。

默认情况下,moment#diff 会将结果截断为零个小数位,并返回一个整数。 如果需要浮点数,则将 true 作为第三个参数传入。 在 2.0.0 之前,moment#diff 返回的数字会四舍五入到最接近的整数,而不是截断的数字。

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

如果该时刻早于传给 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 版本开始,diff 还支持季度单位。

valueOf() 1.0.0+

moment().valueOf();
+moment();

moment#valueOf 简单地输出自 Unix 纪元以来的毫秒数,就像 Date#valueOf 一样。

moment(1318874398806).valueOf(); // 1318874398806
+moment(1318874398806); // 1318874398806

要从 Moment 获取 Unix 时间戳(自该纪元以来的秒数),则使用 moment#unix

注意:ECMAScript 将此称为“时间值”

unix() 1.6.0+

moment().unix();

moment#unix 输出 Unix 时间戳(自 Unix 纪元以来的秒数)

moment(1318874398806).unix(); // 1318874398

此值的下限为最接近的秒数,且不包括毫秒部分。

daysInMonth() 1.5.0+

moment().daysInMonth();

获取当月的天数。

moment("2012-02", "YYYY-MM").daysInMonth() // 29
moment("2012-01", "YYYY-MM").daysInMonth() // 31

toDate() 1.0.0+

moment().toDate();

要获取 Moment.js 封装的原生 Date 对象的副本,则使用 moment#toDate

这将会返回该 moment 使用的 Date 的副本,因此对该 Date 的任何更改都不会导致 moment 发生变化。 如果要更改 moment 的 Date,则参阅 moment#manipulatemoment#set

moment#native 已由 moment#toDate 取代,并已弃用于 1.6.0

toArray() 1.7.0+

moment().toArray();

这会返回一个数组,该数组反映了 new Date() 中的参数。

moment().toArray(); // [2013, 1, 4, 14, 40, 16, 154];

toJSON() 2.0.0+

moment().toJSON();

当将对象序列化为 JSON 时,如果有 Moment 对象,则它会将被解释为 ISO8601 字符串,并调整到 UTC。

JSON.stringify({
    postDate : moment()
}); // '{"postDate":"2013-02-04T22:44:30.652Z"}'

如果希望使用一个 ISO8601 字符串来反映该 moment 的 utcOffset(),则可以像这样修改 toJSON 函数:

moment.fn.toJSON = function() { return this.format(); }

这会更改行为,如下所示:

JSON.stringify({
    postDate : moment()
}); // '{"postDate":"2013-02-04T14:44:30-08:00"}'

toISOString() 2.1.0+

moment().toISOString();
moment().toISOString(keepOffset); // 从 2.20.0 开始

将字符串格式化为 ISO8601 标准。

moment().toISOString() // 2013-02-04T22:44:30.652Z

注意,即使问题中的 moment 处于本地模式,.toISOString() 也会以 UTC 返回时间戳。 这样做是为了与 ES2015 规范中概述的原生 JavaScript Date .toISOString() 规范保持一致。 从 2.20.0 版本开始,可以调用 .toISOString(true) 以防止 UTC 转换。

2.8.4 版本开始,出于性能原因,尽可能使用原生 Date.prototype.toISOString

toObject() 2.10.5+

moment().toObject();

这会返回一个包含年份、月份、月份的日期、小时、分钟、秒钟、毫秒的对象。

moment().toObject()  // {
                     //     years: 2015
                     //     months: 6
                     //     date: 26,
                     //     hours: 1,
                     //     minutes: 53,
                     //     seconds: 14,
                     //     milliseconds: 600
                     // }

toString() 2.1.0+

moment().toString();

以与 JS Date 的 .toString() 类似的格式返回英文字符串。

moment().toString() // "Sat Apr 30 2016 16:59:46 GMT-0500"

inspect() 2.16.0+

moment().inspect();

返回机器可读的字符串,可以对其进行评估以产生相同的 moment。 由于其名称,它还用于节点交互式 shell 中以显示对象。

moment().inspect() // 'moment("2016-11-09T22:23:27.861")'
moment.utc().inspect() // 'moment.utc("2016-11-10T06:24:10.638+00:00")'
moment.parseZone('2016-11-10T06:24:12.958+05:00').inspect() // 'moment.parseZone("2016-11-10T06:24:12.958+05:00")'
moment(new Date('nope')).inspect() // 'moment.invalid(/* Invalid Date */)'
moment('blah', 'YYYY').inspect() // 'moment.invalid(/* blah */)'

注意:此函数主要用于调试,并非所有情况都经过精确处理。

isBefore() 2.0.0+

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

检查一个 moment 是否在另一个 moment 之前。 第一个参数会被解析为 moment(如果尚未解析)。

moment('2010-10-20').isBefore('2010-10-21'); // true

如果要将粒度限制为毫秒以外的单位,则将单位作为第二个参数传入。

由于第二个参数用于确定精度,且不仅仅是要检查的单个值,因此使用 day 将会检查年份、月份、日期。

moment('2010-10-20').isBefore('2010-12-31', 'year'); // false
moment('2010-10-20').isBefore('2011-01-01', 'year'); // true

moment#isAftermoment#isSame 一样,moment#startOf 支持的任何时间单位也适用于 moment#isBefore

year month week isoWeek day hour minute second

如果未将任何内容传给 moment#isBefore,则它将会默认为当前时间。

注意:moment().isBefore() 具有未定义的行为,且不应被使用! 如果代码运行快速,则初始创建的 moment 将会与isBefore 中创建的要执行检查的相同,因此结果将会为 false。 但是,如果代码运行速度较慢,则有可能在 isBefore 中创建的 moment 可测量地在 moment() 中创建的之后,因此该调用将会返回 true

isSame() 2.0.0+

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

检查一个 moment 是否与另一个 moment 相同。 第一个参数会被解析为 moment(如果尚未解析)。

moment('2010-10-20').isSame('2010-10-20'); // true

如果要将粒度限制为毫秒以外的单位,则将单位作为第二个参数传入。

moment('2010-10-20').isSame('2009-12-31', 'year');  // false
moment('2010-10-20').isSame('2010-01-01', 'year');  // true
moment('2010-10-20').isSame('2010-12-31', 'year');  // true
moment('2010-10-20').isSame('2011-01-01', 'year');  // false

当包含第二个参数时,则它将会匹配所有等于或更大的单位。 传入 month 将会检查 monthyear。 传入 day 将会检查 daymonthyear

moment('2010-01-01').isSame('2011-01-01', 'month'); // false, 不同的年份
moment('2010-01-01').isSame('2010-02-01', 'day');   // false, 不同的月份

moment#isAftermoment#isBefore 一样,moment#startOf 支持的任何时间单位也适用于 moment#isSame

year month week isoWeek day hour minute second

如果两个 moment 的时区不同,则第一 moment 的时区会被用于比较。

// 注意:澳大利亚/悉尼在这些日期的 UTC+11:00
moment.tz("2018-11-09T10:00:00", "Australia/Sydney").isSame(moment.tz("2018-11-08T12:00:00", "UTC"), "day"); // false
moment.tz("2018-11-08T12:00:00", "UTC").isSame(moment.tz("2018-11-09T10:00:00", "Australia/Sydney"), "day"); // true

注意:moment().isSame() 具有未定义的行为,且不应被使用! 如果代码运行快速,则初始创建的 moment 将会与isSame 中创建的要执行检查的相同,因此结果将会为 true。 但是,如果代码运行速度较慢,则有可能在 isSame 中创建的 moment 可测量地在 moment() 中创建的之后,因此该调用将会返回 false

isAfter() 2.0.0+

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

检查一个 moment 是否在另一个 moment 之后。 第一个参数会被解析为 moment(如果尚未解析)。

moment('2010-10-20').isAfter('2010-10-19'); // true

如果要将粒度限制为毫秒以外的单位,则将单位作为第二个参数传入。

由于第二个参数用于确定精度,且不仅仅是要检查的单个值,因此使用 day 将会检查年份、月份、日期。

moment('2010-10-20').isAfter('2010-01-01', 'year'); // false
moment('2010-10-20').isAfter('2009-12-31', 'year'); // true

moment#isSamemoment#isBefore 一样,moment#startOf 支持的任何时间单位也适用于 moment#isAfter

year month week isoWeek day hour minute second

如果未将任何内容传给 moment#isAfter,则它将会默认为当前时间。

moment().isAfter(); // false

isSameOrBefore() 2.11.0+

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

检查一个 moment 是否在另一个 moment 之前或与之相同。 第一个参数会被解析为 moment(如果尚未解析)。

moment('2010-10-20').isSameOrBefore('2010-10-21');  // true
moment('2010-10-20').isSameOrBefore('2010-10-20');  // true
moment('2010-10-20').isSameOrBefore('2010-10-19');  // false

如果要将粒度限制为毫秒以外的单位,则将单位作为第二个参数传入。

由于第二个参数用于确定精度,且不仅仅是要检查的单个值,因此使用 day 将会检查年份、月份、日期。

moment('2010-10-20').isSameOrBefore('2009-12-31', 'year'); // false
moment('2010-10-20').isSameOrBefore('2010-12-31', 'year'); // true
moment('2010-10-20').isSameOrBefore('2011-01-01', 'year'); // true

moment#isAftermoment#isSame 一样,moment#startOf 支持的任何时间单位也适用于 moment#isSameOrBefore

year month week isoWeek day hour minute second

isSameOrAfter() 2.11.0+

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

检查一个 moment 是否在另一个 moment 之后或与之相同。 第一个参数会被解析为 moment(如果尚未解析)。

moment('2010-10-20').isSameOrAfter('2010-10-19'); // true
moment('2010-10-20').isSameOrAfter('2010-10-20'); // true
moment('2010-10-20').isSameOrAfter('2010-10-21'); // false

如果要将粒度限制为毫秒以外的单位,则将单位作为第二个参数传入。

由于第二个参数用于确定精度,且不仅仅是要检查的单个值,因此使用 day 将会检查年份、月份、日期。

moment('2010-10-20').isSameOrAfter('2011-12-31', 'year'); // false
moment('2010-10-20').isSameOrAfter('2010-01-01', 'year'); // true
moment('2010-10-20').isSameOrAfter('2009-12-31', 'year'); // true

moment#isSamemoment#isBefore 一样,moment#startOf 支持的任何时间单位也适用于 moment#isSameOrAfter

year month week isoWeek day hour minute second

isBetween() 2.9.0+

//从 2.13.0 开始
moment().isBetween(moment-like, moment-like);
moment().isBetween(moment-like, moment-like, String);
moment().isBetween(moment-like, moment-like, String, String);
// 其中 moment-like 是 Moment|String|Number|Date|Array

//2.9.0 至 2.12.0
moment().isBetween(moment-like, moment-like);
moment().isBetween(moment-like, moment-like, String);
// 其中 moment-like 是 is Moment|String|Number|Date|Array

检查一个 moment 是否在其他两个 moment 之间,可选地检查指定的单位刻度(分钟,小时,日期等)。 这个匹配是排他的。 前两个参数会被解析为 moment(如果尚未解析)。

moment('2010-10-20').isBetween('2010-10-19', '2010-10-25'); // true
moment('2010-10-20').isBetween('2010-10-19', undefined); // true, 因为 moment(undefined) 等效于 moment()

如果要将粒度限制为毫秒以外的单位,则将单位作为第三个参数传入。

moment('2010-10-20').isBetween('2010-01-01', '2012-01-01', 'year'); // false
moment('2010-10-20').isBetween('2009-12-31', '2012-01-01', 'year'); // true

moment#isSamemoment#isBeforemoment#isAfter 一样,moment#startOf 支持的任何时间单位也适用于 moment#isBetween。 年份、月份、星期、ISO星期、日期、小时、分钟、秒钟。

2.13.0 版本引入了包容性。 [ 表示包含。 ( 表示排除。 如果使用包容性参数,则必须传入两个指示符。

moment('2016-10-30').isBetween('2016-10-30', '2016-12-30', null, '()'); //false
moment('2016-10-30').isBetween('2016-10-30', '2016-12-30', null, '[)'); //true
moment('2016-10-30').isBetween('2016-01-01', '2016-10-30', null, '()'); //false
moment('2016-10-30').isBetween('2016-01-01', '2016-10-30', null, '(]'); //true
moment('2016-10-30').isBetween('2016-10-30', '2016-10-30', null, '[]'); //true

注意,如果 fromto 参数相同,但包容性参数不同,则将会返回 false。

moment('2016-10-30').isBetween('2016-10-30', '2016-10-30', null, '(]'); //false

如果未指定包容性参数,则 Moment 将会默认为 ()

isDST() 1.2.0+

moment().isDST();

moment#isDST 检查当前时刻是否为夏令时(daylight saving time)。

moment([2011, 2, 12]).isDST(); // false, 2011年3月12日不是 DST。
moment([2011, 2, 14]).isDST(); // true, 2011年3月14日是 DST。
// 此示例适用于 "en" 语言环境:https://www.timeanddate.com/time/dst/2011.html

isDSTShifted() 新增于 2.3.0,废弃于 2.14.0

moment('2013-03-10 2:30', 'YYYY-MM-DD HH:mm').isDSTShifted()

Note: As of version 2.14.0 this function is deprecated. It doesn't give the right answer after modifying the moment object. For more information refer to moment/3160

Another important piece of validation is to know if the date has been moved by a DST. For example, in most of the United States:

moment('2013-03-10 2:30', 'YYYY-MM-DD HH:mm').format(); //=> '2013-03-10T01:30:00-05:00'

This is because daylight saving time shifts the time from 2:00 to 3:00, so 2:30 isn't a real time. The resulting time is browser-dependent, either adjusting the time forward or backwards. Use moment#isDSTShifted to test for this condition.

Note: before 2.3.0, Moment objects in this condition always returned false for moment#isValid; they now return true.

isLeapYear() 1.0.0+

moment().isLeapYear();

如果该年是闰年,则 moment#isLeapYear 返回 true,否则返回 false

moment([2000]).isLeapYear() // true
moment([2001]).isLeapYear() // false
moment([2100]).isLeapYear() // false

isMoment() 1.5.0+

moment.isMoment(obj);

要检查变量是否为 moment 对象,则使用 moment.isMoment()

moment.isMoment() // false
moment.isMoment(new Date()) // false
moment.isMoment(moment()) // true

2.11.0 版本开始,还可以通过 instanceof 运算符检测 moment 对象:

moment() instanceof moment // true

isDate() 2.9.0+

moment.isDate(obj);

要检查变量是否为原生 js Date 对象,则使用 moment.isDate()

moment.isDate(); // false
moment.isDate(new Date()); // true
moment.isDate(moment()); // false

Moment.js 对国际化具有强大的支持。

可以加载多个语言环境并在它们之间轻松地切换。

除了分配全局的语言环境外,还可以将语言环境分配给特定的 moment。

设置语言环境 (全局) 1.0.0+

// 从 2.8.1 开始
moment.locale(String);
moment.locale(String[]);
moment.locale(String, Object);

// 废弃于 2.8.1
moment.lang(String);
moment.lang(String[]);
moment.lang(String, Object);

默认情况下,Moment.js 随附英语(美国)语言环境字符串。 如果需要其他语言环境,则可以将它们加载到 Moment.js 中以供随后使用。

要加载语言环境,则将键和字符串值传给 moment.locale

可以在自定义章节中找到有关语言环境包的各个部分的更多详细信息。

moment.locale('fr', {
    months : 'janvier_février_mars_avril_mai_juin_juillet_août_septembre_octobre_novembre_décembre'.split('_'),
    monthsShort : 'janv._févr._mars_avr._mai_juin_juil._août_sept._oct._nov._déc.'.split('_'),
    monthsParseExact : true,
    weekdays : 'dimanche_lundi_mardi_mercredi_jeudi_vendredi_samedi'.split('_'),
    weekdaysShort : 'dim._lun._mar._mer._jeu._ven._sam.'.split('_'),
    weekdaysMin : 'Di_Lu_Ma_Me_Je_Ve_Sa'.split('_'),
    weekdaysParseExact : true,
    longDateFormat : {
        LT : 'HH:mm',
        LTS : 'HH:mm:ss',
        L : 'DD/MM/YYYY',
        LL : 'D MMMM YYYY',
        LLL : 'D MMMM YYYY HH:mm',
        LLLL : 'dddd D MMMM YYYY HH:mm'
    },
    calendar : {
        sameDay : '[Aujourd’hui à] LT',
        nextDay : '[Demain à] LT',
        nextWeek : 'dddd [à] LT',
        lastDay : '[Hier à] LT',
        lastWeek : 'dddd [dernier à] LT',
        sameElse : 'L'
    },
    relativeTime : {
        future : 'dans %s',
        past : 'il y a %s',
        s : 'quelques secondes',
        m : 'une minute',
        mm : '%d minutes',
        h : 'une heure',
        hh : '%d heures',
        d : 'un jour',
        dd : '%d jours',
        M : 'un mois',
        MM : '%d mois',
        y : 'un an',
        yy : '%d ans'
    },
    dayOfMonthOrdinalParse : /\d{1,2}(er|e)/,
    ordinal : function (number) {
        return number + (number === 1 ? 'er' : 'e');
    },
    meridiemParse : /PD|MD/,
    isPM : function (input) {
        return input.charAt(0) === 'M';
    },
    // 如果子午线单位未在12左右分开,则实现此函数(以 locale/id.js 为例)。
    // meridiemHour : function (hour, meridiem) {
    //     return /* 0-23 小时,给定的子午线令牌和 1-12小时 */ ;
    // },
    meridiem : function (hours, minutes, isLower) {
        return hours < 12 ? 'PD' : 'MD';
    },
    week : {
        dow : 1, // 星期一是一周的第一天。
        doy : 4  // 用于判断一年中的第一周。
    }
});

有关 week.dowweek.doy 的详细信息可以在自定义章节中找到。

加载语言环境之后,则它会成为活动的语言环境。 要更改活动的语言环境,只需使用已加载的语言环境的键调用 moment.locale

moment.locale('fr');
moment(1316116057189).fromNow(); // il y a une heure
moment.locale('en');
moment(1316116057189).fromNow(); // an hour ago

2.21.0 开始,如果语言环境不可用,则 Moment 将会 console.warn

2.8.0 开始,更改全局的语言环境不会影响已存在的实例。

moment.locale('fr');
var m = moment(1316116057189);
m.fromNow(); // il y a une heure

moment.locale('en');
m.fromNow(); // il y a une heure
moment(1316116057189).fromNow(); // an hour ago

moment.locale 返回使用的语言环境。 这很有用,因为如果 Moment 不知道你指定的语言环境,它就不会更改语言环境。

moment.locale('fr'); // 'fr'
moment.locale('tq'); // 'fr'

也可以指定一个语言环境的列表,Moment 将会使用它具有本地化的第一个语言环境。

moment.locale(['tq', 'fr']); // 'fr'

Moment 还将会尝试从最特定到最不特定的语言环境说明符子字符串,直到找到它知道的语言环境。 当为 Moment 提供从用户环境中拉出的语言环境字符串(例如 window.navigator.language)时,这很有用。

moment.locale('en-NZ'); // 'en'

最后,Moment 将会通过一系列语言环境及其子字符串进行智能搜索。

moment.locale(['en-NZ', 'en-AU']); // 'en-au', 而不是 'en'

设置语言环境 (局部) 1.7.0+

// 从 2.8.1 版本开始
moment().locale(String|Boolean);

// 废弃于 2.8.1 版本
moment().lang(String|Boolean);

当传递可能需要格式化为不同语言环境的 moment 时,全局的语言环境配置可能会出现问题。

moment.locale('en'); // 默认的语言环境为英语。
var localLocale = moment();

localLocale.locale('fr'); // 将此实例设置为使用法语。
localLocale.format('LLLL'); // dimanche 15 juillet 2012 11:01
moment().format('LLLL'); // Sunday, July 15 2012 11:01 AM

moment.locale('es'); // 将全局的语言环境更改为西班牙语。
localLocale.format('LLLL'); // dimanche 15 juillet 2012 11:01
moment().format('LLLL'); // Domingo 15 Julio 2012 11:01

localLocale.locale(false); // 重置实例的语言环境。
localLocale.format('LLLL'); // Domingo 15 Julio 2012 11:01
moment().format('LLLL'); // Domingo 15 Julio 2012 11:01

如果不带参数调用 moment#locale,则会获取该 moment 使用的语言环境配置。

var fr = moment().locale('fr');
fr.localeData().months(moment([2012, 0])) // "janvier"
fr.locale('en');
fr.localeData().months(moment([2012, 0])) // "January"

如果需要访问 moment 的语言环境数据,这是首选的方式。

2.3.0 开始,还可以指定一个语言环境标识符的数组。 它的工作方式与在全局的语言环境配置中相同。

加载语言环境 (NodeJS) 1.0.0+

moment.locale(String);

在 NodeJS 中加载语言环境非常简单。 如果 moment-root/locale/ 中有一个以该键命名的语言环境文件,则对 moment.locale 的第一次调用将会加载该文件。

var moment = require('moment');
moment.locale('fr');
moment(1316116057189).fromNow(); // il y a une heure

如果希望你的语言环境受支持,则使用所需的语言环境和单元测试文件创建一个对 develop 分支的 pull request。

加载语言环境 (浏览器) 1.0.0+

// 从 2.8.1 开始
moment.locale(String, Object);

// 废弃于 2.8.1
moment.lang(String, Object);

在浏览器中加载语言环境仅需要包括语言环境文件。 确保指定字符集以防止编码问题。

<script src="moment.js"></script>
<script src="locale/fr.js" charset="UTF-8"></script>
<script src="locale/pt.js" charset="UTF-8"></script>
<script>
  moment.locale('fr');  // 设置默认/全局的语言环境。
  // ...
</script>

有所有语言环境的压缩版本:

<script src="moment.js"></script>
<script src="min/locales.js" charset="UTF-8"></script>

为了最大程度地减少 HTTP 请求,请使用 Grunt 任务以自定义的语言环境列表来编译 Moment

grunt transpile:fr,it
<script src="min/moment-with-locales.custom.js" charset="UTF-8"></script>

如果使用 JSPM 作为插件管理器,则应在 lib 中添加语言环境。

import * as moment from 'moment';
import 'moment/locale/fr';

注意:语言环境文件是以 UMD 风格定义的,因此它们应在所有环境中无缝运行。

新增语言环境

要将你的语言环境添加到 Moment.js,则提交一个 pull request 并带上语言环境文件和测试文件。 可以在 moment/src/locale/fr.jsmoment/src/test/locale/fr.js 中查看示例。

要在 Node.js 中运行测试,则先执行 npm install,然后执行 grunt

如果所有的测试均通过,则提交 pull request,感谢你的贡献!

locale() 1.6.0+

// 从 2.8.1 版本开始
moment.locale();

// 废弃于 2.8.1 版本
moment.lang();

如果需要经常更改语言环境,则可能想知道当前正在使用的语言环境。 这可以不带任何参数调用 moment.locale

moment.locale('en'); // 设为英语
moment.locale(); // 返回 'en'
moment.locale('fr'); // 设为法语
moment.locale(); // 返回 'fr'

2.12.0 版本开始,可以列出所有已加载并可以使用的语言环境:

moment.locales()

months()/weekdays() 2.3.0+

moment.months()
moment.monthsShort()
moment.weekdays()
moment.weekdaysShort()
moment.weekdaysMin()

有时需要在语言环境中获取月份或工作日的列表,例如当填充下拉菜单时。

moment.months();

返回当前语言环境中的月份列表。

[ 'January',
  'February',
  'March',
  'April',
  'May',
  'June',
  'July',
  'August',
  'September',
  'October',
  'November',
  'December' ]

同样,moment.monthsShort 返回缩写的月份名称,moment.weekdaysmoment.weekdaysShortmoment.weekdaysMin 返回工作日的列表。

可以将整数传给每个函数以获取特定的月份或工作日。

moment.weekdays(3); // 'Wednesday'

2.13.0 开始,可以将布尔值作为 weekday 函数的第一个参数传入。 如果为 true,则将会按特定于语言环境的顺序返回工作日。 例如,在阿拉伯语言环境中,星期六是一周的第一天,因此:

moment.locale('ar');
moment.weekdays(true); // 以阿拉伯语列出周六至周五的工作日列表
moment.weekdays(true, 2); // 将会以阿拉伯语返回星期一

注意:如果缺少语言环境特定的参数,则无论星期几是本地的第一天,工作日始终将星期日作为索引 0。

当格式化月份名称时,某些语言环境会特别考虑。 例如,荷兰语格式化月份的缩写时不带末尾的句号,但前提是格式化破折号之间的月份。 months 方法支持传入格式,以便在适当的上下文中列出月份。

moment.locale('nl');
moment.monthsShort(); // ['jan.', 'feb.', 'mrt.', ...]
moment.monthsShort('-MMM-'); // [ 'jan', 'feb', 'mrt', ...]

最后,可以结合使用格式选项和整数选项。

moment.monthsShort('-MMM-', 3); // 'apr'

localeData() 2.8.0+

localeData = moment.localeData()
localeData.months(Moment)
localeData.months()
localeData.monthsShort(Moment)
localeData.monthsShort()
localeData.monthsParse(String)
localeData.weekdays(Moment)
localeData.weekdays()
localeData.weekdays(Boolean)      ## 新增于 2.24.0,按语言环境对工作日进行排序。
localeData.weekdaysShort(Moment)
localeData.weekdaysShort()
localeData.weekdaysShort(Boolean) ## 新增于 2.24.0,按语言环境对工作日进行排序。
localeData.weekdaysMin(Moment)
localeData.weekdaysMin()
localeData.weekdaysMin(Boolean)   ## 新增于 2.24.0,按语言环境对工作日进行排序。
localeData.weekdaysParse(String)
localeData.longDateFormat(String)
localeData.isPM(String)
localeData.meridiem(Number, Number, Boolean)
localeData.calendar(String, Moment)
localeData.relativeTime(Number, Boolean, String, Boolean)
localeData.pastFuture(Number, String)
localeData.ordinal(Number)
localeData.preparse(String)
localeData.postformat(String)
localeData.week(Moment)
localeData.invalidDate()
localeData.firstDayOfWeek()
localeData.firstDayOfYear()

可以通过 moment.localeData(key) 函数访问当前加载的语言环境的属性。 它返回当前语言环境或具有给定键的语言环境:

// 获取当前的语言环境
var currentLocaleData = moment.localeData();
var frLocaleData = moment.localeData('fr');

返回的对象具有以下方法:

localeData.months(aMoment);  // aMoment 的完整月份名称
localeData.monthsShort(aMoment);  // aMoment 的简短月份名称
localeData.monthsParse(longOrShortMonthString);  // 返回输入的月份 id (0 至 11)
localeData.weekdays(aMoment);  // aMoment 的完整工作日名称
localeData.weekdaysShort(aMoment);  // aMoment 的简短工作日名称
localeData.weekdaysMin(aMoment);  // aMoment 的最小工作日名称
localeData.weekdaysParse(minShortOrLongWeekdayString);  // 返回输入的工作日 id (0 至 6)
localeData.longDateFormat(dateFormat);  // 返回缩写的日期时间格式(LT、L、LL 等)的完整格式
localeData.isPM(amPmString);  // 如果 amPmString 代表 PM,则返回 true
localeData.meridiem(hours, minutes, isLower);  // 返回大写/小写的特定日期时间的 am/pm 字符串
localeData.calendar(key, aMoment);  // 返回用于日历表示的格式。键是 'sameDay'、'nextDay'、'lastDay'、'nextWeek'、'prevWeek'、'sameElse' 之一
localeData.relativeTime(number, withoutSuffix, key, isFuture);  // 返回相对时间的字符串,键是 's'、'm'、'mm'、'h'、'hh'、'd'、'dd'、'M'、'MM'、'y'、'yy' 之一。当 number 为 1 时为单个字母
localeData.pastFuture(diff, relTime);  // 根据差异将 relTime 字符串转换为过去或未来的字符串
localeData.ordinal(number);  // 将数字转换为序数字符串 1-> 1st
localeData.preparse(str);  // 在解析每个输入字符串之前调用
localeData.postformat(str);  // 在格式化每个字符串后调用
localeData.week(aMoment);  // 返回 aMoment 的周年
localeData.invalidDate();  // 返回 'Invalid date' 的翻译
localeData.firstDayOfWeek();  // 0-6 (星期日至星期六)
localeData.firstDayOfYear();  // 0-15 用于判断年份的第一周

有关 firstDayOfYear 的详细信息可以在自定义章节中查看。

locale('x-pseudo') 2.13.0+

moment.locale('x-pseudo')

2.13.0 版本开始,moment 可选地包含伪语言环境。 此语言环境将会使用非常明显变化的数据填充日期。 伪语言环境在测试时很有用,因为它们可以清楚地显示已定位和未定位的数据。 只需包含伪语言环境,并将 moment 的语言环境设置为 x-pseudo。 Moment 中的文本将会非常容易发现。

moment.locale('x-pseudo');
moment().format('LLL'); //14 F~ébrú~árý 2010 15:25
moment().fromNow(); //'á ~féw ~sécó~ñds á~gó'
moment().calendar(); //'T~ódá~ý át 02:00'

Moment.js 非常容易自定义。 通常,应该使用自定义创建语言环境。

moment.locale('en-my-settings', {
    // 自定义
});

可以通过传入 null 作为第二个参数来移除先前定义的语言环境。 删除的语言环境将不再可用。

moment.locale('fr'); // 'fr'
moment.locale('en'); // 'en'
moment.locale('fr', null);
moment.locale('fr'); // 'en'

2.12.0 开始,可以创建从父语言环境继承的语言环境。

moment.defineLocale('en-foo', {
  parentLocale: 'en',
  /* */
});

在语言环境中未指定的属性将会从父语言环境中继承。

2.16.0 版本开始,可以使用尚未定义或加载的父语言环境来定义语言环境。

moment.defineLocale('fakeLocale', {parentLocale:'xyz'})

2.21.0 开始,当尝试使用新定义的语言环境创建 moment 时,如果存在父语言环境,则 moment 将会尝试延迟加载它。 当失败时,它会默认将父语言环境设置为全局的语言环境。

2.12.0 开始,还可以更新语言环境的属性。

moment.updateLocale('en', {
  /**/
});

指定的任何属性将会被更新,而其他属性将会保持不变。 此函数不会影响已经存在的 moment。

要还原更新,则使用:

moment.updateLocale('en', null);

使用 moment.locale() 更改现有的语言环境已废弃于 2.12.0。 改用 moment.updateLocale()

months 1.0.0+

// 从 2.12.0 开始
moment.updateLocale('en', {
    months : String[]
});
moment.updateLocale('en', {
    months : Function
});
moment.updateLocale('en', {
    months : {
        format : String[],
        standalone : String[]
    }
});
// 从 2.11.0 开始
moment.locale('en', {
    months : {
        format : String[],
        standalone : String[]
    }
});
// 从 2.8.1 至 2.11.2
moment.locale('en', {
    months : String[]
});
moment.locale('en', {
    months : Function
});

// 废弃于 2.8.1
moment.lang('en', {
    months : String[]
});
moment.lang('en', {
    months : Function
});

Locale#months 应是月份名称的数组。

moment.updateLocale('en', {
    months : [
        "January", "February", "March", "April", "May", "June", "July",
        "August", "September", "October", "November", "December"
    ]
});

如果需要更多处理来计算月份的名称(例如,如果不同格式的语法不同),则 Locale#months 可以是具有以下签名的函数。 它应始终返回月份的名称。

moment.updateLocale('en', {
    months : function (momentToFormat, format) {
        // momentToFormat 是当前正在被格式化的 moment。
        // format 是格式化字符串。
        if (/^MMMM/.test(format)) { // 如果格式以 'MMMM' 开头。
            return nominative[momentToFormat.month()];
        } else {
            return subjective[momentToFormat.month()];
        }
    }
});

2.11.0 版本开始,月份也可以是一个对象,指定 standaloneformat 的形式(主格和宾格)。 在格式上运行以检查是否使用 format 形式的正则表达式是 /D[oD]?(\[[^\[\]]*\]|\s+)+MMMM?/。 从 2.14.0 版本开始,可以使用 isFormat 键指定另一个。

moment.updateLocale('en', {
    months : {
         format: 'sausio_vasario_kovo_balandžio_gegužės_birželio_liepos_rugpjūčio_rugsėjo_spalio_lapkričio_gruodžio'.split('_'),
         standalone: 'sausis_vasaris_kovas_balandis_gegužė_birželis_liepa_rugpjūtis_rugsėjis_spalis_lapkritis_gruodis'.split('_'),
         isFormat: /D[oD]?(\[[^\[\]]*\]|\s+)+MMMM?|MMMM?(\[[^\[\]]*\]|\s+)+D[oD]?/  // from 2.14.0
    }
});

monthsShort 1.0.0+

// 从 2.12.0 开始
moment.updateLocale('en', {
    monthsShort : String[]
});
moment.updateLocale('en', {
    monthsShort : Function
});
moment.updateLocale('en', {
    monthsShort : {
        format: String[],
        standalone : String[]
    }
});
// 从 2.11.0 开始
moment.locale('en', {
    monthsShort : {
        format: String[],
        standalone : String[]
    }
});
// 从 2.8.1 至 2.11.2
moment.locale('en', {
    monthsShort : String[]
});
moment.locale('en', {
    monthsShort : Function
});

// 废弃于 2.8.1
moment.lang('en', {
    monthsShort : String[]
});
moment.lang('en', {
    monthsShort : Function
});

Locale#monthsShort 应是月份缩写的数组。

moment.updateLocale('en', {
    monthsShort : [
        "Jan", "Feb", "Mar", "Apr", "May", "Jun",
        "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
    ]
});

Locale#months 一样,Locale#monthsShort 也可以是回调函数。

moment.updateLocale('en', {
    monthsShort : function (momentToFormat, format) {
        if (/^MMMM/.test(format)) {
            return nominative[momentToFormat.month()];
        } else {
            return subjective[momentToFormat.month()];
        }
    }
});

注意:从 2.11.0 版本开始,与 Locale#months 一样,Locale#monthsShort 可以是具有 standaloneformat 用例的对象。

moment.updateLocale('en', {
    monthsShort : {
        format: 'янв_фев_мар_апр_мая_июня_июля_авг_сен_окт_ноя_дек'.split('_'),
        standalone: 'янв_фев_март_апр_май_июнь_июль_авг_сен_окт_ноя_дек'.split('_')
    }
});

weekdays 1.0.0+

// 从 2.12.0 版本开始
moment.updateLocale('en', {
    weekdays : String[]
});
moment.updateLocale('en', {
    weekdays : Function
});
moment.updateLocale('en', {
    weekdays : {
        standalone : String[],
        format : String[],
        isFormat : RegExp
    }
});
// 从 2.11.0 版本开始
moment.locale('en', {
    weekdays : {
        standalone : String[],
        format : String[],
        isFormat : Boolean
    }
});
// 从 2.8.1 至 2.11.2 版本
moment.locale('en', {
    weekdays : String[]
});
moment.locale('en', {
    weekdays : Function
});

// 废弃于 2.8.1 版本
moment.lang('en', {
    weekdays : String[]
});
moment.lang('en', {
    weekdays : Function
});

Locale#weekdays 应是工作日名称的数组。

moment.updateLocale('en', {
    weekdays : [
        "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"
    ]
});

Locale#weekdays 也可以是回调函数。

moment.updateLocale('en', {
    weekdays : function (momentToFormat, format) {
        return weekdays[momentToFormat.day()];
    }
});

注意:从 2.11.0 版本开始,format/standalone 用例也可以传入。 isFormat 将会用于完整的格式字符串,以判断要使用的格式。

moment.updateLocale('en', {
    weekdays : {
        standalone: 'Воскресенье_Понедельник_Вторник_Среда_Четверг_Пятница_Суббота'.split('_'),
        format: 'Воскресенье_Понедельник_Вторник_Среду_Четверг_Пятницу_Субботу'.split('_'),
        isFormat: /\[ ?[Вв] ?(?:прошлую|следующую|эту)? ?\] ?dddd/
    }
});

weekdaysShort 1.0.0+

// 从 2.12.0 开始
moment.updateLocale('en', {
    weekdaysShort : String[]
});
moment.updateLocale('en', {
    weekdaysShort : Function
});
// 从 2.8.1 至 2.11.2
moment.locale('en', {
    weekdaysShort : String[]
});
moment.locale('en', {
    weekdaysShort : Function
});

// 废弃于 2.8.1
moment.lang('en', {
    weekdaysShort : String[]
});
moment.lang('en', {
    weekdaysShort : Function
});

Locale#weekdaysShort 应是工作日缩写的数组。

moment.updateLocale('en', {
    weekdaysShort : ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"]
});

Locale#weekdaysShort 也可以是回调函数。

moment.updateLocale('en', {
    weekdaysShort : function (momentToFormat, format) {
        return weekdaysShort[momentToFormat.day()];
    }
});

weekdaysMin 1.7.0+

// 从 2.12.0 开始
moment.updateLocale('en', {
    weekdaysMin : String[]
});
moment.updateLocale('en', {
    weekdaysMin : Function
});

// 从 2.8.1 至 2.11.2
moment.locale('en', {
    weekdaysMin : String[]
});
moment.locale('en', {
    weekdaysMin : Function
});

// 废弃于 2.8.1
moment.lang('en', {
    weekdaysMin : String[]
});
moment.lang('en', {
    weekdaysMin : Function
});

Locale#weekdaysMin 应是两个字母的工作日缩写的数组。 它们的目的是用于日历选择器之类的,因此它们应尽可能短小。

moment.updateLocale('en', {
    weekdaysMin : ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"]
});

Locale#weekdaysMin 也可以是回调函数。

moment.updateLocale('en', {
    weekdaysMin : function (momentToFormat, format) {
        return weekdaysMin[momentToFormat.day()];
    }
});

longDateFormat 1.1.0+

// 从 2.12.0 开始
moment.updateLocale('en', {
    longDateFormat : Object
});

// 从 2.8.1 至 2.11.2
moment.locale('en', {
    longDateFormat : Object
});

// 废弃于 2.8.1
moment.lang('en', {
    longDateFormat : Object
});

Locale#longDateFormat 应是一个包含每个长日期格式 L LL LLL LLLL LT LTS 的键/值对的对象。 LT 应是时间格式,也用于 moment#calendar

moment.updateLocale('en', {
    longDateFormat : {
        LT: "h:mm A",
        LTS: "h:mm:ss A",
        L: "MM/DD/YYYY",
        l: "M/D/YYYY",
        LL: "MMMM Do YYYY",
        ll: "MMM D YYYY",
        LLL: "MMMM Do YYYY LT",
        lll: "MMM D YYYY LT",
        LLLL: "dddd, MMMM Do YYYY LT",
        llll: "ddd, MMM D YYYY LT"
    }
});

可以排除小写的 l 令牌,它们将会通过使用短令牌变体替换长令牌而自动创建。

moment.updateLocale('en', {
    longDateFormat : {
        LT: "h:mm A",
        LTS: "h:mm:ss A",
        L: "MM/DD/YYYY",
        LL: "MMMM Do YYYY",
        LLL: "MMMM Do YYYY LT",
        LLLL: "dddd, MMMM Do YYYY LT"
    }
});

relativeTime 1.0.0+

// 从 2.12.0 开始
moment.updateLocale('en', {
    relativeTime : Object
});
// 从 2.8.1 至 2.11.2
moment.locale('en', {
    relativeTime : Object
});

// 废弃于 2.8.1
moment.lang('en', {
    relativeTime : Object
});

Locale#relativeTime 应是用于 moment#from 的替换字符串的对象。

moment.updateLocale('en', {
    relativeTime : {
        future: "in %s",
        past:   "%s ago",
        s  : 'a few seconds',
        ss : '%d seconds',
        m:  "a minute",
        mm: "%d minutes",
        h:  "an hour",
        hh: "%d hours",
        d:  "a day",
        dd: "%d days",
        M:  "a month",
        MM: "%d months",
        y:  "a year",
        yy: "%d years"
    }
});

Locale#relativeTime.future 指向未来日期的前缀/后缀,而 Locale#relativeTime.past 则指向过去日期的前缀/后缀。 对于所有其他字符,单个字符指向单数,而双字符指向复数。

如果语言环境需要对令牌进行其他处理,则可以使用以下签名将令牌设置为函数。 该函数应返回一个字符串。

function (number, withoutSuffix, key, isFuture) {
    return string;
}

key 参数指向 Locale#relativeTime 对象中的替换键。(例如 s m mm h 等)

number 参数指向该键的单位数。 对于 m,该数字是分钟数,以此类推。

如果不带后缀显示令牌,则 withoutSuffix 参数将会为 true,如果带后缀显示令牌,则为 false。(之所以使用逻辑倒置,是因为默认的行为是显示后缀。)

如果要使用未来的后缀/前缀,则 isFuture 参数将会为 true,如果要使用过去的前缀/后缀,则为 false。

meridiem 1.6.0+

// 从 2.12.0 开始
moment.updateLocale('en', {
    meridiem : Function
});
// 从 2.8.1 至 2.11.2
moment.locale('en', {
    meridiem : Function
});

// 废弃于 2.8.1
moment.lang('en', {
    meridiem : Function
});

如果语言环境使用 'am/pm',则可以省略 Locale#meridiem,因为这些值是默认值。

如果语言环境需要对 am/pm 进行任何其他计算,则 Locale#meridiem 应是一个基于小时、分钟、和大写/小写返回正确字符串的回调函数。

moment.updateLocale('zh-cn', {
    meridiem : function (hour, minute, isLowercase) {
        if (hour < 9) {
            return "早上";
        } else if (hour < 11 && minute < 30) {
            return "上午";
        } else if (hour < 13 && minute < 30) {
            return "中午";
        } else if (hour < 18) {
            return "下午";
        } else {
            return "晚上";
        }
    }
});

meridiemParse 2.1.0+

// 从 2.12.0 开始
moment.updateLocale('en', {
    meridiemParse : RegExp
    isPM : Function
});

// 从 2.8.1 至 2.11.2
moment.locale('en', {
    meridiemParse : RegExp
    isPM : Function
});

// 废弃于 2.8.1
moment.lang('en', {
    meridiemParse : RegExp
    isPM : Function
});

如果输入的字符是中午12点以后,则 Locale#isPM 应返回 true。 这用于解析 a A 令牌。

moment.updateLocale('en', {
    isPM : function (input) {
        return ((input + '').toLowerCase()[0] === 'p');
    }
});

要配置应将哪些字符串解析为输入,则设置 meridiemParse 属性。

moment.updateLocale('en', {
    meridiemParse : /[ap]\.?m?\.?/i
});

calendar 1.3.0+

// 从 2.12.0 开始
moment.updateLocale('en', {
    calendar : Object
});
// 从 2.8.1 至 2.11.2
moment.locale('en', {
    calendar : Object
});

// 废弃于 2.8.1
moment.lang('en', {
    calendar : Object
});

Locale#calendar 应是具有以下格式的字符串。

moment.locale('en', {
    calendar : {
        lastDay : '[Yesterday at] LT',
        sameDay : '[Today at] LT',
        nextDay : '[Tomorrow at] LT',
        lastWeek : '[last] dddd [at] LT',
        nextWeek : 'dddd [at] LT',
        sameElse : 'L'
    }
});

每个 Locale#calendar 键也可以是一个回调函数,具有当前 moment 的范围,且第一个参数是描述现在的 moment。 它应该返回一个格式化字符串。

function callback (now) {
    return '[hoy a la' + ((this.hours() !== 1) ? 's' : '') + '] LT';
}

calendarFormat 2.14.0+

moment.calendarFormat = Function

这可以修改日历使用的令牌。

moment.calendarFormat = function (myMoment, now) {
    var diff = myMoment.diff(now, 'days', true);
    var nextMonth = now.clone().add(1, 'month');

    var retVal =  diff < -6 ? 'sameElse' :
        diff < -1 ? 'lastWeek' :
        diff < 0 ? 'lastDay' :
        diff < 1 ? 'sameDay' :
        diff < 2 ? 'nextDay' :
        diff < 7 ? 'nextWeek' :
        // 介绍 thisMonth 和 nextMonth。
        (myMoment.month() === now.month() && myMoment.year() === now.year()) ? 'thisMonth' :
        (nextMonth.month() === myMoment.month() && nextMonth.year() === myMoment.year()) ? 'nextMonth' : 'sameElse';
    return retVal;
};

ordinal 1.0.0+

// 从 2.12.0 开始
moment.updateLocale('en', {
    ordinal : Function
});
// 从 2.8.1 至 2.11.2
moment.locale('en', {
    ordinal : Function
});

// 废弃于 2.8.1
moment.lang('en', {
    ordinal : Function
});

Locale#ordinal 应是一个返回给定数字序数的函数。

moment.updateLocale('en', {
    ordinal : function (number, token) {
        var b = number % 10;
        var output = (~~ (number % 100 / 10) === 1) ? 'th' :
            (b === 1) ? 'st' :
            (b === 2) ? 'nd' :
            (b === 3) ? 'rd' : 'th';
        return number + output;
    }
});

2.0.0 开始,序数函数应同时返回数字和序数。以前仅返回序数。

2.1.0 开始,添加了令牌参数。它是要排序的令牌的字符串,例如:Md

有关序数的更多信息,参阅 Wikipedia

relativeTimeThreshold() 2.7.0+

moment.relativeTimeThreshold(unit);  // getter
moment.relativeTimeThreshold(unit, limit);  // setter

duration.humanize 具有阈值,这些阈值定义何时将一个单位视为一分钟、一小时等。 例如,默认情况下,超过45秒会被视为一分钟,超过22小时会被视为一天,依此类推。 要更改这些截止值,则使用 moment.relativeTimeThreshold(unit, limit),其中 unit 是 sssmhdM 之一。

单位 含义 用法
ss 几秒钟 被认为是秒钟的最少秒数。必须在设置 `s` 单位之后设置,或者不设置 `s` 单位。
s 秒钟 被认为是一分钟的最少秒数。
m 分钟 被认为是一小时的最少分钟数。
h 小时 被认为是一天的最少小时数。
d 被认为是一个月的最少天数。
M 月份 被认为是一年的最少月份数。
  // 检索现有的阈值。
  moment.relativeTimeThreshold('ss'); // 44
  moment.relativeTimeThreshold('s');  // 45
  moment.relativeTimeThreshold('m');  // 45
  moment.relativeTimeThreshold('h');  // 22
  moment.relativeTimeThreshold('d');  // 26
  moment.relativeTimeThreshold('M');  // 11

  // 设置新的阈值。
  moment.relativeTimeThreshold('ss', 3);
  moment.relativeTimeThreshold('s', 40);
  moment.relativeTimeThreshold('m', 40);
  moment.relativeTimeThreshold('h', 20);
  moment.relativeTimeThreshold('d', 25);
  moment.relativeTimeThreshold('M', 10);

注意:检索阈值新增于 2.8.1

注意:检索与设置 ss 阈值新增于 2.18.0

relativeTimeRounding() 2.14.0+

moment.relativeTimeRounding();  // getter
moment.relativeTimeRounding(fn);  // setter

duration.humanize 在将其提供给语言环境中指定的 relativeTime 格式字符串之前,会舍入一个可能为双精度的值。 要控制舍入,则可以使用 moment.relativeTimeRounding

var roundingDefault = moment.relativeTimeRounding();

// 向下舍入相对时间。
moment.relativeTimeRounding(Math.floor);

moment.relativeTimeThreshold('s', 60);
moment.relativeTimeThreshold('m', 60);
moment.relativeTimeThreshold('h', 24);
moment.relativeTimeThreshold('d', 31);
moment.relativeTimeThreshold('M', 12);

var a = moment();
a.subtract({hours: 23, minutes: 59, seconds: 59});
a.toNow()  // == '23 小时内'  '向下舍入到最近的小时'

// 回退到默认值。
moment.relativeTimeRounding(roundingDefault);

甚至可以选择完全不舍入:

var retainValue = function (value) {
    return value;
};
moment.relativeTimeRounding(retainValue);

var a = moment();
a.subtract({hours: 39});
a.toNow() // == '1.625 天内', '向下舍入到最近的年份'

now 2.11.0+

moment.now = function () { return +new Date(); }

如果要更改 Moment 看到的时间,可以指定一个方法,该方法返回自 Unix 纪元(1970年1月1日)以来的毫秒数。

默认为:

moment.now = function () {
    return +new Date();
}

这将会在调用 moment() 时使用,而在 format() 中省略令牌时使用的当前日期。 通常,任何需要当前时间的方法都可以在后台使用。

week 1.0.0+

// 从 2.12.0 开始
moment.updateLocale('en', {
    week : {
        dow : Int,
        doy : Int
     }
});
// 从 2.8.1 至 2.11.2
moment.locale('en', {
    week : {
        dow : Int,
        doy : Int
    }
});

// 废弃于 2.8.1
moment.lang('en', {
    week : {
        dow : Int,
        doy : Int
    }
});

Locale#week.dow 应是代表星期中第一天的整数,0是星期日、1是星期一、...、6是星期六。

Locale#week.doy 应是整数。 doydow 一起用于判断年份中的第一周。 doy 的计算方式为 7 + dow - janX,其中 janX 是一月的第一天(必须属于年份中的第一周)。

// ISO-8601,欧洲
moment.updateLocale("en", { week: {
  dow: 1, // 星期的第一天是星期一
  doy: 4  // 年份的第一周必须包含1月4日 (7 + 1 - 4)
}});

// 美国,加拿大
moment.updateLocale("en", { week: {
  dow: 0, // 星期的第一天是星期日
  doy: 6  // 年份的第一周必须包含1月1日 (7 + 0 - 1)
}});

// 许多阿拉伯国家
moment.updateLocale("en", { week: {
  dow: 6, // 星期的第一天是星期六
  doy: 12 // 年份的第一周必须包含1月1日 (7 + 6 - 1)
}});

// 也很常见
moment.updateLocale("en", { week: {
  dow: 1, // 星期的第一天是星期一
  doy: 7  // 年份的第一周必须包含1月1日 (7 + 1 - 1)
}});

invalidDate 2.3.0+

// 从 2.12.0 开始
moment.updateLocale('en', {
    invalidDate : String
});

// 从 2.8.1 至 2.11.2
moment.locale('en', {
    invalidDate : String
});

// 废弃于 2.8.1
moment.lang('en', {
    invalidDate : String
});

Locale#invalidDate 应是一个字符串。

moment.updateLocale("es", {
  invalidDate: "Fecha invalida"
});

Moment.js 也有时长的对象。 将 moment 定义为单个时间点,将 duration 定义为时间的长度。

时长没有定义的开始和结束日期。 它们是无上下文的。

从概念上讲,时长比 '今天下午2点到4点之间' 更类似于 '2 小时'。 因此,它们不是在依赖上下文的单位之间进行转换的好方法。

例如,一年可以定义为366天、365天、365.25天、12个月、52周。 没有上下文,试图将年转换为天是毫无意义的。 与使用 Durations 相比,使用 moment#diff 计算两个时刻之间的天数或年数要好得多。

duration() 1.6.0+

moment.duration(Number, String);
moment.duration(Number);
moment.duration(Object);
moment.duration(String);

要创建时长,则调用 moment.duration(),并以毫秒为单位。

moment.duration(100); // 100 毫秒

如果要使用毫秒以外的其他度量单位来创建 moment,则也可以传入度量单位。

moment.duration(2, 'seconds');
moment.duration(2, 'minutes');
moment.duration(2, 'hours');
moment.duration(2, 'days');
moment.duration(2, 'weeks');
moment.duration(2, 'months');
moment.duration(2, 'years');

同样,moment#addmoment#subtract的简写在这里也适用。

简写
years y
months M
weeks w
days d
hours h
minutes m
seconds s
milliseconds ms

moment#add 相似,如果需要多个不同的度量单位,则可以传入值的对象。

moment.duration({
    seconds: 2,
    minutes: 2,
    hours: 2,
    days: 2,
    weeks: 2,
    months: 2,
    years: 2
});

2.1.0 开始,moment 支持解析 ASP.NET 风格的时间跨度。 支持以下格式。

格式是以冒号分隔的小时、分钟、秒钟的字符串,例如 23:59:59。 天数可以加上点分隔符,如 7.23:59:59。 还支持部分秒数如23:59:59.999`。

moment.duration('23:59:59');
moment.duration('23:59:59.999');
moment.duration('7.23:59:59.999');
moment.duration('23:59'); // 新增于 2.3.0

2.3.0 开始,moment 还支持解析 ISO 8601 时长。

moment.duration('P1Y2M3DT4H5M6S');
moment.duration('P1M');

2.11.0 开始,支持时长的格式字符串,其中天数和剩下的时间之间有空格。

moment.duration('7 23:59:59.999');

2.13.0 开始,解析时长时支持混合的负号和正号。

moment.duration('PT-6H3M')

2.18.0 开始,支持无效的时长,类似于无效的时刻。 要创建无效的时长,可以为单位的值传入 NaN

在即将发布的版本中,预期无效的时长可以覆盖更多情况(例如单位的空值)。

moment.duration(NaN);
moment.duration(NaN, 'days');
moment.duration.invalid();

clone() 2.19.0+

moment.duration().clone();

创建时长的副本。 时长是可变的,就像 moment 对象一样,因此可以在某个时间点获取快照。

var d1 = moment.duration();
var d2 = d1.clone();
d1.add(1, 'second');
d1.asMilliseconds() !== d2.asMilliseconds();

humanize() 1.6.0+

moment.duration().humanize();

有时,只想要 moment#from 的所有优点,但又不想创建两个 moment,而只想显示一段时长。

使用 moment.duration().humanize()

moment.duration(1, "minutes").humanize(); // 1 分钟
moment.duration(2, "minutes").humanize(); // 2 分钟
moment.duration(24, "hours").humanize();  // 1 天

默认情况下,返回的字符串是没有后缀。 如果需要后缀,则按如下所示传入 true。

moment.duration(1, "minutes").humanize(true); // 1 分钟内

对于当前时间之前的后缀,则传入负数。

moment.duration(-1, "minutes").humanize(true); // 1 分钟前

无效的时长会被人性化为 Invalid Date 的本地化版本。

moment.duration.invalid().humanize(); // Invalid Date

milliseconds() 1.6.0+

moment.duration().milliseconds();
moment.duration().asMilliseconds();

要获取时长的毫秒数,则使用 moment.duration().milliseconds()

它将会返回 0 至 999 之间的数字。

moment.duration(500).milliseconds(); // 500
moment.duration(1500).milliseconds(); // 500
moment.duration(15000).milliseconds(); // 0

如果想要时长的长度(以毫秒为单位),则改用 moment.duration().asMilliseconds()

moment.duration(500).asMilliseconds(); // 500
moment.duration(1500).asMilliseconds(); // 1500
moment.duration(15000).asMilliseconds(); // 15000

seconds() 1.6.0+

moment.duration().seconds();
moment.duration().asSeconds();

要获取时长的秒数,则使用 moment.duration().seconds()

它将会返回 0 至 59 之间的数字。

moment.duration(500).seconds(); // 0
moment.duration(1500).seconds(); // 1
moment.duration(15000).seconds(); // 15

如果想要时长的长度(以秒为单位),则改用 moment.duration().asSeconds()

moment.duration(500).asSeconds(); // 0.5
moment.duration(1500).asSeconds(); // 1.5
moment.duration(15000).asSeconds(); // 15

minutes() 1.6.0+

moment.duration().minutes();
moment.duration().asMinutes();

与时长的其他获取器一样,moment.duration().minutes() 用于获取分钟数(0-59)。

moment.duration().asMinutes() 用于获取时长的长度(以分钟为单位)。

hours() 1.6.0+

moment.duration().hours();
moment.duration().asHours();

与时长的其他获取器一样,moment.duration().hours() 用于获取小时数(0-23)。

moment.duration().asHours() 用于获取时长的长度(以小时为单位)。

days() 1.6.0+

moment.duration().days();
moment.duration().asDays();

与时长的其他获取器一样,moment.duration().days() 用于获取天数(0-30)。

moment.duration().asDays() 用于获取时长的长度(以天为单位)。

weeks() 1.6.0+

moment.duration().weeks();
moment.duration().asWeeks();

与时长的其他获取器一样,moment.duration().weeks() 用于获取星期数(0-4)。

moment.duration().asWeeks() 用于获取时长的长度(以星期为单位)。

与时长的其他获取器不同,星期数获取器是作为天数的子集,且不会从天数中扣除。

注意:以星期为单位的时长的长度定义为 7 天。

months() 1.6.0+

moment.duration().months();
moment.duration().asMonths();

与时长的其他获取器一样,moment.duration().months() 用于获取月数(0-11)。

moment.duration().asMonths() 用于获取时长的长度(以月为单位)。

years() 1.6.0+

moment.duration().years();
moment.duration().asYears();

与时长的其他获取器一样,moment.duration().years() 用于获取年数。

moment.duration().asYears() 用于获取时长的长度(以年为单位)。

add() 2.1.0+

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

通过增加时间来更改原始的时长。

用于创建时长的相同的键和速记可以在此处用作第二个参数。

var a = moment.duration(1, 'd');
var b = moment.duration(2, 'd');
a.add(b).days(); // 3

注意,将无效的时长添加到任何其他时长会产生无效的时长。

subtract() 2.1.0+

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

通过减去时间来更改原始的时长。

用于创建时长的相同的键和速记可以在此处用作第二个参数。

var a = moment.duration(3, 'd');
var b = moment.duration(2, 'd');
a.subtract(b).days(); // 1

注意,将无效的时长添加到任何其他时长会产生无效的时长。

duration(x.diff(y)) 2.1.0+

var duration = moment.duration(x.diff(y))

可以将时长与 moment#diff 一起使用,以获取两个时刻之间的时长。 为此,只需将 moment#diff 方法传给 moment#duration,如下所示:

  var x = new moment()
  var y = new moment()
  var duration = moment.duration(x.diff(y))
  // 返回时长对象,其时长在 x 和 y 之间。

参阅此处以获取有关 moment#diff 的更多信息。

as() 2.1.0+

moment.duration().as(String);

作为 Duration#asX 的替代,可以使用 Duration#as('x')。 同样,moment#add 中的所有简写键也适用于此。

duration.as('hours');
duration.as('minutes');
duration.as('seconds');
duration.as('milliseconds');

无效的时长将会为所有单位返回 NaN

get() 2.1.0+

moment.duration().get(String);

作为 Duration#x() 获取器的替代,可以使用 Duration#get('x')。 同样,moment#add 中的所有简写键也适用于此。

duration.get('hours');
duration.get('minutes');
duration.get('seconds');
duration.get('milliseconds');

无效的时长将会为所有单位返回 NaN

toJSON() 2.9.0+

moment.duration().toJSON();

当将时长对象序列化为 JSON 时,它将会表示为 ISO8601 字符串。

JSON.stringify({
    postDuration : moment.duration(5, 'm')
}); // '{"postDuration":"PT5M"}'

无效的时长返回 json 表示的 Invalid Date

isDuration() 1.6.0+

moment.isDuration(obj);

要检查变量是否为 moment 的时长对象,则使用 moment.isDuration()

moment.isDuration() // false
moment.isDuration(new Date()) // false
moment.isDuration(moment()) // false
moment.isDuration(moment.duration()) // true
moment.isDuration(moment.duration(2, 'minutes')) // true

toISOString() 2.8.0+

moment.duration().toISOString();

返回 ISO 8601 标准指定的字符串形式的时长。

moment.duration(1, 'd').toISOString() // "P1D"

格式 PnYnMnDTnHnMnS 的说明:

单位 含义
P _P_ 代表周期。 放置在时长表示的开始处。
Y
M
D
T 在时间分量之前的指示符。
H 小时
M 分钟
S 秒钟

locale() 2.17.1+

moment.duration().locale();
moment.duration().locale(String);

可以使用 locale(...) 获取或设置时长的语言环境。 语言环境将会影响时长的字符串方法,例如 humanize()。 有关国际化的常用信息,请参见国际化章节。

moment.duration(1, "minutes").locale("en").humanize(); // a minute
moment.duration(1, "minutes").locale("fr").humanize(); // une minute
moment.duration(1, "minutes").locale("es").humanize(); // un minuto

humanize() 的后缀也已国际化:

moment.duration(1, "minutes").locale("en").humanize(true); // in a minute
moment.duration(1, "minutes").locale("fr").humanize(true); // dans une minute
moment.duration(1, "minutes").locale("es").humanize(true); // en un minuto

moment.duration(-1, "minutes").locale("en").humanize(true); // a minute ago
moment.duration(-1, "minutes").locale("fr").humanize(true); // il y a une minute
moment.duration(-1, "minutes").locale("es").humanize(true); // hace un minuto

Moment 公开了一些方法,这些方法可能对扩展库或编写自定义解析器的开发者有用。

normalizeUnits() 2.3.0+

moment.normalizeUnits(String);

Moment 的许多函数都允许调用者传入单位枚举的别名。 例如,下面的所有 get 都是等效的。

var m = moment();
m.get('y');
m.get('year');
m.get('years');

如果要扩展库,则可能需要访问 Moment 的工具,以便更好地使函数与 Moment 的函数保持一致。

moment.normalizeUnits('y');      // 'year'
moment.normalizeUnits('Y');      // 'year'
moment.normalizeUnits('year');   // 'year'
moment.normalizeUnits('years');  // 'year'
moment.normalizeUnits('YeARS');  // 'year'

invalid() 2.3.0+

moment.invalid(Object);

可以创建自己的无效 Moment 对象,这对于创建自己的解析器很有用。

var m = moment.invalid();
m.isValid();                      // false
m.format();                       // 'Invalid date'
m.parsingFlags().userInvalidated; // true

invalid 还接受一个对象,该对象指定要设置的解析标志。 这不会设置 userInvalidated 解析标志,除非它是指定的属性之一。

var m = moment.invalid({invalidMonth: 'Actober'});
m.parsingFlags().invalidMonth; // 'Actober'

无需指定 Moment 可以识别的解析标志。 但是,Moment 将会是无效的,并且解析标志将会由 parsingFlags() 返回。

其他一些开发者为 Moment.js 制作了插件,可能对你有用。

msdate

如果你在 .NET 中使用 OLE Automation 日期,则查看 Markit On Demand 的 moment-msdate。 使用此插件,可以将 OA 日期格式化为 JavaScript 日期,反之亦然。

moment 转换为 OA 日期:

moment().toOADate(); // 浮点数

或者,将 OA 日期转换为 moment

moment.fromOADate(41493); // Wed Aug 07 2013 00:00:00 GMT-0600 (MDT)

更多信息和详细文档可以在 GitHub 上找到 http://markitondemand.github.io/moment-msdate/

jdateformatparser

npm install moment-jdateformatparser

如果要使用 java.text.DateFormat,可以使用此插件。

例如,

moment("2013-12-24 14:30").formatWithJDF("dd.MM.yyyy");  // 返回格式化的日期 "24.12.2013"
moment().toJDFString("DD.MM.YYYY");  // 返回 Java 的格式模式 "dd.MM.yyyy"

该仓库位于 github.com/MadMG/moment-jdateformatparser

twix

npm install twix

另一个范围插件是 Isaac Cambron 的库 Twix。 它具有许多与范围相关的特性,并且擅长格式化范围。 例如,

var t = moment("1/25/1982 9:30 AM").twix("1/25/1982 1:30 PM");
t.isCurrent(); // false
t.count('minutes'); // 241
t.format();  // 'Jan 25, 1982, 9:30 AM - 1:30 PM'
t.simpleFormat("h:m"); // '9:30 - 1:30'

所有选项和特性的完整文档在这里

像这样在 npm 上可用:

npm install twix

或者只是从这里获取 JS 文件。

precise-range

npm install moment-precise-range-plugin

Rob Dawson 编写的 Precise Range 插件可用于显示日期/时间范围的准确的人类可读的表示形式:

moment("2014-01-01 12:00:00").preciseDiff("2015-03-04 16:05:06");
 // 1 year 2 months 3 days 4 hours 5 minutes 6 seconds
moment.preciseDiff("2014-01-01 12:00:00", "2014-04-20 12:00:00");
// 3 months 19 days

要获取原始数字值而不是字符串,则将 true 值作为第三个参数传给该方法:

moment.preciseDiff(m1, m2, true); 
// {years : 0, months : 1, days : 2, hours : 3, minutes : 4, seconds : 5, firstDateWasLater : false}

isocalendar

npm install moment-isocalendar

如果你正在寻找类似 Python 的 isocalendar 方法,则可以使用 Rocky Meza 的插件

moment-isocalendar

在 moment 上调用 isocalendar 方法将会返回如下数组:

[year, week_of_year, day_of_week, minutes_since_midnight]

moment().isocalendar(); // [2012, 8, 5, 870]

还可以从 isocalendar 数组重造 moment。

moment.fromIsocalendar([2011, 51, 5, 870]).format('LLLL');
// "Friday, December 23 2011 2:30 PM"

该仓库位于 github.com/fusionbox/moment-isocalendar

jalaali

npm install moment-jalaali

如果要使用 Jalaali 日历系统(Jalali、Persian、Khorshidi 或 Shamsi),则可以使用 Behrang Noruzi Niya 的插件 moment-jalaali

当安装后,它会封装 moment,且 moment 将可以格式化和解析 Jalaali 的年月。 这是一个简短的示例:

var m = moment('1360/5/26', 'jYYYY/jM/jD'); // 解析 Jalaali 日期。
m.format('jYYYY/jM/jD [is] YYYY/M/D'); // 1360/5/26 is 1981/8/17

该仓库位于 github.com/behrang/moment-jalaali

hijri

npm install moment-hijri

如果要使用 Hijri 日历,则可以使用 moment-hijri 插件。 moment-hijri 是基于 Umm al-Qura 计算得出的 Hijri 阴历的 moment 插件。 该插件由 Suhail Alkowaileet 开发。

当安装时,它将会封装 moment,且你将可以解析 Hijri 日期。 这是一个简短的示例:

m = moment('1410/8/28', 'iYYYY/iM/iD'); // 解析 Hijri 日期。
m.format('iYYYY/iM/iD [is] YYYY/M/D'); // 1410/8/28 is 1990/3/25

该仓库位于 github.com/xsoh/moment-hijri.

recur

npm install moment-recur

如果需要处理重复的日期,则可以使用 Casey Trimm 的插件 moment-recur

此插件将会允许你创建基于长度的间隔(天、周等)和基于日历的间隔(月份的日期、年份的月份等)。

它提供了一个 matches 函数来测试日期是否根据规则集重现,还提供了生成器函数来获取系列中的下一个和上一个日期。

仓库、文档和更多示例可以在 github.com/c-trimm/moment-recur 上找到。

var interval = moment( "01/01/2014" ).recur().every(2).days(); // 长度间隔
interval.matches( "01/03/2014" ); // true
interval.next( 2, "L" ); // ["01/03/2014", "01/05/2014"]
interval.forget( "days" ); // 删除规则
interval.dayOfMonth( 10 ); // 日历间隔
interval.matches( "05/10/2014" ); // true
interval.previous( 2, "L" ); // ["12/10/2013", "11/10/2013"]

twitter

如果想尝试像 Twitter 一样格式化推文的时间,则可以使用 @hijonathanmoment.twitter 插件。

这是显示人类可读的时间戳的长短版本的简单方法。

moment().subtract(5, 'hours').twitterLong();
// 5 hours

是的,它可以进行智能多元化。

moment().subtract(1, 'hour').twitterLong();
// 1 hour

还不够短吗?

moment().subtract(6, 'days').twitterShort();
// 6d

fquarter

如果需要财政、日历或学术季度,可以使用 @robgallenmoment-fquarter 插件。

最简单的是,只需在任何 moment 对象上调用 fquarter 方法。 它返回格式化的字符串,其中四月是第一季度。

moment("2013-01-01").fquarter();
// Q4 2012/13

可以将任何月份作为起始季度,例如七月:

moment("2013-01-01").fquarter(7);
// Q3 2012/13

如果需要日历季度,则从一月开始:

moment("2013-01-01").fquarter(1);
// Q1 2013

parseformat

npm install moment-parseformat

该插件提取日期/时间字符串的格式。

var format = moment.parseFormat('Thursday, February 6th, 2014 9:20pm');
// dddd, MMMM Do, YYYY h:mma
moment().format(format); // 格式化

这样就可以创建智能日期输入,让用户设置日期/时间,并提取用户的首选格式以供将来使用。 在 minutes.io 上找到其用法示例。

该插件由 @gr2m 编写。 链接:演示 | 源代码

round

npm install moment-round

For example, 该插件会将日期/时间四舍五入到给定的时间间隔。

例如,

require('moment-round');
var m = new moment(); // 2015-06-18 15:30:19
m.round(5, 'seconds'); // 2015-06-18 15:30:20
m.ceil(3, 'minutes'); // 2015-06-18 15:33:00
m.floor(16, 'hours'); // 2015-06-18 00:00:00
m.ceil(21, 'hours'); // 2015-06-18 21:00:00
m.ceil(20, 'hours'); // 2015-06-19 00:00:00

该仓库位于 github.com/WebDevTmas/moment-round

transform

bower install moment-transform

moment-transform 是一个通过模式操作日期的插件。 可以对 Moment 实例的各个部分(小时、月份等)使用基本操作(设置/添加/减少)。

moment().transform('YYYY-MM-+01 00:00:00.000'); // Tonight at midnight
moment().transform('14:30:00.000'); // Today, 2:30 pm
moment().transform('YYYY-MM--30 00:00:00.000'); // 30 days ago

可选的参数可以指定自定义的模式并强制使用严格的模式(默认情况下,在传入的字符串中非字母字符不是必需的)。

moment().transform('+01MMYYYY', 'DD/MM/YYYY', false); // Tomorrow, same time
moment().transform('+01MMYYYY', 'DD/MM/YYYY', true); // Invalid date

示例在这里,仓库在这里

taiwan

npm install moment-taiwan

如果要使用台湾日历系统,可以使用 Bradwoo8621 的插件 moment-taiwan

当安装后,它将会可以封装 moment,且将可以格式化和解析台湾年份。 这是一个简短的示例:

m = moment('104/01/01', 'tYY/MM/DD') // 解析 Taiwan 日期
m.format('tYY/MM/DD [is] YYYY/M/D') // 104/01/01 is 2015/01/01

m.twYear() // 104

该仓库位于 github.com/bradwoo8621/moment-taiwan

timer

npm install moment-timer

这是一个 Moment.js 插件,允许使用计时器,该计时器比原生的 JavaScript 计时器提供更多的控制权。 基本上,这是对 JavaScript 自有的 setInterval 和 setTimeout 的重写。

例如,

var timer = moment.duration(5, "seconds").timer({loop: true}, function() {
  // 回调
});

该仓库位于 github.com/SeverinDK/moment-timer

business

npm install moment-business

这是一个 Moment.js 库,允许 Moment 在西方工作周中进行操作:7 天工作周,其中周六和周日为非工作日。

例如,

import business from 'moment-business';

// 如果 moment 是周一至周五,则为 true,否则为 false。
business.isWeekDay(someMoment);

// 增加五个工作日到 Moment。
business.addWeekDays(someMoment, 5);

该仓库位于 github.com/jmeas/moment-business

shortformat

如果要以较短的方式格式化时间,可以使用 @researchgatemoment-shortformat 插件。

它基于和类似于 moment.twitter 插件,但输出不同。

moment().subtract(5, 'hours').short();
// 5h ago
moment().add(5, 'hours').short();
// in 5h

您还可以禁用相对时间模板的使用:

moment().subtract(1, 'hour').short(false);
// 1h

如果该日期在将来或过去过长,它将会显示为:

moment().subtract(500, 'days').short();
// 5 Mar, 1970

feiertage

npm install moment-feiertage --save

这个 moment-feiertage 是一个 Moment.js 插件,用于确定日期是否为德国假期。 假期取自维基百科(德国)。 确定日期是否为假日有点复杂,因为宗教节日每年变化,在德国的 16 个州内也不同。

DaniSchenk 创建。

var someDateInSomeStates = moment('2018-11-01').isHoliday(['BW', 'SH', 'TH']);
/* returns {
  allStates: false,
  holidayName: 'Allerheiligen',
  holidayStates: [ 'BW' ],
  testedStates: [ 'BW', 'SH', 'TH' ]
}*/

该仓库位于 github.com/DaniSchenk/moment-feiertage