php 给定 Unix 时间戳,如何获取当天的开始和结束时间?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/10197900/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Given a Unix timestamp, how to get beginning and end of that day?
提问by Talon
I have a Unix timestamp like this:
我有一个像这样的 Unix 时间戳:
$timestamp=1330581600
How do I get the beginning of the day and the end of the day for that timestamp?
我如何获得该时间戳的一天开始和一天结束?
e.g.
$beginOfDay = Start of Timestamp's Day
$endOfDay = End of Timestamp's Day
I tried this:
我试过这个:
$endOfDay = $timestamp + (60 * 60 * 23);
But I don't think it'll work because the timestamp itself isn't the exact beginning of the day.
但我认为它不会起作用,因为时间戳本身并不是一天的确切开始。
回答by rrehbein
strtotime can be used to to quickly chop off the hour/minutes/seconds
strtotime 可用于快速截断小时/分钟/秒
$beginOfDay = strtotime("today", $timestamp);
$endOfDay = strtotime("tomorrow", $beginOfDay) - 1;
DateTime can also be used, though requires a few extra steps to get from a long timestamp
也可以使用 DateTime,但需要一些额外的步骤才能从长时间戳中获取
$dtNow = new DateTime();
// Set a non-default timezone if needed
$dtNow->setTimezone(new DateTimeZone('Pacific/Chatham'));
$dtNow->setTimestamp($timestamp);
$beginOfDay = clone $dtNow;
$beginOfDay->modify('today');
$endOfDay = clone $beginOfDay;
$endOfDay->modify('tomorrow');
// adjust from the start of next day to the end of the day,
// per original question
// Decremented the second as a long timestamp rather than the
// DateTime object, due to oddities around modifying
// into skipped hours of day-lights-saving.
$endOfDateTimestamp = $endOfDay->getTimestamp();
$endOfDay->setTimestamp($endOfDateTimestamp - 1);
var_dump(
array(
'time ' => $dtNow->format('Y-m-d H:i:s e'),
'start' => $beginOfDay->format('Y-m-d H:i:s e'),
'end ' => $endOfDay->format('Y-m-d H:i:s e'),
)
);
With the addition of extended time in PHP7, there is potential to miss a second if using $now <= $endchecking with this.
Using $now < $nextStartchecking would avoid that gap, in addition to the oddities around subtracting seconds and daylight savings in PHP's time handling.
随着 PHP7 中的延长时间的增加,如果使用$now <= $end此检查可能会错过一秒钟。$now < $nextStart除了在 PHP 的时间处理中减去秒和夏令时的奇怪之处之外,使用检查可以避免这种差距。
回答by Robert Hickman
Just DateTime
只是日期时间
$beginOfDay = DateTime::createFromFormat('Y-m-d H:i:s', (new DateTime())->setTimestamp($timestamp)->format('Y-m-d 00:00:00'))->getTimestamp();
$endOfDay = DateTime::createFromFormat('Y-m-d H:i:s', (new DateTime())->setTimestamp($timestamp)->format('Y-m-d 23:59:59'))->getTimestamp();
First a DateTime object is created and the timestamp is set to the desired timestamp. Then the object is formatted as a string setting the hour/minute/second to the beginning or end of the day. Lastly, a new DateTime object is created from this string and the timestamp is retrieved.
首先创建一个 DateTime 对象并将时间戳设置为所需的时间戳。然后对象被格式化为一个字符串,将小时/分钟/秒设置为一天的开始或结束。最后,从该字符串创建一个新的 DateTime 对象并检索时间戳。
Readable
可读
$dateTimeObject = new DateTime();
$dateTimeObject->setTimestamp($timestamp);
$beginOfDayString = $dateTimeObject->format('Y-m-d 00:00:00');
$beginOfDayObject = DateTime::createFromFormat('Y-m-d H:i:s', $beginOfDayString);
$beginOfDay = $beginOfDayObject->getTimestamp();
We can get the end of the day in an alternate manner using this longer version:
我们可以使用这个更长的版本以另一种方式结束一天:
$endOfDayObject = clone $beginOfDayOject(); // Cloning because add() and sub() modify the object
$endOfDayObject->add(new DateInterval('P1D'))->sub(new DateInterval('PT1S'));
$endOfDay = $endOfDayOject->getTimestamp();
Timezone
时区
The timezone can be set as well by adding a timestamp indicator to the format such as Oand specifying the timestamp after creating the DateTime object:
也可以通过在格式中添加时间戳指示符来设置时区,例如O并在创建 DateTime 对象后指定时间戳:
$beginOfDay = DateTime::createFromFormat('Y-m-d H:i:s O', (new DateTime())->setTimezone(new DateTimeZone('America/Los_Angeles'))->setTimestamp($timestamp)->format('Y-m-d 00:00:00 O'))->getTimestamp();
Flexibility of DateTime
日期时间的灵活性
We can also get other information such as the beginning/end of the month or the beginning/end of the hour by changing the second format specified. For month: 'Y-m-01 00:00:00'and 'Y-m-t 23:59:59'. For hour: 'Y-m-d H:00:00'and 'Y-m-d H:59:59'
我们还可以通过更改指定的第二个格式来获取其他信息,例如月份的开始/结束或小时的开始/结束。对于月份:'Y-m-01 00:00:00'和'Y-m-t 23:59:59'。小时:'Y-m-d H:00:00'和'Y-m-d H:59:59'
Using various formats in combination with add()/sub() and DateInterval objects, we can get the beginning or end of any period, although some care will need to be taken to handle leap years correctly.
将各种格式与 add()/sub() 和 DateInterval 对象结合使用,我们可以获得任何时期的开始或结束,尽管需要注意正确处理闰年。
Relevant Links
相关链接
From the PHP docs:
来自 PHP 文档:
- DateTime
- datewith info on the format
- DateTimeZone
- DateInterval
回答by Cal
You can use a combination of date()and mktime():
您可以使用组合date()和mktime():
list($y,$m,$d) = explode('-', date('Y-m-d', $ts));
$start = mktime(0,0,0,$m,$d,$y);
$end = mktime(0,0,0,$m,$d+1,$y);
mktime()is smart enough to wrap months/years when given a day outside the specified month (jan 32nd will be feb 1st, etc)
mktime()足够聪明,可以在指定月份之外的一天(1 月 32 日将是 2 月 1 日等)包装月/年
回答by James
You could convert the time to the current data and then use the strtotime function to find the start of the day and simply add 24 hours to that to find the end of the day.
您可以将时间转换为当前数据,然后使用 strtotime 函数查找一天的开始,然后简单地添加 24 小时以查找一天的结束。
You could also use the remainder operator (%) to find the nearest day. For example:
您还可以使用余数运算符 (%) 来查找最近的日期。例如:
$start_of_day = time() - 86400 + (time() % 86400);
$end_of_day = $start_of_day + 86400;
回答by Ganesh
Today Starting date timestamp. Simple
今天 开始日期时间戳。简单的
$stamp = mktime(0, 0, 0);
echo date('m-d-Y H:i:s',$stamp);
回答by KayakinKoder
The accepted answer unfortunately breaks due to a php bug that occurs in very specific scenarios. I'll discuss those scenarios, but first the answer using DateTime. The only difference between this and the accepted answer occurs after the // IMPORTANTline:
不幸的是,由于在非常特定的情况下发生的 php 错误,已接受的答案会中断。我将讨论这些场景,但首先使用 DateTime 来回答。这与接受的答案之间的唯一区别发生在该// IMPORTANT行之后:
$dtNow = new DateTime();
// Set a non-default timezone if needed
$dtNow->setTimezone(new DateTimeZone('America/Havana'));
$dtNow->setTimestamp($timestamp);
$beginOfDay = clone $dtNow;
// Go to midnight. ->modify('midnight') does not do this for some reason
$beginOfDay->modify('today');
// now get the beginning of the next day
$endOfDay = clone $beginOfDay;
$endOfDay->modify('tomorrow');
// IMPORTANT
// get the timestamp
$ts = $endOfDay->getTimestamp();
// subtract one from that timestamp
$tsEndOfDay = $ts - 1;
// we now have the timestamp at the end of the day. we can now use that timestamp
// to set our end of day DateTime
$endOfDay->setTimestamp($tsEndOfDay);
So you'll note that instead of using ->modify('1 second ago');we instead get the timestamp and subtract one. The accepted answer using modifyshouldwork, but breaks because of php bug in very specific scenarios. This bug occurs in timezones that change daylight savings at midnight, on the day of the year that clocks are moved "forward". Here is an example you can use to verify that bug.
所以你会注意到->modify('1 second ago');我们不是使用而是获取时间戳并减去一。使用的公认答案modify应该可以工作,但在非常特定的场景中由于 php 错误而中断。此错误发生在更改夏令时的时区中,即时钟“向前”移动的那一天的午夜。这是您可以用来验证该错误的示例。
bug example code
错误示例代码
// a time zone, Cuba, that changes their clocks forward exactly at midnight. on
// the day before they make that change. there are other time zones which do this
$timezone = 'America/Santiago';
$dateString = "2020-09-05";
echo 'the start of the day:<br>';
$dtStartOfDay = clone $dtToday;
$dtStartOfDay->modify('today');
echo $dtStartOfDay->format('Y-m-d H:i:s');
echo ', '.$dtStartOfDay->getTimestamp();
echo '<br><br>the start of the *next* day:<br>';
$dtEndOfDay = clone $dtToday;
$dtEndOfDay->modify('tomorrow');
echo $dtEndOfDay->format('Y-m-d H:i:s');
echo ', '.$dtEndOfDay->getTimestamp();
echo '<br><br>the end of the day, this is incorrect. notice that with ->modify("-1 second") the second does not decrement the timestamp by 1:<br>';
$dtEndOfDayMinusOne = clone $dtEndOfDay;
$dtEndOfDayMinusOne->modify('1 second ago');
echo $dtEndOfDayMinusOne->format('Y-m-d H:i:s');
echo ', '.$dtEndOfDayMinusOne->getTimestamp();
echo '<br><br>the end of the day, this is correct:<br>';
$dtx = clone $dtEndOfDay;
$tsx = $dtx->getTimestamp() - 1;
$dty = clone $dtEndOfDay;
$dty->setTimestamp($tsx);
echo $dty->format('Y-m-d H:i:s');
echo ', '.$tsx;
bug example code output
错误示例代码输出
the start of the day:
2020-03-26 00:00:00, 1585173600
the start of the *next* day:
2020-03-27 01:00:00, 1585260000
the end of the day, this is incorrect. notice that with ->modify("1 second ago") the
second does not decrement the timestamp by 1:
2020-03-27 01:59:59, 1585263599
the end of the day, this is correct:
2020-03-26 23:59:59, 1585259999
回答by Kareem
$start_of_day = floor (time() / 86400) * 86400;
$end_of_day = ceil (time() / 86400) * 86400;
If your need both values in the same script. It is faster to +/- 86400 seconds to one of the variables than to fire both floor and ceil. For example:
如果您需要同一脚本中的两个值。+/- 86400 秒到其中一个变量比同时触发 floor 和 ceil 更快。例如:
$start_of_day = floor (time() / 86400) * 86400;
$end_of_day = $start_of_day + 86400;
回答by Daniel Bj?rn?dal
For anyone that have this question in the future:
对于将来有此问题的任何人:
Any day code
任何一天代码
<?php
$date = "2015-04-12 09:20:00";
$midnight = strtotime("midnight", strtotime($date));
$now = strtotime($date);
$diff = $now - $midnight;
echo $diff;
?>
Current day code
当日代码
<?php
$midnight = strtotime("midnight");
$now = date('U');
$diff = $now - $midnight;
echo $diff;
?>

