在PHP中处理日期
Posted xjshipin
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在PHP中处理日期相关的知识,希望对你有一定的参考价值。
前言
有许多话题论坛又来了,话题很多人常常有困难。 其中一个问题是如何处理日期,将其转换成不同的格式,时区问题,等等。本教程将试图解决的许多常见问题与日期和时间相关的问题。
在数据库中存储日期和时间
包括如何在php中处理日期之前,我想谈一下应该如何日期存储在一个数据库中。 具体我要谈谈mysql。因为这就是我最的经验。 也有其他DBMS设施来处理日期和时间信息,所以你可以查看手册。
许多人“发明”自己的方式在数据库中存储日期,这不可避免地给了他们一些麻烦。 例如他们可能有一个VARCHAR字段类型和存储日期以DD / MM / YYYY格式。 这是错误的方法。
有许多不同的方法可以将日期正确地存储在一个数据库中。 一种方法是整数字段,存储一个Unix时间戳。 我不喜欢这种方法。 它让你无法使用MySQL的日期和时间函数,并且有潜在的问题Y2K38问题。
MySQL数据类型称为时间戳。 这将显示的日期和时间ISO 8601格式,即从最重要的部分(年)最重要的部分(第二)。 一个例子可能是2009-08-18 9:17:21。 额外的格式输入的时候,其实没有必要,所以2009081891721将是一样的。
还有一个数据类型称为DATETIME。 第一次看它时,它似乎相同的时间戳,但事实并非如此。 首先,时间戳Y2K38仍有问题的事情,所以它只能存储日期,可以用一个32位无符号整数表示从Unix纪元(1970-01-01就是)。 这给了一个上限2038-01-19 03:14:07。 DATETIME没有这个问题; 它可以存储日期从1000-01-01到9999-12-31。 最后,有一些数据类型称为日期和时间。 这些都是如果你只需要日期或时间只有一部分。
我的建议是使用DATETIME、日期或时间取决于您的需要。 事实上,有一年的类型。 使用MySQL的内置数据类型存储日期和时间允许您使用它日期和时间函数。
我不会使用数据库在本教程的其余部分。 示例假设您已经有一些字符串包含一些日期。
时区
这是一个非常常见的问题。 当使用date()函数在PHP中使用服务器时间总是生成日期和时间戳。 除非你是在一个不同的时区比你的服务器,这不是一个问题。 我有一个VPS(虚拟专用服务器)在英国,但我住在丹麦。 这是一个小时的时差。 如何获得PHP显示正确的时间给我吗?
因为我是服务器管理员,我可以改变服务器的时钟(这是我所做的)。 大多数人不能这样做,所以我们必须解决这个问题的一些替代方案。
如果你有访问php。 ini(或者可以改变它的指示使用Apache . htaccess文件)可以改变date.timezone指令(实际上,这需要设置的东西如果你不希望错误从PHP)。 否则你可以使用作用是()函数。 手册有有效的时区列表您可以使用这两个东西。 因为我在丹麦,我会选择欧洲/哥本哈根。
让我们试试:
回声日期(H:我:年代”);
我的电脑的当地时间是09:34:08,这也是输出。 现在我们将试图改变时区:
作用是(“美国/ New_York”); 回声日期(H:我:年代”);
我们会得到03:34:08。 所以它似乎工作(多么幸运!)。 这是一个非常好的方法。
如果我们需要多个日期不同的时区,但相同页面? 这非常简单。 考虑下面的例子:
作用是(“欧洲/哥本哈根”); 回声在哥本哈根召开的时间是: 。日期(H:我:年代”) 。PHP_EOL; 作用是(“美国/ New_York”); 回声”在纽约的时间是: 。日期(H:我:年代”) 。PHP_EOL; 作用是(“欧洲/莫斯科”); 回声在莫斯科的时间是: 。日期(H:我:年代”) 。PHP_EOL;
将目前的输出是:
在哥本哈根召开的时间是:09:45:56 在纽约的时间是:03:45:56 在莫斯科的时间是:11:45:56
如果你有用户从多个时区? 还简单! 问他们什么是他们的时区,并相应地设置它。 这个函数timezone_identifiers_list()给你一个数组的所有时区标识符,所以你可以用它来生成一个下拉列表中选择。 你也可以尝试确定,拍摄地但这超出了本教程的范围。
最后,PHP函数函数(),总是在格林尼治时间格式的日期。 如果你知道抵消在几秒钟内你可以做:
函数的(H:我:年代”,时间() +抵消美元);
,所以你可能会做的
函数的(H:我:年代”,时间() + 3600年);
一个偏移量的一个小时。 然而,这需要你DST要考虑进去。 并非所有国家遵守DST,一些不同于其他人。 我的建议是使用PHP的内置支持时区。
从一种格式转换到另一个地方
“我有一个约会在DD / MM / YYYY但是;我需要它。 救命!”
我们如何帮助这个人吗? 好吧,让我们分析这个问题。 每个日期由三部分组成:一天,月,年。 所以,我们需要做的是重新排序,使用连字符而不是斜杠。 我们有几个方式可以做到这一点。 让我们先试着分裂。 我们有一个函数调用爆炸()的。
oldDate美元= “18/08/2009”; / / DD / MM / YYYY 美元的部分=爆炸(‘ / ‘,oldDate美元); / * * *现在我们有: *部分美元[0]:一天 *部分美元[1]: *部分美元[2]: *我们也可以做: *列表(日,月,美元美元)=爆炸(“/”,oldDate美元); * / newDate美元= “{ $部分[1]} - { $部分[0]} { $部分[2]}”; / /; echo $ newDate; / / 08-18-2009
这似乎很好工作。 我们还可以使用正则表达式。 这基本上是一个一行程序:
oldDate美元= “18/08/2009”; newDate美元=preg_replace(“# ^( d { 2 })/( d { 2 })/( d { 4 })$ #”, ‘ $ 2 - $ 1 - $ 3 ‘,oldDate美元);
我不打算解释正则表达式在本教程中。 你可以看看这个正则表达式教程的。
任何其他方法吗? 是的,有! 因为它通常是编程,有很多方法可以做到一件事。 假设我们已经分手日期在三个变量美元一天,美元的月和美元一年我们可以用一个函数调用mktime()生成一个Unix时间戳,然后使用日期()格式它以这种方式:
美元的时间戳=mktime(0, 0, 0,美元的月,美元一天,美元一年); 回声日期(“m-d-Y”,美元的时间戳);
另一种方法是使用strtotime()一个格式化的字符串转换成一个Unix时间戳。 除了strtotime()不承认DD / MM / YYYY作为一个有效的日期格式,返回false。 也有模棱两可的问题。 考虑到字符串07-08-2009。 是8月7日还是7月8日? 它将是前者。
日期确认
如果你把一个日期作为输入(例如生日),这将是非常有用的知道它实际上是一个有效的日期。 有两个条件必须满足一个日期之前可以认为是有效的:
-
它必须符合特定格式(例如我们可能只希望YYYY-MM-DD)。
-
日期必须实际上存在(2009-02-29不存在,但2008-02-29)。
第一个条件是相当简单的,我们可以使用正则表达式。 第二个是稍微复杂一些。 我们将不得不考虑一个月的长度。 也许这是一个闰年,也许它不是吗? 幸运的是,我们不必担心; PHP有一个函数调用checkdate(),嗯…… 检查日期。 所以,正则表达式和checkdate()是我们所需要的。 一个小例子:
< ?php 如果 ($ _SERVER(“REQUEST_METHOD”] = = “职位” &&收取($ _POST(“日期”))) { 如果 (preg_match(“# ^( d { 4 })-( d { 2 })( d { 2 })$ #”,$ _POST(“日期”),$匹配) &&checkdate($匹配(2),$匹配(3),$匹配(1))) { 回声‘ < p > <强>有效日期< / >强壮! < / p > "; } 其他的 { 回声‘ < p > <强>无效日期< / >强壮! < / p > "; } 回声“人力资源> <”; } ? > <表单动作= "< ?php echo $ _SERVER(“PHP_SELF”] ? >”方法= " post " > <标签 为=“日期”>输入一个ISO 8601日期:< /标签> < input type = " text " name = "日期" id =“日期”< ?php如果 (!空($ _POST(“日期”])): ? >值= "< ?php echo htmlentities($ _POST(“日期”]) ? >”< ?php endif? >> <按钮 类型=“提交”>检查的有效性< /按钮> < /形式>
这个例子应该是相当简单的。 首先我们检查的格式字符串使用preg_match(),我们也提取月,日和年反向引用。 preg_match()返回true,如果字符串是否与模式匹配。 因为逻辑,从左到右的关联,preg_match()是评价第一,checkdate()仅仅是评估如果第一个操作数是正确的(如果左操作数是假的,和表达不可能返回true,所以评估正确的操作数是多余的,因此它不是的原因)。
如果你有了单独的字段日、月和年更简单,我们可以跳过检查格式。
您可能设置附加条件必须满足在考虑一个日期之前有效。 你可能会问约会间隔意味着第一个必须比过去早。 你可能只希望日期在过去或未来,或者他们可能要在一个特定的预设时间间隔。 最简单的方法是将日期转换为Unix时间戳。 从在此基本的整数的比较。 我把它作为练习。 一个更安全的赌注(记得Y2K38)可能使用DateTime::diff()
以上是关于在PHP中处理日期的主要内容,如果未能解决你的问题,请参考以下文章