php - PHP时间比较失败
问题描述
我正在开发一个 Wordpress 插件,但在时间比较方面遇到了问题。我基本上想要:如果选择的时间在当前时间之前,做这件事......但它不起作用。
expire
如果比 time() 提前不到五个小时,则验证失败。我通过添加 gmt 偏移来纠正这个问题,expire
但它仍然失败。有任何想法吗?
//$_POST['expire'] = '2019-01-31T12:00';
if(validateDate($_POST['expire'])) {
$expires_epoch = (strtotime($_POST['expire']) - (get_option( 'gmt_offset' ) * HOUR_IN_SECONDS));
if($expires_epoch < time()) {
...do the thing...
}
}
有什么想法吗?这看起来很简单,但似乎并没有按照我想要的方式工作。
解决方案
strtotime
它可以接受的格式有限,并且不会总是提供所需的结果。为了避免日期格式的歧义,正如 PHP 文档所推荐的那样,替代方法是使用DateTime::createFromFormat
. 这将允许您强制执行所提供的所需格式$_POST['expire']
。
使用格式Y-m-d\TH:i|
规则,强制执行ISO-8601格式,不包括秒和时区。( |
pipeline) 将剩余秒数重置为:00
,否则 PHP 将使用当前秒数。
如果您希望您的代码在到期日期过后运行,那么您只需要比较expire_date < current_date
.
示例:https ://3v4l.org/EelYY
//current date is 2019-01-04 08:33:30
//$_POST['expire'] = '2019-01-04T08:32';
if ($expire_date = \DateTime::createFromFormat('Y-m-d\TH:i|', $_POST['expire'])) {
$current_date = new \DateTime();
if ($expire_date < $current_date) {
/* example purposes only */
$diff = $expire_date->diff($current_date);
echo 'Expired ' . $diff->format('%y years %m months %d days %h hours %i minutes %s seconds') . ' ago';
//do the thing
}
} else {
die('Invalid Date Format Provided');
}
结果
Expired 0 years 0 months 0 days 0 hours 1 minutes 30 seconds ago
澄清如何以及为什么使用 Wordpress 的时区偏移量。
默认情况下,PHP 将在使用 、 和 对象时使用您指定的值date.timezone
。这仅对 Wordpress 和大多数其他应用程序在向查看器显示您的应用程序生成的日期或接受来自用户的要保存并显示给其他用户的日期字符串时很重要。例如显示创建帖子的时间或预期发生事件的时间。否则,通常可以忽略用户时区偏移量,因为 PHP 会将本地时区偏移量应用于解析的日期。php.ini
date()
time()
strtotime()
DateTime
例如,默认 PHPdate.timezone
是 UTC。我创建了一个我想在2019-01-01 09:00
我的时间 (EST) 发生的事件。但该活动将在 3 小时前在加利福尼亚州 (PST) 的某个人开始2019-01-01 06:00
。
为了向其他用户显示事件,必须将日期从 EST 的用户时区偏移量转换为 UTC 并存储在数据库中。然后从 UTC 转换为显示为其他时区。
示例:https ://3v4l.org/vA97A
$defaultTZ = new \DateTimeZone(date_default_timezone_get());
$event_start = '2019-01-01 09:00';
//event starts at 2019-01-01 09:00 EST
$est_date = new \DateTimeImmutable($event_start, new \DateTimeZone('America/New_York'));
//convert to native date to save in database
$utc_date = $est_date->setTimeZone($defaultTZ);
$db_date = $utc_date->format(DATE_ISO8601);
//event starts at 2019-01-01 14:00 UTC
$db_event_start = '2019-01-01T14:00:00+0000';
$event_date = new \DateTimeImmutable($db_event_start, $defaultTZ);
//display the start times to users
$pst_date = $event_date->setTimeZone(new \DateTimeZone('America/Los_Angeles'));
$est_date = $event_date->setTimeZone(new \DateTimeZone('America/New_York'));
echo 'Event Starts at:';
echo $event_date->format('Y-m-d H:i T');
echo $pst_date->format('Y-m-d H:i T');
echo $est_date->format('Y-m-d H:i T');
//display event status
echo 'Event ' . ($event_date <= new \DateTime('now', $defaultTZ) ? 'Has' : 'Not') . ' Started';
结果
Event Starts at:
2019-01-01 14:00 GMT+0000
2019-01-01 06:00 PST
2019-01-01 09:00 EST
Event Has Started
对于 WordPress,您通常会替换
date_default_timezone_get()
为get_option('timezone_string')
使用应用程序时区偏移量而不是 PHP 的默认时区偏移量。
推荐阅读
- r - 独立组的 t.test 错误:数据基本上是恒定的
- python - 将多个txt文件转换为单个文件的Python脚本
- javascript - UpdateOne MongoDB 使用来自另一个字段的值进行推送
- ios - 我可以使用 iOS 图表显示所有标记吗?
- javascript - 如何从我的 nodejs 服务器运行 js 文件
- python - Django通过admin中的主键过滤多对多关系
- javascript - Firebase admin sdk 调用错误的捕获
- c# - 什么时候异步,什么时候同步
- java - 列表视图中的 MP 图表
- java - 保存图像库 64 AngularJS Spring-Batch