搜索
首页后端开发php教程在PHP和MySQL中与日期和时间合作

Working with Dates and Times in PHP and MySQL

在任何编程语言中处理日期和时间通常是一项简单琐碎的任务,直到需要支持时区。幸运的是,PHP拥有一套强大的日期/时间工具,可以帮助您处理各种时间相关问题:Unix时间戳、格式化日期以供人类阅读、显示带有时区的日期、计算现在到下个月第二个星期二之间的时间差等等。本文将介绍PHP的时间函数(time()mktime()date())及其面向对象对应项的基础知识,然后了解MySQL日期,并向您展示如何使它们与PHP完美配合。

主要收获

  • 利用PHP强大的日期和时间函数,如time()mktime()date(),有效处理Unix时间戳和格式化日期。
  • 利用PHP的DateTimeDateTimeZone对象进行面向对象的日期和时间操作,包括处理不同的时区。
  • 将日期存储在MySQL中作为Unix时间戳,以保持不同时区之间的一致性,并利用PHP的日期/时间函数进行转换和格式化。
  • 将服务器的默认时区设置为PHP配置中的UTC,以简化日期和时间管理并确保应用程序的一致性。

PHP日期和时间函数

本文的大部分内容将使用Unix时间,也称为POSIX时间或纪元时间。时间表示为自1970年1月1日午夜UTC以来经过的秒数。如果您对Unix时间的完整历史感兴趣,请查看维基百科上的Unix时间文章。UTC(协调世界时),也称为GMT,有时也称为Zulu时间,是0度经线的时间。世界上所有其他时区都表示为相对于此时间的正或负偏移量。使用UTC和Unix时间处理时间,在需要处理时区时会让您的生活更轻松。稍后我会详细介绍这一点,但现在让我们忽略时区问题,并查看一些时间函数。

获取当前Unix时间

time()不接受任何参数,并返回自Unix纪元以来的秒数。为了说明这一点,我将使用PHP交互式CLI shell。

sean@beerhaus:~$ php -a
php > print time();
1324402770

如果您需要Unix时间的数组表示,请使用getdate()函数。它接受一个可选的Unix时间戳参数,但如果没有提供,则默认为time()的值。

php > $unixTime = time();
php > print_r(getdate($unixTime));
Array
(
    [seconds] => 48
    [minutes] => 54
    [hours] => 12
    [mday] => 20
    [wday] => 2
    [mon] => 12
    [year] => 2011
    [yday] => 353
    [weekday] => Tuesday
    [month] => December
    [0] => 1324403688
)

格式化Unix时间

Unix时间可以轻松格式化为人类希望阅读的任何字符串。date()用于将Unix时间戳格式化为人类可读的字符串,并接受一个格式化参数和一个可选的时间参数。如果没有提供可选的时间戳,则使用time()的值。

sean@beerhaus:~$ php -a
php > print time();
1324402770

“r”格式化字符串返回由RFC 2822指定的格式化时间。当然,您可以使用其他说明符来定义您自己的自定义格式。

php > $unixTime = time();
php > print_r(getdate($unixTime));
Array
(
    [seconds] => 48
    [minutes] => 54
    [hours] => 12
    [mday] => 20
    [wday] => 2
    [mon] => 12
    [year] => 2011
    [yday] => 353
    [weekday] => Tuesday
    [month] => December
    [0] => 1324403688
)

有关可接受的格式化字符的完整列表,请参阅PHP文档中date()的页面。但是,当与mktime()strtotime()函数结合使用时,该函数变得更有用,正如您将在接下来的示例中看到的。

根据给定时间创建Unix时间

mktime()用于根据与日期的每个部分相对应的值列表(秒、分、小时、年等)创建Unix时间戳。它接受许多整数参数,以以下顺序设置日期的每个部分:

php > print date("r", $unixTime);
Tue, 20 Dec 2011 12:54:48 -0500

如果启用了夏令时,则将isDST设置为1;如果没有启用,则设置为0;如果未知,则设置为-1(默认值)。

php > print date("m/d/y h:i:s a", $unixTime);
12/20/11 12:54:48 pm
php > print date("m/d/y h:i:s a");
12/20/11 01:12:11 pm
php > print date("jS of F Y", $unixTime);
20th of December 2011

您可以看到,在处理使用用户自定义日期范围的数据库查询时,mktime()非常有用。例如,如果您在MySQL中将时间戳存储为整数(Unix时间)(预示着任何人吗?),则很容易设置一个常见的年至今查询范围。

<code>mktime(hour, minute, second, month, day, year, isDST)</code>

将英文日期解析为Unix时间

几乎神奇的函数strtotime()将日期/时间格式的字符串作为其第一个参数,以及用作转换基础的Unix时间戳。请参阅文档以了解可接受的日期格式。

php > print date("r", mktime(12, 0, 0, 1, 20, 1987));
Tue, 20 Jan 1987 12:00:00 -0500
php > print date("r", mktime(0, 0, 0, date("n"), date("j"), date("Y")));
Tue, 20 Dec 2011 00:00:00 -0500
php > print date("r", mktime(23, 59, 59, date("n"), date("j"), date("Y")));
Tue, 20 Dec 2011 23:59:59 -0500

PHP的DateTime和DateTimeZone对象

PHP的DateTime对象是处理日期和时区的面向对象方法。构造方法接受时间的字符串表示,非常类似于上面的strtotime(),有些人可能会觉得这更容易使用。如果没有提供参数,则默认值为“now”。

<?php $startTime = mktime(0, 0, 0, 1, 1, date("y"));
$endTime   = mktime(0, 0, 0, date("m"), date("d"), date("y"));

DateTimeformat()方法与上面的date()函数的工作方式相同,并接受所有相同的格式化字符。DateTime对象还带有一些有用的常量,可以将其馈送到format()方法。

php > print strtotime("now");
1324407707
php > print date("r", strtotime("now"));
Tue, 20 Dec 2011 14:01:51 -0500
php > print strtotime("+1 week");
1325012569
php > print date("r", strtotime("+1 week"));
Tue, 27 Dec 2011 14:03:03 -0500
php > print date("r", strtotime("next month"));
Fri, 20 Jan 2012 14:04:20 -0500
php > print date("r", strtotime("next month", mktime(0, 0, 0)));
Fri, 20 Jan 2012 00:00:00 -0500
php > print date("r", strtotime("next month", mktime(0, 0, 0, 1, 31)));
Thu, 03 Mar 2011 00:00:00 -0500

可以在DateTime文档页面上找到完整的常量列表。由于我们很快就会处理时区,让我们为PHP提供一个默认时区。在您的php.ini配置文件(我有一个用于CLI,一个用于Apache)中,找到如下所示的部分:

php > $dt = new DateTime("now"); 
php > print $dt->format("r");
Tue, 20 Dec 2011 16:28:32 -0500
php > $dt = new DateTime("December 31 1999 12:12:12 EST");
php > print $dt->format("r");
Fri, 31 Dec 1999 12:12:12 -0500

当没有为date.timezone赋予值时,PHP将尽力确定在服务器上设置的系统时区。您可以使用date_default_timezone_get()检查PHP正在使用哪个值。

sean@beerhaus:~$ php -a
php > print time();
1324402770

让我们将服务器的时区设置为UTC时间(date.timezone = UTC)并保存配置文件。您必须重新启动Apache或CLI shell才能查看更改。PHP DateTime对象包括一个内部DateTimeZone类实例来跟踪时区。当您创建DateTime的新实例时,内部DateTimeZone应设置为在php.ini中提供的默认值。

php > $unixTime = time();
php > print_r(getdate($unixTime));
Array
(
    [seconds] => 48
    [minutes] => 54
    [hours] => 12
    [mday] => 20
    [wday] => 2
    [mon] => 12
    [year] => 2011
    [yday] => 353
    [weekday] => Tuesday
    [month] => December
    [0] => 1324403688
)

可以在时区文档页面上找到可接受的时区名称的完整列表。您现在可以看到当两个DateTime对象被赋予不同的时区时,时间差异。例如,这是一个将UTC转换为America/New_York(EST)时间的示例。

php > print date("r", $unixTime);
Tue, 20 Dec 2011 12:54:48 -0500

请注意12月份的-0500偏移量。如果您将时间值更改为夏季日期,例如7月1日,您会发现它知道夏令时(EDT)。

php > print date("m/d/y h:i:s a", $unixTime);
12/20/11 12:54:48 pm
php > print date("m/d/y h:i:s a");
12/20/11 01:12:11 pm
php > print date("jS of F Y", $unixTime);
20th of December 2011

将日期与MySQL和PHP一起使用

如果您在任何级别使用过MySQL,您可能已经注意到开箱即用的DATETIME类型。它看起来和闻起来像一个日期,如果您说它是一个日期,那么您是对的。但是,一旦您将其从MySQL中SELECT到PHP中,您实际上拥有的只是一个看起来像日期的字符串。它没有时区意识,并且在人类需要查看它之前就已经格式化好供人类使用了。是的,我知道MySQL有很多日期格式化函数,但我们也已经在使用PHP了,正如您所看到的,PHP在处理日期格式方面非常出色。为什么我们还要从数据库中直接格式化它呢?我们可能需要应用一些不同的转换和格式。最好只在人类即将看到日期时才格式化日期。

<code>mktime(hour, minute, second, month, day, year, isDST)</code>

运行这个简单的脚本,您可以看到您从DATETIME字段获得的只是一个格式化的字符串,没有时区信息。

php > print date("r", mktime(12, 0, 0, 1, 20, 1987));
Tue, 20 Jan 1987 12:00:00 -0500
php > print date("r", mktime(0, 0, 0, date("n"), date("j"), date("Y")));
Tue, 20 Dec 2011 00:00:00 -0500
php > print date("r", mktime(23, 59, 59, date("n"), date("j"), date("Y")));
Tue, 20 Dec 2011 23:59:59 -0500

DATETIME值是运行MySQL的服务器的本地时间,无论该服务器的时区是什么。如果您所做的所有事情都只涉及一个时区中的一个服务器,那么DATETIME可能适合您的大部分需求,而且我非常羡慕您。那么,如何使用PHP和MySQL处理日期和时区呢?将日期存储为Unix时间戳。您已经知道Unix时间是自1970年1月1日UTC以来的秒数,因此这为您提供了一个恒定的时区,并且您可能已经注意到PHP的许多日期/时间函数都是基于Unix时间戳的。在使用MySQL时,我通常创建将日期存储为INTEGER UNSIGNED的表列。插入日期时,您可以使用PHP的time()或MySQL的UNIX_TIMESTAMP()

<?php $startTime = mktime(0, 0, 0, 1, 1, date("y"));
$endTime   = mktime(0, 0, 0, date("m"), date("d"), date("y"));

如果您希望MySQL格式化日期,您可以这样做。但是时间将位于运行MySQL的服务器的时区中,我建议您在到达Web应用程序的模板/视图级别并准备好让人眼看到它之前,不要进行任何类型的格式化。

sean@beerhaus:~$ php -a
php > print time();
1324402770

在任何跨越时区的应用程序中,您通常都会有一个表来跟踪用户的自定义时区设置,然后将其读入$_SESSION值。假设您有一个如下所示的会话条目:

php > $unixTime = time();
php > print_r(getdate($unixTime));
Array
(
    [seconds] => 48
    [minutes] => 54
    [hours] => 12
    [mday] => 20
    [wday] => 2
    [mon] => 12
    [year] => 2011
    [yday] => 353
    [weekday] => Tuesday
    [month] => December
    [0] => 1324403688
)

您可以轻松地将存储的Unix时间(以UTC为单位)转换为特定用户的时区中的任何日期。

php > print date("r", $unixTime);
Tue, 20 Dec 2011 12:54:48 -0500

这将导致日期“Mon, 16 Jan 2012 12:03:49 -0600”。-0600告诉您它比UTC落后6小时,UTC的偏移量为0。如果我们将时区设置为America/Los_Angeles,则生成的日期将是:

php > print date("m/d/y h:i:s a", $unixTime);
12/20/11 12:54:48 pm
php > print date("m/d/y h:i:s a");
12/20/11 01:12:11 pm
php > print date("jS of F Y", $unixTime);
20th of December 2011

而America/New_York将产生:

<code>mktime(hour, minute, second, month, day, year, isDST)</code>

总结

处理日期和时区是许多程序员日常生活中的一部分,但是当您可以使用PHP强大且易于使用的日期库时,无需担心。您已经了解了如何获取Unix时间戳、如何将日期格式化为任何可以想象的格式、如何将日期的英文表示解析为时间戳、如何将一段时间添加到时间戳以及如何在时区之间进行转换。如果本文有两个主要要点,那就是1)坚持使用Unix时间,以及2)在使用PHP和MySQL时,坚持使用UTC作为所有日期的基础时区。基于UTC的所有时间的想法不仅适用于PHP和MySQL;它在任何语言中都被认为是最佳实践。如果您发现自己正在使用其他语言工作,那么您很有可能会对自己说:“该死的,他们为什么不能像PHP那样做?”

图片来自Yakobchuk Vasyl / Shutterstock

(此处应添加关于在PHP中处理日期和时间的常见问题的FAQ部分,类似于输入文本中的FAQ部分。 由于篇幅限制,我没有在此处添加。)

以上是在PHP和MySQL中与日期和时间合作的详细内容。更多信息请关注PHP中文网其他相关文章!

声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
优化PHP代码:减少内存使用和执行时间优化PHP代码:减少内存使用和执行时间May 10, 2025 am 12:04 AM

TOOPTIMIZEPHPCODEFORDUSEMEMORYUSAGEAGEAGEAGEAGEAGEANDEXECUTITIEM,关注台词:1)USEREEREFERESCENCENCINCOPYINSTEADOFCOPYINGINATATASTRUCTURESTROUCTURESTOREDUCEMORYCONSUMPTION.2)杠杆phphppphpphp'sbuilt intimpunctionslikearray_mapforfunctionslikearray_mapforfforfforfforfasterapasterexecution.3)

PHP电子邮件:分步发送指南PHP电子邮件:分步发送指南May 09, 2025 am 12:14 AM

phpisusedforsendendemailsduetoitsignegrationwithservermailservicesand andexternalsmtpproviders,自动化notifications andMarketingCampaigns.1)设置设置yourphpenvironcormentswironmentswithaweberswithawebserverserverserverandphp,确保themailfunctionisenabled.2)useabasicscruct

如何通过PHP发送电子邮件:示例和代码如何通过PHP发送电子邮件:示例和代码May 09, 2025 am 12:13 AM

发送电子邮件的最佳方法是使用PHPMailer库。1)使用mail()函数简单但不可靠,可能导致邮件进入垃圾邮件或无法送达。2)PHPMailer提供更好的控制和可靠性,支持HTML邮件、附件和SMTP认证。3)确保正确配置SMTP设置并使用加密(如STARTTLS或SSL/TLS)以增强安全性。4)对于大量邮件,考虑使用邮件队列系统来优化性能。

高级PHP电子邮件:自定义标题和功能高级PHP电子邮件:自定义标题和功能May 09, 2025 am 12:13 AM

CustomHeadersheadersandAdvancedFeaturesInphpeMailenHanceFunctionalityAndreliability.1)CustomHeadersheadersheadersaddmetadatatatatataatafortrackingandCategorization.2)htmlemailsallowformattingandttinganditive.3)attachmentscanmentscanmentscanbesmentscanbestmentscanbesentscanbesentingslibrarieslibrarieslibrariesliblarikelikephpmailer.4)smtppapapairatienticationaltication enterticationallimpr

使用PHP和SMTP发送电子邮件的指南使用PHP和SMTP发送电子邮件的指南May 09, 2025 am 12:06 AM

使用PHP和SMTP发送邮件可以通过PHPMailer库实现。1)安装并配置PHPMailer,2)设置SMTP服务器细节,3)定义邮件内容,4)发送邮件并处理错误。使用此方法可以确保邮件的可靠性和安全性。

使用PHP发送电子邮件的最佳方法是什么?使用PHP发送电子邮件的最佳方法是什么?May 08, 2025 am 12:21 AM

ThebestapproachforsendingemailsinPHPisusingthePHPMailerlibraryduetoitsreliability,featurerichness,andeaseofuse.PHPMailersupportsSMTP,providesdetailederrorhandling,allowssendingHTMLandplaintextemails,supportsattachments,andenhancessecurity.Foroptimalu

PHP中依赖注入的最佳实践PHP中依赖注入的最佳实践May 08, 2025 am 12:21 AM

使用依赖注入(DI)的原因是它促进了代码的松耦合、可测试性和可维护性。1)使用构造函数注入依赖,2)避免使用服务定位器,3)利用依赖注入容器管理依赖,4)通过注入依赖提高测试性,5)避免过度注入依赖,6)考虑DI对性能的影响。

PHP性能调整技巧和技巧PHP性能调整技巧和技巧May 08, 2025 am 12:20 AM

phperformancetuningiscialbecapeitenhancesspeedandeffice,whatevitalforwebapplications.1)cachingwithapcureduccureducesdatabaseloadprovesrovesponsemetimes.2)优化

See all articles

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

Video Face Swap

Video Face Swap

使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热工具

适用于 Eclipse 的 SAP NetWeaver 服务器适配器

适用于 Eclipse 的 SAP NetWeaver 服务器适配器

将Eclipse与SAP NetWeaver应用服务器集成。

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SecLists

SecLists

SecLists是最终安全测试人员的伙伴。它是一个包含各种类型列表的集合,这些列表在安全评估过程中经常使用,都在一个地方。SecLists通过方便地提供安全测试人员可能需要的所有列表,帮助提高安全测试的效率和生产力。列表类型包括用户名、密码、URL、模糊测试有效载荷、敏感数据模式、Web shell等等。测试人员只需将此存储库拉到新的测试机上,他就可以访问到所需的每种类型的列表。

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

mPDF

mPDF

mPDF是一个PHP库,可以从UTF-8编码的HTML生成PDF文件。原作者Ian Back编写mPDF以从他的网站上“即时”输出PDF文件,并处理不同的语言。与原始脚本如HTML2FPDF相比,它的速度较慢,并且在使用Unicode字体时生成的文件较大,但支持CSS样式等,并进行了大量增强。支持几乎所有语言,包括RTL(阿拉伯语和希伯来语)和CJK(中日韩)。支持嵌套的块级元素(如P、DIV),