Is this the proper way to get the end of day in PHP?
Asked Answered
B

6

5

I'm getting the End Of Day like this:

function endofday($date_to_change)
{
  $date_to_change = date('Y-m-d');
  $date_to_change = date('Y-m-d H:i:s', strtotime("+23 hours 59 minutes  59 seconds", strtotime($date_to_change)));
  return date("Y-m-d H:i:s", $date_to_change);
}

It works but is this the proper and most efficient way to get 23:59:59 from a date? My goal is to select rows from a mysql database between 00:00:00 and 23:59:59 from a date passed in with or without time.

Bookbinder answered 4/5, 2019 at 15:25 Comment(2)
Use MYSQL for this: #22874931Bedlam
Hi Chris I'm looking for the correct PHP function, then pass in.Bookbinder
E
2

Можно и так
$begin = date('Y-m-d 00:00:00');
$end = date('Y-m-d 23:59:59',strtotime($date_to_change));

Epi answered 4/5, 2019 at 15:37 Comment(2)
This will not work, if $begin is calclated before and $end after a day change. You have to use $begin as reference time, for example: $end = $begin + 86399. But this solution have another issue, on days with daylight saving changes.Daguerreotype
@Wimm for daylight saving then would you suggest getting midnight from next day then subtract 1 second (or millisecond) ?Bookbinder
L
5

If you don't want to use this kind of SQL query

where end_date < '2020-09-01' # this date is 1 day after the actual end date

You can use DateTime() function

$endDate = date_create('2020-08-31')->modify('+1 day -1 microsecond')

// or, similar result
$endDate = new DateTime('2020-08-31');
$endDate->modify('+1 day -1 microsecond');
Landed answered 27/12, 2021 at 8:15 Comment(0)
E
2

Можно и так
$begin = date('Y-m-d 00:00:00');
$end = date('Y-m-d 23:59:59',strtotime($date_to_change));

Epi answered 4/5, 2019 at 15:37 Comment(2)
This will not work, if $begin is calclated before and $end after a day change. You have to use $begin as reference time, for example: $end = $begin + 86399. But this solution have another issue, on days with daylight saving changes.Daguerreotype
@Wimm for daylight saving then would you suggest getting midnight from next day then subtract 1 second (or millisecond) ?Bookbinder
D
1

Why not using date >= start && date < end?

In general, working with inclusive beginning and exclusive end is a standard programming way. Otherwise you will exclude 23:59:59.500.

Also you get always correct (time) differences if using end-start.

Finally you can use end as start for the next range without adjusting it.

In my opinion, using an exclusive end value/time has only advantages.

I you want to print the time, you can use time-1 to print 23:59:59, or time-0.001 to print 23:59:59.999. Anyway people understand the meaning of until 20:00 as times before 20:00.

Daguerreotype answered 4/5, 2019 at 15:40 Comment(1)
Yes you are correct for the query part of this... which typically would mean the php function I was looking for not needed, but I'm working with existing code and I need a function to adjust variables.Bookbinder
C
1

This could potentially be another solution.

$today = new \DateTime('midnight today');
$endOfDay = (new \DateTime('midnight tomorrow'));
var_dump($today < $endOfDay);

var_dump($today->format('Y-m-d H:i:s')); // 2022-02-08 00:00:00
var_dump($endOfDay->format('Y-m-d H:i:s')); // 2022-02-09 00:00:00
Conventicle answered 8/2, 2022 at 23:50 Comment(0)
B
0

More readable way to get end of given day nowdays would be

function endOfDay(string $dateToChange): \DateTime
{
    return (new \DateTime($dateToChange))->setTime(23, 59, 59);
}

var_dump(endOfDay('2019-05-04'));

will give you (take note that \DateTime contains TZ info)

object(DateTime)#1 (3) {
  ["date"]=> string(26) "2019-05-04 23:59:59.000000"
  ["timezone_type"]=> int(3)
  ["timezone"]=> string(3) "UTC"
}

But, as @Wiimm mentioned in his answer, this way you'll be missing a second out of day. So it would be more correct to use

function startOfDay(\DateTime $dt): \DateTime
{
    return (clone $dt)->setTime(0, 0, 0);
}

and correct comparison:

$date = new \DateTime('2019-05-04 15:25:13'); // 2019-05-04 15:25:13.000000
$dateNextDay = (clone $date)->modify('+1 day'); // 2019-05-05 15:25:13.000000

$isInBetween = startOfDay($date) <= $date && $date < startOfDay($dateNextDay); // true

Take note of using clone(otherwise original $date would be modified) and completely switching to DateTime.

Most of ORMs already knows how to work with \DateTime, but if you need to convert it to string:

echo $date->format('Y-m-d H:i:s'); // 2019-05-04 00:00:00
Barela answered 10/2, 2023 at 1:18 Comment(0)
B
0

You can get the start and end of day by setting the proper time part.

Given a date-time object:

    $date = DateTime::createFromFormat('Y-m-d', '2024-03-01');
  • Date at start of the day:
    $startOfTheDay = $date->setTime(0,0);
  • Date at end of the day:
    $endOfTheDay = date->setTime(23,59,59,999999);
Barbur answered 5/3, 2024 at 20:13 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.