javascript - MomentJS:关于不同区域设置的操作日期的解释。这是一个错误吗?

标签 javascript date momentjs

我想获取一年中第一周的第一天。

所以:

import moment from 'moment';  

const jan = moment([2017, 0]);
const firstDayWeekYear = jan.clone().week(1).day(1);
console.log("jan", jan.format('DD/MMM/YYYY')); // jan 01/Jan/2017
console.log("firstDayWeekYear", firstDayWeekYear.format('DD/MMM/YYYY')); // firstDayWeekYear 02/Jan/2017  (correct)

但是如果我使用意大利语言环境,我会得到这个

import moment from 'moment';
import 'moment/locale/it';

const jan = moment([2017, 0]);
const firstDayWeekYear = jan.clone().week(1).day(1);
console.log("jan", jan.format('DD/MMM/YYYY')); // 01/gen/2017
console.log("firstDayWeekYear", firstDayWeekYear.format('DD/MMM/YYYY')); // firstDayWeekYear 11/gen/2016  (why 2016?)

2018年它再次正常工作

 const jan = moment([2018, 0]);
    const firstDayWeekYear = jan.clone().week(1).day(1);
    console.log("jan", jan.format('DD/MMM/YYYY')); // 01/gen/2018
    console.log("firstDayWeekYear", firstDayWeekYear.format('DD/MMM/YYYY')); // firstDayWeekYear 01/gen/2018  (correct)

...但在 2021 年...

const jan = moment([2021, 0]);
const firstDayWeekYear = jan.clone().week(1).day(1);
console.log("jan", jan.format('DD/MMM/YYYY')); // 01/gen/2021
console.log("firstDayWeekYear", firstDayWeekYear.format('DD/MMM/YYYY')); // firstDayWeekYear 30/dic/2019  (why 2019?)

有人可以向我解释为什么在闰年之后该代码不起作用吗?这是一个错误吗?

编辑1: moment.utc() 创建相同的错误日期

编辑2: const firstDayWeekYear = jan.clone().isoWeek(1).day(1); 始终创建 11/gen/2016

最佳答案

以下代码如下。

根据Savvy time ,意大利使用 ISO 8601 方案对一年中的天数和周数进行编号。因此,对于意大利人来说,2017 年的第一周从 2017 年 1 月 2 日星期一开始。表达式:

moment([2017, 0]);

创建 2017 年 1 月 1 日星期日的日期,该日期(在 ISO 方案中)是 2016 年最后一周的最后一天。然后:

.week(1)

将日期设置为 2016 年第一周的同一天(即最后一天),即 2016 年 1 月 10 日星期日。然后:

.day(1)

应将其设置为该周的第一天,即 2016 年 1 月 4 日星期一。因此,如果您获得 1 gennaio(2017 年 1 月),则表示出了问题。

2018年,1月1日星期一也是2018年ISO第一周的ISO第一天。

2021 年,1 月 1 日是星期五,上一年(2020 年)的最后一周也是星期五。

.week(1)

应该去2020年1月3日星期五(即2020年第一周的星期五),然后

.day(1)

会将其移至该周的第一天,即 2019 年 12 月 30 日星期一(实际上是 2020 年第一周的第一个星期一)。

QED。

以下内容仅使用 ISO 周数和日数作为区域设置的替代。

var f = 'ddd D MMM YYYY';
var d = moment([2017,0]);
console.log(d.format(f)); // Sun 1 Jan 2017

d.isoWeek(1);
console.log(d.format(f)); // Sun 10 Jan 2017

d.isoWeekday(1);
console.log(d.format(f)); // Mon 4 Jan 2017

var e = moment([2021,0]);
console.log(e.format(f)); // Fri 1 Jan 2021

e.isoWeek(1);
console.log(e.format(f)); // Fri 3 Jan 2020

e.isoWeekday(1);
console.log(e.format(f)); // Mon 30 Dec 2019
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.18.1/moment.min.js"></script>

PS 我认为使用语言代码来定义语言环境的想法是错误的。 moment.js 的作者本可以使用 IANA tz 数据库区域设置(基于地理区域,即实际区域设置),但在使用语言时遵循 ECMA 402。但语言没有区域设置,许多语言(例如西类牙语、中文)在世界各地都使用。诸如一年的第一周和一周的第一天之类的规则往往是由官僚机构而不是语言来定义的。在意大利讲中文的人可能希望使用意大利语(地点)方案进行周编号,而不是中文方案,因此格式和时区等内容的地点应基于 IANA tz 数据库使用的地点。要使用的语言应该是一个完全独立的参数。

关于javascript - MomentJS:关于不同区域设置的操作日期的解释。这是一个错误吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46489512/

相关文章:

javascript - 从第一个调用的 promise 中获取第二个调用的响应

javascript - 数据名称添加数据html标签

javascript - Pikaday Datepicker 太多递归/堆栈溢出

javascript - 如何将 moment.js 加载到 webpack 中

javascript - 如何在使用javascript单击一次后禁用 Bootstrap 按钮

javascript - D3.js:从 JSON 数据定义序数轴

PHP:向日期添加秒数

java - 如何将字符串转换为日期 (HHMMMDD)(小时、月份、日期)

php - 在 URL 中传递英国日期

javascript - Jest 将 MomentJS 导入到未弹出的 React 应用程序中