给定一个Unix时间戳,如何获得当天的开始和结束?

时间:2012-04-17 19:33:53

标签: php timestamp strtotime unix-timestamp

我有一个像这样的Unix时间戳:

$timestamp=1330581600

如何获取该时间戳的当天开始和当天结束?

e.g.
$beginOfDay = Start of Timestamp's Day
$endOfDay = End of Timestamp's Day

我试过了:

$endOfDay = $timestamp + (60 * 60 * 23);

但我不认为它会起作用,因为时间戳本身并不是当天的确切开始。

10 个答案:

答案 0 :(得分:153)

strtotime可用于快速切断小时/分钟/秒

$beginOfDay = strtotime("midnight", $timestamp);
$endOfDay   = strtotime("tomorrow", $beginOfDay) - 1;

也可以使用DateTime,但需要一些额外的步骤才能从长时间戳中获取

$dtNow = new DateTime();
// Set a non-default timezone if needed
$dtNow->setTimezone(new DateTimeZone('Pacific/Chatham'));
$dtNow->setTimestamp($timestamp);

$beginOfDay = clone $dtNow;

// Go to midnight.  ->modify('midnight') does not do this for some reason
$beginOfDay->modify('today');

$endOfDay = clone $beginOfDay;
$endOfDay->modify('tomorrow');
// adjust from the next day to the end of the day, per original question
$endOfDay->modify('1 second ago');

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'),
    )
);

答案 1 :(得分:10)

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();

首先创建一个DateTime对象,并将时间戳设置为所需的时间戳。然后将对象格式化为字符串,将小时/分钟/秒设置为当天的开头或结尾。最后,从该字符串创建一个新的DateTime对象,并检索时间戳。

可读

$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();

我们可以使用这个更长的版本以另一种方式结束一天:

$endOfDayObject = clone $beginOfDayOject(); // Cloning because add() and sub() modify the object
$endOfDayObject->add(new DateInterval('P1D'))->sub(new DateInterval('PT1S'));
$endOfDay = $endOfDayOject->getTimestamp();

时区

也可以通过在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();

DateTime的灵活性

我们还可以通过更改指定的第二种格式来获取其他信息,例如月份的开头/结尾或小时的开始/结束。对于月份:'Y-m-01 00:00:00''Y-m-t 23:59:59'。小时:'Y-m-d H:00:00''Y-m-d H:59:59'

将各种格式与add()/ sub()和DateInterval对象结合使用,我们可以得到任何时期的开始或结束,尽管需要注意正确处理闰年。

相关链接

来自PHP文档:

答案 2 :(得分:5)

您可以结合使用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()非常聪明,可以在指定月份之外的一天(jan 32nd将是1月1日等)包裹数月/年

答案 3 :(得分:4)

您可以将时间转换为当前数据,然后使用strtotime函数查找当天的开始,只需添加24小时即可查找当天结束。

您还可以使用余数运算符(%)查找最近的日期。例如:

$start_of_day = time() - 86400 + (time() % 86400);
$end_of_day = $start_of_day + 86400;

答案 4 :(得分:2)

今天开始日期时间戳。简单

Add_prod.objects.filter(cat__category = filter_category)

答案 5 :(得分:2)

不幸的是,由于在非常特定的情况下发生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);

因此,您会注意到,我们没有使用->modify('1 second ago');,而是获得了时间戳并减去了1。使用modify接受的答案会起作用,但是似乎存在一个非常特定的php错误。此错误发生在时区,该时区会在时钟“向前”移动的一年中的午夜更改夏令时。这是您可以用来验证该错误的示例。

错误示例代码

// 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;

错误示例代码输出

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

答案 6 :(得分:0)

对于将来有这个问题的任何人:

任何日期代码

<?php
$date = "2015-04-12 09:20:00";

$midnight = strtotime("midnight", strtotime($date));
$now = strtotime($date);

$diff = $now - $midnight;
echo $diff;
?>

当天代码

<?php
$midnight = strtotime("midnight");
$now = date('U');

$diff = $now - $midnight;
echo $diff;
?>

答案 7 :(得分:0)

$start_of_day = floor (time() / 86400) * 86400;
$end_of_day = ceil (time() / 86400) * 86400;

如果您需要在同一个脚本中同时使用这两个值。与其中一个变量相比,它可以更快地达到+/- 86400秒,而不是触发地板和天花板。例如:

$start_of_day = floor (time() / 86400) * 86400;
$end_of_day = $start_of_day + 86400;

答案 8 :(得分:0)

$date = (new \DateTime())->setTimestamp(1330581600);

echo $date->modify('today')->format('Y-m-d H:i:s'); // 2012-02-29 00:00:00
echo PHP_EOL;
echo $date->modify('tomorrow - 1 second')->format('Y-m-d H:i:s'); // 2012-02-29 23:59:59

答案 9 :(得分:0)

<块引用>
    $startOfDay = new \DateTime('tomorrow');
    $startOfDay->modify('-1 day');

这对我有用:)