我最近遇到了一个大问题,因为我有一个系统每周向客户付款。
众所周知,一年有52周,并且有标准。我使用PHP aka date('W')来获取日期的周数,根据标准ISO-8601计算。
以下是一些参考资料:
但这是问题:2009年有53周。似乎通过公历在400年内有71年有53周。这是我不知道的一件事,可能很多人也没有。
根据维基百科:
2009-12-31是2009-W53-4(ISO年2009有53周,延长了2009年的公历年,从周四开始和结束,两天结束,为期三天)。
并且PHP中的日期函数完全尊重它。
如果你查看MS Outlook,并在日历视图中显示星期几,它将显示52周 考虑到2009年12月28日至2010年1月3日第1周。这是另一个标准吗?美国标准还是什么?
如果是这样,那为什么PHP不支持它呢?有人做过支持这个的功能吗?
有53周是否正确?我们有欧洲和美国的客户。
答案 0 :(得分:5)
Outlook不遵循任何类型的周编号标准。它有两个设置来确定周编号,称为“一周的第一天”和“一年中的第一周”。
通过将“周的第一天”设置为星期一,将“第一周”设置为“第一个4天周”,可以模拟ISO标准。
每个用户都必须按照ISO标准进行此调整。
我知道没有单独的美国标准,显然,Outlook也没有。
答案 1 :(得分:4)
我认为你不会有问题。事实上,您遵循国际标准的日期和时间格式和计数(ISO8601
)。如果您有任何投诉的客户,只需将他们推荐给标准。
Outlook的周编号有点等同于以下内容:
$dummyWeek = floor((date('z') + (date('N') - 1)) / 7) + 1;
出于计费目的,您最好使用ISO8601
作为标准。事实上,如果你看一下你今年将要填补的税款,他们会将上一财政年度描述为53周。
Outlook计算方法的问题是一周不能保证为7天。例如,OW01-2010仅在2天内受到影响:1月1日星期五,1月2日星期六。这是一个非常短的计费周期。
ISO8601
周保证为7天,这就是我们每4/5/6年需要一个闰周的原因。
您更喜欢哪一种选择:
ISO8601
:偶尔有53周,但每一个都是7天。Outlook
:一年中有52/53周随机,但每周需要支付两次“半周”。答案 2 :(得分:2)
这是我解决它的方式。 注意:我在PHP中编码,但在SQL中实现的算法是我下面代码的相关部分。另请注意,我分别处理了'2028-12-31',因为它是一个特殊的日期,它给出54作为它的周数。
// generate an sql that calculates the outlook week of $date (until 2033)
function sqlWeek ($date) {
$week = "if( ". $date . " = '2028-12-31', 54, (week( " . $date . ", 0) + if( (year( " . $date . ") - 1) in (2011, 2016, 2022, 2033), 0, 1)) MOD (if (year( ". $date .") = 2028, 54, if( (year( ".$date." ) - 1) in (2011, 2016, 2022, 2033), 53, 52))))";
return "concat( if( char_length( ".$week." ) < 2, concat( '0', ".$week." ), ".$week." ), '/', year($date) )";
}
答案 3 :(得分:0)
美国以外的世界比内部更多 - 而ISO 8601可能在美国以外的地方使用得比在里面更广泛。
最初的声明'一年有52周'只是部分正确,正如您现在所发现的那样。就ISO周而言,如维基百科所述,您可以在第53周结束。在N年的第52周或N年的第53周,您可以有N + 1年的最多三天。在N年的第1周,您可以有N-1年的最多三天。而且你需要确定ISO'周 - 年'和'周' - 因为当公历年为N时,ISO周年可以是年N-1或N + 1(取决于哪个结束时)你正在与之合作的一年)。这就是为什么strftime()中有单独的格式说明符('%Y','%y','%g','%G')的原因(但请注意,POSIX标准认为在第一天之前的几天) 1月的星期一是本年度的第0周,而不是上一年的第52周或第53周。
“周”似乎没有任何可靠的“美国标准”。根据您使用的软件,您会得到不同的结果。如果你看一周的Oracle定义,那么一年的前七天是第1周;你在一年中的第53周有1天或2天。
另请参阅SO 274861了解ISO周数代码的实现。即使您不使用该语言编写代码,该算法也应该易于理解。
答案 4 :(得分:0)
请注意,如果您使用的是PHP,那么您可能也在使用MySQL。 MySQL 不遵循ISO-8601周惯例,但它足够接近您可能认为的那样。正如其他人注意到Outlook一样,试图模仿一种不明智的非标准计算周数的方法是不值得的!