Get seconds until the end of the month in PHP - php

I would like to set a cookie with PHP that has to expire at the end of the month.
How can I get the number of seconds until the end of the month?
Thank you.

You can use time() to get the number of seconds elapsed since the epoche. Then use strtotime("date") to get the number of seconds to your date. Subtract the two and you have the number of seconds difference.
This will give you the last second of the month:
$end = strtotime('+1 month',strtotime(date('m').'/01/'.date('Y').' 00:00:00')) - 1;
This will give you now:
$now = time();
This will give you the distance:
$numSecondsUntilEnd = $end - $now;

If you're using setcookie() function, then you don't really need the number of seconds, you need the timestamp, when cookie should be expired:
// Works in PHP 5.3+
setcookie("cookie_name", "value", strtotime("first day of next month 0:00"));
// Example without using strtotime(), works in all PHP versions
setcookie("cookie_name", "value", mktime(0, 0, 0, date('n') + 1, 1, date('Y')));

In PHP 5.3 they added a DateTime class which makes handling operations like this make a lot more sense and a little bit easier too (in my opinion).
$datetime1 = new DateTime('now'); // current date
$datetime2 = new DateTime(date("Ymt")); // last day in the month
$interval = $datetime1->diff($datetime2); // difference
echo $interval->format('%d') * 86400; // number of seconds

Create a timestamp for the end of the month and subtract the timestamp for the current time from it.
// Create a timestamp for the last day of current month
// by creating a date for the 0th day of next month
$eom = mktime(0, 0, 0, date('m', time()) + 1, 0);
// Subtract current time for difference
$diff = $eom - time();

Related

How can I create a zero DateTime with php?

I need to create an empty date with DateTime(). So, all zeros. The time should be displayed in that way: 0000:00:0:00:00.
What I have tried:
$date = new DateTime("2019-05-09 12:07");
$date->setTime(0, 0);
$date->setDate(0, 0, 0);
echo $date->format("Y:W:j:H:i");
That outputs
-0001:49:30:00:00
instead of 0000:00:0:00:00
What could I do to achieve a zero datetime?
More an explanation of what is going wrong than how to achieve what you are after - even if it is possible.
From a date point of view - 0 is invalid for both the month and day. In the manual it has the example
Example #2 Values exceeding ranges are added to their parent values
So if you have greater than the number of days in a month, it will make it the next month
In your case it is almost the opposite, having a number less than the start of the month. So 0 as the month and day, it will act as -1, so if you formatted it as
echo $date->format("Y:m:d:H:i");
the output is
-0001:11:30:00:00
So as you can see, the day and month are 0-1 (11 and 30) and this has overflowed into the year with -1.
No, You cannot make a datetime 0000:00:0:00:00 from DateTime()
php > echo (new DateTime("0000-00-00 00:00:00"))->format("Y-W-j H:i");
-0001-49-30 00:00
php > echo (new DateTime())->setISODate(0,0,0)->setTime(0,0,0,0)->format("Y-W-j H:i");
-0001-52-26 00:00
Surely Not..!
although you can create any Date with PHP helper function (that uses DateTime class behind) any of you desire date with Zeor Time only
$date = date_create('now'); // or any '1970-01-01'
$date = date_format($date, 'Y-m-d 00:00:00');
// or
$date = date('Y-m-d 00:00:00', strtotime('2021-12-21'));
// or
$date = date('Y-m-d 00:00:00');
output: "2021-12-21 00:00:00"
you can initialize the time with current time and take difference of the current time after. its a trick you can perfom to get (0000-00-00 00:00:00).
$currentTime = new DateTime('NOW');
$diff = $currentTime->diff(new DateTime('NOW'));
echo $diff->format("%Y-%m-%d %H %i %s");
that will give you 0000-00-00 00:00:00

How to check how many days passed from timestamp - counting the days at midnight

I'm trying to know how many days have passed from a certain timestamp, but the problem is I can't set it up, so that after midnight will count it as another day.
Here is what I tried:
<?php
$now = time(); // or your date as well
$your_date = 1572123244;
$datediff = $now - $your_date;
echo round($datediff / (60 * 60 * 24));
If I put a timestamp of five minutes before midnight (1572134100), five minutes after midnight should appear that "one day passed"
The usual way of counting the days passed since a given timestamp would be something like this:
$dt = date_create_from_format('U', 1572046200);
$diff = $dt->diff(new DateTime());
echo $diff->days;
But this counts the full 24 hour periods as days. In your case you want to count calendar dates irrespective of the time of day. I would recommend then to ceil the timestamp to the midnight.
$dt = date_create_from_format('U', 1572047700);
$dt->setTime(0, 0); // set time to 00:00
$now = new DateTime('now', new DateTimeZone('UTC')); // time now, but in UTC
$now->setTime(0, 0); // set time to 00:00
$diff = $dt->diff($now);
echo $diff->days;
I am not sure about your current time zone, but timestamps are by nature in UTC, hence you should probably normalize your local time to UTC as well.
What this code does is it sets both today's date and the timestamp you are comparing against to the midnight of the UTC day and then calculates the difference between the two. Taking the time out of equation, this will always count the full 24 hour days.

Given a Unix timestamp, how to get beginning and end of that day?

I have a Unix timestamp like this:
$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.
strtotime can be used to to quickly chop off the hour/minutes/seconds
$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
$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 <= $end checking with this.
Using $now < $nextStart checking would avoid that gap, in addition to the oddities around subtracting seconds and daylight savings in PHP's time handling.
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.
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 O and specifying the timestamp after creating the DateTime object:
$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'
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.
Relevant Links
From the PHP docs:
DateTime
date with info on the format
DateTimeZone
DateInterval
You can use a combination of date() and 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)
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.
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;
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 // IMPORTANT line:
$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 modify should work, 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.
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
Today Starting date timestamp. Simple
$stamp = mktime(0, 0, 0);
echo date('m-d-Y H:i:s',$stamp);
$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:
$start_of_day = floor (time() / 86400) * 86400;
$end_of_day = $start_of_day + 86400;
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;
?>
$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
$startOfDay = new \DateTime('tomorrow');
$startOfDay->modify('-1 day');
This works for me :)
A little late to the party, but here's another easy way to achieve what you're looking for:
$timestamp=1330581600;
$format = DATE_ATOM;
$date = (new DateTime())->setTimestamp($timestamp);
// Here's your initial date, created from the timestamp above
// 2012-03-01T06:00:00+00:00
$dateFromTimestamp = $date->format($format);
// This is the beginning of the day
// 2012-03-01T00:00:00+00:00
$startOfDay = $date->setTime(0,0);
// This is the beginning of the next day
// 2012-03-02T00:00:00+00:00
$startOfNextDay = $startOfDay->modify('+1 day');
I would personally avoid using the end of the day unless it's absolutely necessary. You can, of course, use 23:59:59 but this is not the actual end of the day (there's still 1 second left). What I do is use the start of the next day as my end boundary, for example:
$start = new DateTime('2021-11-09 00:00:00');
$end = new DateTime('2021-11-10 00:00:00');
if ($someDateTime >= $start && $someDateTime < $end) {
// do something
}
If I must use the end of the day, I'd go with calculating the start of the next day and then subtracting 1 microsecond from that.
$beginOfDay = (new DateTime('today', new DateTimeZone('Asia/Tehran')))->getTimestamp();
$endOfDay = $beginOfDay + 86399;
You can set a timezone by replacing "Asia/Tehran". One day is 86400 seconds, Don't ask me why 86399, It is a whisper in my mind that says it is 86399, So I do not even want to think about its truth.

Difference between dates [duplicate]

This question already has answers here:
Closed 12 years ago.
Possible Duplicates:
Difference between dates
How to calculate the date difference between 2 dates using php
So, I have two dates. For instance, 2010-09-24 and 2010-09-25. I want to check if between those two dates the difference is 1 day.
I don't need to get a value of 86400 which means one day in seconds.
Don't forget that it can be 28, 28, 29, 30, 31 days in month.
Thanks.
What I have right now, but it doesn't work when there is difference between months:
$strto = strtotime($date);
$d1 = date('d', $strto);
$d2 = date('d', time());
echo $d2- $d1;
You can use strtotime to get the number of seconds in between
echo abs(strtotime('2010-09-24') - strtotime('2010-09-25'));
Don't use the day value - (eg date('d', ...)) - leave it as an integer (the result of strtotime()). Then subtract those dates, and then get the floor(difference / 86400).
Like so:
$dt = strtotime($date);
echo floor(abs(time() - $dt) / 86400);
You can do this nicely with the DateTime class if you have PHP 5.3:
<?php
$datetime1 = new DateTime('2010-09-25');
$datetime2 = new DateTime('2010-09-26');
$interval = $datetime1->diff($datetime2);
$intervaldays = (int) $interval->format('%R%d'); // %R signs the result +/-
This is probably less efficient than using strtotime methods, but it is very readable.
Why are you using date('d'... which returns the day of the month?
strtotime will create a UNIX-timestamp which is exactly what time() returns, so abs(time() - strtotime($date)) should already do the job. This way you don't have to worry how many days a month has as you're only working with timestamps.
This will get you the number of (complete) days:
floor( abs(time() - strtotime($date)) / 86400 )

How do I find the unix timestamp for the start of the next day in php?

I have a unix timestamp for the current time. I want to get the unix timestamp for the start of the next day.
$current_timestamp = time();
$allowable_start_date = strtotime('+1 day', $current_timestamp);
As I am doing it now, I am simply adding 1 whole entire day to the unix timestamp, when instead I would like to figure out how many seconds are left in this current day, and only add that many seconds in order to get the unix timestamp for the very first minute of the next day.
What is the best way to go about this?
The most straightforward way to simply "make" that time:
$tomorrowMidnight = mktime(0, 0, 0, date('n'), date('j') + 1);
Quote:
I would like to figure out how many seconds are left in this current day, and only add that many seconds in order to get the unix timestamp for the very first minute of the next day.
Don't do it like that. Avoid relative calculations whenever possible, especially if it's so trivial to "absolutely" get the timestamp without seconds arithmetics.
You can easily get tomorrow at midnight timestamp with:
$tomorrow_timestamp = strtotime('tomorrow');
If you want to be able to do a variable amount of days you could easily do it like so:
$days = 4;
$x_num_days_timestamp = strtotime(date('m/d/Y', strtotime("+$days days"))));
$tomorrow = strtotime('+1 day', strtotime(date('Y-m-d')));
$secondsLeftToday = time() - $tomorrow;
Something simple like:
$nextday = $current_timestamp + 86400 - ($current_timestamp % 86400);
is what I'd use.
The start of the next day is calculated like this:
<?php
$current_timestamp = time();
$allowable_start_date = strtotime('tomorrow', $current_timestamp);
echo date('r', $allowable_start_date);
?>
If it needs to follow your peculiar requirement:
<?php
$current_timestamp = time();
$seconds_to_add = strtotime('tomorrow', $current_timestamp) - $current_timestamp;
echo date('r', $current_timestamp + $seconds_to_add);
?>
My variant:
$allowable_start_date = strtotime('today +1 day');

Categories