似乎周计算算法不够通用,因为它似乎无法正确地处理某些道琼斯/ doy组合:
// see http://en.wikipedia.org/wiki/Seven-day_week#cite_ref-15
moment.locale(moment.locale(), { week: { dow: 6, doy: 1 } });
moment("2012-12-28", "YYYY-MM-DD").week(); // 51 -- should be 52?
moment("2012-12-29", "YYYY-MM-DD").week(); // 52 -- should be 1
moment("2013-01-01", "YYYY-MM-DD").week(); // 52 -- should be 1
moment("2013-01-08", "YYYY-MM-DD").week(); // 53 -- should be 2
moment("2013-01-11", "YYYY-MM-DD").week(); // 53 -- should be 2
moment("2013-01-12", "YYYY-MM-DD").week(); // 1 -- should be 3
moment().weeksInYear(2012); // 52
我假设weekOfYear
函数有些问题,除非我做错了什么?
有什么想法吗? 这会影响许多地区,这些地区的一周的第一天不是星期日或星期一。 如果错误已通过验证,我应该提交请求以进行更好的weekOfYear
计算,还是已经有计划纠正当前算法?
我必须承认, doy
设置让我很困惑。 { dow: 6, doy: 12 }
表示该周从星期六开始,第1周是从1月1日开始的一周。 如果我理解正确, {dow:6, doy: 1}
意味着第一周离开包含12月26日。
我在拉取请求中添加了带有{ dow: 6, doy: 12 }
的测试。
您是说{ dow: 6, doy: 1 }
吗? 我认为doy
值大于7并没有任何实际含义。
不,我的意思是{dow: 6, doy: 12}
。 请注意, doy
不是1月的第一天。 {dow: 6, doy: 12}
是阿拉伯国家/地区的标准-该周从周六开始,第一周是包含1月1日的一周。
该错误实际上不在从日期算起的星期中,而只是在另一个方向上。
哇,如果是这种情况,那么这一次一直误会doy
。
确实,根据文档, localeData.firstDayOfYear()
可以返回0到15之间的任何整数,但这对我来说似乎很奇怪。
只是为了帮助我理解,您能解释一下为什么是12而不是1吗? 而会是什么一个doy
的1
或4
,则意味着在这种情况下? 确切地说,数学在这里如何工作? 您似乎对此有很好的了解。
我找到了一个很好的解释,这使doy
含义更加明显,尽管我似乎仍然无法弄清楚它怎么可能大于6。
@icambron ,请给我
@usmonster自从我看了很久以来,但是我的头顶...是的,我也不明白。 抱歉,我帮不上忙。 每当我写链接解释时,我都只是写了一堆Moment的实现来处理几周,因此我可能那时就明白了,但是doy
值似乎不等于6,所以这种解释似乎并不那么有趣。 。
我无法解释doy
的定义方式,但是您可以将其设置为7 + dow - janX
,其中janX
是必须属于该周的1月10日1号
因此,如果1月1日必须属于第一周,而星期六是一周的第一天,则doy = 7 + 6 - 1 = 12
。 对于ISO,美国为doy = 7 + 1 - 4 = 4
对于美国为doy = 7 + 0 - 1 = 6
。
嗯,如果是这种方式的_implemented_,我认为这是实现问题。 我没有看到其他定义(例如ISO,Unicode TR35)定义每周的计算。 API中的注释甚至都没有暗示这是怎么回事,尽管现在我注意到已经编写了假设这种逻辑的测试,例如,我看到这样的行:
dow : 1, // Monday is the first day of the week.
doy : 7 // The week that contains Jan 1st is the first week of the year.
并在另一个文件中:
dow : 6, // Saturday is the first day of the week.
doy : 12 // The week that contains Jan 1st is the first week of the year.
因此,您对实施的评估看起来很准确。 尽管如此,还是感觉很糟糕,好像测试是为了匹配损坏的实现而编写的。
这尤其令人沮丧,因为要做的更干净的事情是只修复实现,使其做到直观(例如在第一周必须使用“ janX
”),但是现在修复该问题就不会了。向后兼容。 啊。
另一种选择是弃用doy
并为周配置引入新选项,例如minDays
或dom
,以指定“一月天”的最小数量(1- 7)应该在一年的第一周。 如果不小心指定了doy
,它将被覆盖。
有什么想法吗?
据我所知,我们已经在等周内设置了代码,然后我们就滥用了这一事实,并确保数字能够使它起作用。
如果我们将语义更改为对用户更有意义,那可能会更好。 但是它应该向后兼容(因此新方法公开了新数字)。
在您的示例中,如果将doy加7几次,则可以使其正常工作,因为它相对于dow。
以#2336结尾
您好@ichernev。 :)回到一年后的今天,我仍然支持实现更有意义的语义,尽管我几乎可以肯定,在不更改语法的情况下就不可能做到向后兼容。
如果您将doy加7几次,则可以使其生效,因为它相对于dow。
我不认为情况总是如此。例如,在建议的语义更改前后, { dow: 0, doy: 6 }
并不意味着同一件事。 (这就是为什么我建议弃用doy
以便使用另一个名称的原因。)
我应该在哪里寻求更多反馈? 尽管可以将对话移至moment / momentjs.com#279,但如果更合适,则可以打开一个新的问题,因此该特定问题已解决。
我还想解决这个问题,因为我花了额外的时间试图弄清楚doy
工作原理,并且必须下载执行该操作的源代码。 就像@usmonster所建议的那样,引入一个新的,在语义上更相关的设置变量将是很棒的。
最有用的评论
我无法解释
doy
的定义方式,但是您可以将其设置为7 + dow - janX
,其中janX
是必须属于该周的1月10日1号因此,如果1月1日必须属于第一周,而星期六是一周的第一天,则
doy = 7 + 6 - 1 = 12
。 对于ISO,美国为doy = 7 + 1 - 4 = 4
对于美国为doy = 7 + 0 - 1 = 6
。