处理日期和时间是让程序员头疼的问题之一。同时,它们又是软件开发的基础,从元数据和事物排序到基于时间的触发器,以及介于两者之间的大量应用都离不开它们。
日期和时间也容易出错。处理不当,它们可能会让最终用户和程序员同事都感到困惑。
这是一份关于如何在PHP编程语言中处理日期和时间的快速指南。它旨在作为您最常见需求(如日期格式化和调整)的参考。它很简单,但很可能涵盖您 80% 的需求。
这项研究得到了 Frontend Masters 的支持,Frontend Masters 是 CSS-Tricks 的官方学习合作伙伴。
需要前端开发培训?
Frontend Masters 是学习的最佳场所。他们提供关于所有最重要的前端技术的课程。有兴趣成为全栈开发人员吗?这是您的最佳选择:
参加课程 ### 获取当前日期和时间
需要注意的是,日期和时间可以用三种形式表示:时间戳(即纪元时间)、DateTime 对象和字符串。
首先,获取当前日期和时间的代码:
<?php $now = new DateTime(); var_dump($now); // object(DateTime)#1 (3) { // ["date"]=?> // string(26) "2021-10-13 22:25:11.790490" // ["timezone_type"]=> // int(3) // ["timezone"]=> // string(12) "Asia/Jakarta" // }
这提供了一个 DateTime 对象,可用于创建日期和时间字符串:
<?php $now = new DateTime(); echo $now-?>format("Y-m-d"); // 2021-10-13 echo $now->format("Y-m-d h:i:s A"); // 2021-10-13 10:10:31 PM
您可以直观地理解 Y 代表年份,m 代表月份,d 代表月份中的日期,等等。完整的参数列表可以在 PHP 手册中找到,但我会在此处列出一些最常用的参数以供参考。
DateTime 对象可以转换为时间戳:
<?php $now = new DateTime(); echo $now-?>getTimestamp(); // 1634139081
但是我们也可以在不构造 DateTime 对象的情况下获取当前时间戳:
<?php echo time(); // 1634139081</pre?><h3>构造特定时间的 DateTime 对象</h3> <p>如果我们想为特定时间(例如 2011 年 7 月 14 日)构造一个 DateTime 对象,该怎么办?我们可以将格式化的日期字符串传递给构造函数:</p> <?php $date = new DateTime("2011-07-14"); var_dump($date); // object(DateTime)#1 (3) { // ["date"]=?> // string(26) "2011-07-14 00:00:00.000000" // ["timezone_type"]=> // int(3) // ["timezone"]=> // string(12) "Asia/Jakarta" // } <p>构造函数也接受其他格式:</p> <?php $date = new DateTime("14-07-2011"); var_dump($date); // object(DateTime)#1 (3) { // ["date"]=?> // string(26) "2011-07-14 00:00:00.000000" // ["timezone_type"]=> // int(3) // ["timezone"]=> // string(12) "Asia/Jakarta" // } <p>但是要注意模棱两可的格式,例如:</p> <?php $date = new DateTime("07/14/2011"); var_dump($date); // object(DateTime)#1 (3) { // ["date"]=?> // string(26) "2011-07-14 00:00:00.000000" // ["timezone_type"]=> // int(3) // ["timezone"]=> // string(12) "Asia/Jakarta" // } <p>您可能认为每个人都应该熟悉美国的日期格式。但并非每个人都熟悉,而且它的解释可能不同。PostgreSQL 也不例外。</p> CREATE TABLE IF NOT EXISTS public.datetime_demo ( created_at date ); insert into datetime_demo (created_at) values ('07/12/2011'); select created_at from datetime_demo; /* 2011-12-07 */ <p>您可能认为这将返回 2011 年 7 月 12 日,但它返回的是 2011 年 12 月 7 日。更好的方法是使用显式格式:</p> <?php $date = DateTime::createFromFormat('m/d/y', "10/08/21"); var_dump($date); //object(DateTime)#2 (3) { // ["date"]=?> // string(26) "2021-10-08 16:00:47.000000" // ["timezone_type"]=> // int(3) // ["timezone"]=> // string(12) "Asia/Jakarta" //} <p>如果我们想从时间戳构造一个 DateTime 对象,该怎么办?</p> <?php $date = new DateTime(); $date-?>setTimestamp(1634142890); var_dump($date); //object(DateTime)#1 (3) { // ["date"]=> // string(26) "2021-10-13 23:34:50.000000" // ["timezone_type"]=> // int(3) // ["timezone"]=> // string(12) "Asia/Jakarta" // } <p>如果我们想将时间戳对象转换为格式化的日期字符串,则不必创建 DateTime 对象:</p> <?php echo date("Y-m-d h:i A", time()); // 2021-10-14 04:10 PM</pre?><h3>时区</h3> <p>我们可以创建一个包含时区信息的 DateTime 对象,例如,如果我们处理的是太平洋标准时间、东部夏令时间等。</p> <?php $timezone = new DateTimeZone("America/New_York"); $date = new DateTime("2021-10-13 05:00", $timezone); var_dump($date); // object(DateTime)#1 (3) { // ["date"]=?> // string(26) "2021-10-13 05:00:00.000000" // ["timezone_type"]=> // int(3) // ["timezone"]=> // string(16) "America/New_York" // } // 例如,东部夏令时间:纽约 $date = new DateTime("2021-10-13 05:00 EDT"); var_dump($date); // object(DateTime)#2 (3) { // ["date"]=> // string(26) "2021-10-13 05:00:00.000000" // ["timezone_type"]=> // int(2) // ["timezone"]=> // string(3) "EDT" // } $date = new DateTime("2021-10-13 05:00 -04:00"); var_dump($date); // object(DateTime)#1 (3) { // ["date"]=> // string(26) "2021-10-13 05:00:00.000000" // ["timezone_type"]=> // int(1) // ["timezone"]=> // string(6) "-04:00" // } <p>有三种方法可以创建包含时区信息的 DateTime 对象。timezone_type 为每种方法接受不同的值。</p> <p>但是,假设我们想将以纽约时区显示的日期和时间转换为以雅加达时区显示,该怎么办?</p> <?php $newYorkTimeZone = new DateTimeZone("America/New_York"); $date = new DateTime("2021-11-11 05:00", $newYorkTimeZone); echo $date-?>format("Y-m-d h:i A"); // 2021-11-11 05:00 AM $jakartaTimeZone = new DateTimeZone("Asia/Jakarta"); $date->setTimeZone($jakartaTimeZone); echo $date->format("Y-m-d h:i A"); // 2021-11-11 05:00 PM <p>当纽约是凌晨 5:00 时,同一天的雅加达是下午 5:00。2021 年 11 月 11 日,雅加达比纽约快 12 小时。但一个月前,雅加达只比纽约快 11 小时,如下所示:</p> <?php $newYorkTimeZone = new DateTimeZone("America/New_York"); $date = new DateTime("2021-10-11 05:00", $newYorkTimeZone); echo $date-?>format("Y-m-d h:i A"); // 2021-10-11 05:00 AM $jakartaTimeZone = new DateTimeZone("Asia/Jakarta"); $date->setTimeZone($jakartaTimeZone); echo $date->format("Y-m-d h:i A"); // 2021-10-11 04:00 PM <p>PHP 会自动处理夏令时。</p> <h3>本地化</h3> <p>这是在美国显示日期和时间的常用方法:</p> <?php $now = new DateTime(); echo $now-?>format("m/d/Y h:i A"); // 10/14/2021 03:00 PM <p>但是法国的某个人可能更喜欢与其地区更常见的格式。他们可能会抱怨说“这太可怕了”。首先,除了美国之外,没有人将月份放在日期之前。其次,法国不使用 AM 或 PM——他们像军方一样使用 24 小时制(例如 14:00 而不是下午 2:00)。这就是让法国当地人满意的做法。</p> <?php $now = new DateTime(); echo $now-?>format("d/m/Y H:i"); // 14/10/2021 15:00 <p>但这需要深入了解特定国家或地区。相反,我们可以对日期进行本地化。要对日期进行本地化,我们需要安装 PHP 的国际化支持。在 Ubuntu 中,我们可以执行此步骤:</p> $ sudo apt-get install php-intl <p>要以法语显示日期和时间,我们可以使用 IntlDateFormatter:</p> $locale = "fr_FR.UTF-8"; $formatter = new IntlDateFormatter($locale, IntlDateFormatter::FULL, IntlDateFormatter::SHORT, "Asia/Singapore"); $date = new DateTime("2020-10-10 00:00 UTC"); echo $formatter->format($date); // samedi 10 octobre 2020 à 08:00 <p>您将法语语言环境作为 IntlDateFormatter 的第一个参数传递。<br>第二个参数是日期的格式。第三个参数是时间的格式。显示日期和时间的时区位于第四个参数中。</p> <p>除了 IntlDateFormatter::FULL 和 IntlDateFormatter::SHORT 之外,其他常用的格式还有 IntlDateFormatter::NONE、IntlDateFormatter::LONG<br>和 IntlDateFormatter::MEDIUM。</p> <p>如果您对时间或第三个参数使用 IntlDateFormatter::NONE,则表示您不包含格式中的时间:</p> $locale = "fr_FR.UTF-8"; $formatter = new IntlDateFormatter($locale, IntlDateFormatter::LONG, IntlDateFormatter::NONE, "Asia/Singapore"); $date = new DateTime("2020-10-10 00:00 UTC"); echo $formatter->format($date); // 10 octobre 2020 <h3>时间旅行</h3> <p>让我们进行时间旅行,回到过去和未来。首先,让我们了解 DateInterval:</p> <?php $interval = new DateInterval("P4M1W2DT2H5M"); // P 4M 1W 2D T 2H 5M // // P = 周期间隔(年、月、周、日) // 4M = 4 个月 // 1W = 1 周 // 2D = 2 天 // // T = 时间间隔(小时、分钟、秒) // 2H = 2 小时 // 5M = 5 分钟</pre?><p>P 和 T 用于分隔周期间隔和时间间隔。以下是我们如何前往未来的方法:</p> <?php $date = new DateTime("2021-10-14"); $interval = new DateInterval("P2D"); // 2 天 $futureDate = $date-?>add($interval); echo $futureDate->format("Y-m-d"); // 2021-10-16 <p>以下是我们如何回到过去的方法:</p> <?php $date = new DateTime("2021-10-14 10:00"); $interval = new DateInterval("PT6H"); // 6 小时 $pastDate = $date-?>sub($interval); echo $pastDate->format("Y-m-d H:i"); // 2021-10-14 04:00 <p>如果我们想使用星期几的名称进行时间旅行,我们可以结合使用 strtotime() 函数和 DateTime 对象的 setTimestamp() 方法:</p> <?php $nextTuesday = strtotime("next tuesday"); $date = new DateTime("2021-10-14"); $date-?>setTimestamp($nextTuesday); echo $date->format("Y-m-d"); // 2021-10-19 <p>请参阅 PHP 文档中 strtotime() 参数的完整列表。</p> <h3>定期发生的日期和时间</h3> <p>日历应用程序中的一项常见功能是设置重复提醒,例如每两天或每周一次。我们可以使用 DatePeriod 来表示一段时间:</p> <?php $start = new DateTime("2021-10-01"); $end = new DateTime("2021-11-01"); $interval = new DateInterval("P1W"); // 1 周 $range = new DatePeriod($start, $interval, $end); // 从 2021 年 10 月 1 日开始(包含),每 1 周跳过一次 // 直到 2021 年 11 月 1 日(不包含) foreach ($range as $date) { echo $date-?>format("Y-m-d") . "n"; } // 2022-10-01 // 2022-10-08 // 2022-10-15 // 2022-10-22 // 2022-10-29 <h3>多少天前?</h3> <p>您知道像 Twitter 这样的服务会显示某人 X 分钟/小时/天/等等之前发布的内容吗?我们可以通过计算当前时间和该操作发生时间之间经过的时间来做到这一点。</p> <?php $date = new DateTime("2022-10-30"); $date2 = new DateTime("2022-10-25"); $date3 = new DateTime("2022-10-10"); $date4 = new DateTime("2022-03-30"); $date5 = new DateTime("2020-03-30"); function get_period_ago($endDate, $startDate) { $dateInterval = $endDate-?>diff($startDate); if ($dateInterval->invert==1) { if ($dateInterval->y > 0) { return $dateInterval->y . " years agon"; } if ($dateInterval->m > 0) { return $dateInterval->m . " months agon"; } if ($dateInterval->d > 7) { return (int)($dateInterval->d / 7) . " weeks agon"; } if ($dateInterval->d > 0) { return $dateInterval->d . " days agon"; } } } echo get_period_ago($date, $date2); // 5 days ago echo get_period_ago($date, $date3); // 2 weeks ago echo get_period_ago($date, $date4); // 7 months ago echo get_period_ago($date, $date5); // 2 years ago <p>从 diff() 方法获取 DateInterval 对象后,请确保通过检查 invert 属性来确保 $startDate 变量在过去。然后检查 y、m 和 d 属性。</p> <p>可以在此处 PHP 文档中找到 DateInterval 对象属性的完整列表。</p> <h3>接下来的步骤?</h3> <p>现在您已经掌握了一些处理日期和时间时常用的 PHP 代码片段。需要获取当前日期和时间吗?也许您需要以某种方式格式化日期,或者包含本地时区,或者比较日期。所有这些都在这里!</p> <p>当然,我们还没有讨论更多关于日期和时间的方法和函数——例如与日历相关的函数等等。请务必随时查看 PHP 手册的日期和时间部分,以获取更多用例和示例。</p>
以上是PHP日期和时间食谱的详细内容。更多信息请关注PHP中文网其他相关文章!