Php 日期/时间添加的标准?
我正在寻找日期/时间添加的标准。我还没找到。我特别希望找到一个规范,定义在1月31日这样的日期上加上一个月时应该发生什么。正确答案是2月28日(/29日)?三月一日?三月二号 我看到了不同工具(本例中是PHP和MySQL)之间不一致的实现,我正试图找到某种标准来作为我工作的基础 不同的结果: PHPPhp 日期/时间添加的标准?,php,mysql,oracle,datetime,standards,Php,Mysql,Oracle,Datetime,Standards,我正在寻找日期/时间添加的标准。我还没找到。我特别希望找到一个规范,定义在1月31日这样的日期上加上一个月时应该发生什么。正确答案是2月28日(/29日)?三月一日?三月二号 我看到了不同工具(本例中是PHP和MySQL)之间不一致的实现,我正试图找到某种标准来作为我工作的基础 不同的结果: PHP $end = strtotime("+1 month", 1314835200); //1317513600 Sat, 01 Oct 2011 20:00:00 -0400 MySQL SEL
$end = strtotime("+1 month", 1314835200);
//1317513600 Sat, 01 Oct 2011 20:00:00 -0400
MySQL
SELECT UNIX_TIMESTAMP(DATE_ADD(FROM_UNIXTIME(1314835200), INTERVAL 1 MONTH));
#1317427200 Fri, 30 Sep 2011 20:00:00 -0400
Oracle
SELECT ADD_MONTHS('31-Aug-11', 1) FROM dual;
#30-SEP-11
(很抱歉更改了格式,我的oracle foo很弱)
Java
Calendar c = Calendar.getInstance();
c.clear();
c.set( 2011, Calendar.AUGUST, 31 );
c.add( Calendar.MONTH, 1 );
c.getTime()
#Fri Sep 30 00:00:00 EDT 2011
每月的第一天+1个月应等于下个月的第一天。在SQL Server上尝试此操作
SELECT CAST ('01/01/2012' AS DateTime), DATEADD (m, 1, '01/01/2012')
UNION ALL SELECT CAST ('02/01/2012' AS DateTime), DATEADD (m, 1, '02/01/2012')
UNION ALL SELECT CAST ('03/01/2012' AS DateTime), DATEADD (m, 1, '03/01/2012')
UNION ALL SELECT CAST ('04/01/2012' AS DateTime), DATEADD (m, 1, '04/01/2012')
UNION ALL SELECT CAST ('05/01/2012' AS DateTime), DATEADD (m, 1, '05/01/2012')
这导致
----------------------- -----------------------
2012-01-01 2012-02-01
2012-02-01 2012-03-01
2012-03-01 2012-04-01
2012-04-01 2012-05-01
2012-05-01 2012-06-01
----------------------- -----------------------
2012-01-31 2012-02-29
2012-01-30 2012-02-29
2012-01-29 2012-02-29
2012-01-28 2012-02-28
2012-01-27 2012-02-27
2012-01-26 2012-02-26
本月最后一天+1个月应等于下个月最后一天。这应该适用于下个月、本月、10个月等等
SELECT CAST ('01/31/2012' AS DateTime), DATEADD (m, 1, '01/31/2012')
UNION ALL SELECT CAST ('01/30/2012' AS DateTime), DATEADD (m, 1, '01/30/2012')
UNION ALL SELECT CAST ('01/29/2012' AS DateTime), DATEADD (m, 1, '01/29/2012')
UNION ALL SELECT CAST ('01/28/2012' AS DateTime), DATEADD (m, 1, '01/28/2012')
UNION ALL SELECT CAST ('01/27/2012' AS DateTime), DATEADD (m, 1, '01/27/2012')
UNION ALL SELECT CAST ('01/26/2012' AS DateTime), DATEADD (m, 1, '01/26/2012')
这导致
----------------------- -----------------------
2012-01-01 2012-02-01
2012-02-01 2012-03-01
2012-03-01 2012-04-01
2012-04-01 2012-05-01
2012-05-01 2012-06-01
----------------------- -----------------------
2012-01-31 2012-02-29
2012-01-30 2012-02-29
2012-01-29 2012-02-29
2012-01-28 2012-02-28
2012-01-27 2012-02-27
2012-01-26 2012-02-26
看看31、30、29都变成了2月29日(2012年是闰年)
p、 我去掉了时间部分(全部为零)以帮助它更具可读性没有广泛接受的标准。不同实现的原因是人们不能就标准应该是什么达成一致。许多流行的软件系统给出了没有人会想到的答案。因此,要告诉用户您的系统将提供什么,文档总是必要的。然而,你选择的方法是基于你认为大多数人会期望的 我想大多数街上的人都会同意:
那么,就这样吧\ 根据POSIX.1-2001标准,下个月(在调用
mktime
之前增加tm_mon
)是通过调整值来完成的,直到它们合适为止。例如,从2001年1月31日起的下个月是2001年3月3日。这是因为31的tmu-mday
对于1(2月)的tmu-mon
无效,因此它被标准化为2(3月)的tmu-mon
和3的tmu-mday
从2000年1月31日起的下一个月是2000年3月2日,因为2月在那一年有29天。从1月开始的下一个月,2038不存在,这取决于
。检查SQL标准,我打赌你可以找到下个月的不同含义。我怀疑ISO8601可能会给你另一个选择。重点是,有许多不同的行为,“下个月”的含义是非常特定于领域的
编辑:我想我已经发现了SQL-92是如何处理它的,显然要求从1月31日开始的下个月是一个错误
链接:
- SQL-92:
- POSIX:(虽然显然该版本现在遵从ISO C,但它似乎不那么清晰。尽管我机器上的mktime手册页很清晰)
- ISO C:
- 爪哇:
SELECT
ADDDATE(DATE('2010-12-31'), INTERVAL 1 MONTH) 'Dec + Month',
ADDDATE(DATE('2011-01-31'), INTERVAL 1 MONTH) 'Jan + Month',
ADDDATE(DATE('2011-02-28'), INTERVAL 1 MONTH) 'Feb + Month',
ADDDATE(DATE('2011-03-31'), INTERVAL 1 MONTH) 'Mar + Month';
输出:
Dec + Month Jan + Month Feb + Month Mar + Month
2011-01-31 2011-02-28 2011-03-28 2011-04-30
十二月+一月+二月+三月+月份
2011-01-31 2011-02-28 2011-03-28 2011-04-30
我的结论是:
2011-01-31+P1M=2011-02-28
。我相信这是日期时间库中最广泛选择的默认选择,因此是事实上的标准
为此提供了一种策略模式,有四种选择,请参见
更有趣的问题是2011-01-31+P1M-1D
的答案是什么。如果你加上月份,然后解决无效的日期,然后减去日期,你得到2011-02-27。但我认为大多数用户都期望2011-02-28,因为这段时间是一次性增加的。看看ThreeTen是怎么处理的
我曾考虑尝试编写一个通用的日期/时间计算最佳实践,或实际的规范,但实际上没有时间 试试mysql日期函数: 选择ADDDATE('2011-01-31',间隔1个月)//2011-02-28 输入带有闰年的日期
选择ADDDATE('2012-01-31',间隔1个月)//2012-02-29我相信事实上的标准是ISO 8601。不幸的是,存在许多歧义,例如: 未定义日期算术
2001-03-30 + P1M = 2001-04-29 (Add 30 days)
2001-03-30 + P1M = 2001-04-30 (Add 1 mon.)
加法不是交换的或结合的
2001-03-30 + P1D + P1M = 2001-04-30
2001-03-30 + P1M + P1D = 2001-05-01
减法不是加法的倒数
小数的精度可能会有所不同
完整规格可在以下网址找到:
我认为每种产品都试图遵守一个不可能实现的标准。模棱两可的部分可以解释,因此每个人都可以解释。这是同一个标准,打开了我们对千年虫
我喜欢我自己