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

Tal*_*lon 70 php timestamp strtotime unix-timestamp

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

$timestamp=1330581600
Run Code Online (Sandbox Code Playgroud)

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

e.g.
$beginOfDay = Start of Timestamp's Day
$endOfDay = End of Timestamp's Day
Run Code Online (Sandbox Code Playgroud)

我试过这个:

$endOfDay = $timestamp + (60 * 60 * 23);
Run Code Online (Sandbox Code Playgroud)

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

rre*_*ein 162

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

$beginOfDay = strtotime("today", $timestamp);
$endOfDay   = strtotime("tomorrow", $beginOfDay) - 1;
Run Code Online (Sandbox Code Playgroud)

也可以使用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'),
    )
);
Run Code Online (Sandbox Code Playgroud)

  • '今天​​'也会返回当天的开头`strtotime('today',$ timestamp)` (4认同)
  • `$endOfDay->modify('tomorrow -1 second');` 也有效。 (4认同)
  • 为什么在最后减1秒? (2认同)

Rob*_*man 10

只是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();
Run Code Online (Sandbox Code Playgroud)

首先创建一个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();
Run Code Online (Sandbox Code Playgroud)

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

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

时区

也可以通过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();
Run Code Online (Sandbox Code Playgroud)

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文档:

  • 您创建的内容简洁易读。不幸的是,它将在leap秒内失败。有些日子在23:59:58结束,而另一些日子则在23:59:60结束。特别是,如果尝试为不存在的日期时间创建日期,例如在理论上可以在此之前结束一秒的一天中的23:59:59,则会引起问题。接受的答案使用PHP的\ DateTime :: modify方法,可以避免这种情况。PHP的内置库足够聪明,可以解决围绕日期和时间(包括leap秒)的所有奇怪问题。 (2认同)

Cal*_*Cal 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);
Run Code Online (Sandbox Code Playgroud)

mktime() 在指定月份之外的一天(jan 32nd将是feb 1st等),足够聪明地包裹数月/年