php datetime using existing date to create new date with added days - php

I have a date:
$launched=new DateTime();
I would like to create a new DateTime using $launched but adding days. Something like:
$expired=new DateTime($launched->modify("+$expiry days"));
How can I do this?

Assuming you are using PHP 5.5 or newer DateTimeImmutable makes this easy:
$launched = new DateTimeImmutable();
$expired = $launched->modify("+$expiry days");
DateTimeImmutable does not modify the original object which is what DateTime does. So you can just assign the resulting object return by modify() to a variable and have a new object with a date in the future.
If you are using an older, and obsolete, version of PHP you can clone the original object to achieve the same result:
$launched = new DateTimeImmutable();
$expired = clone $launched;
$expired->modify("+$expiry days");

Related

How to correctly add a date and a time (string) in PHP?

What is the "cleanest" way to add a date and a time string in PHP?
Albeit having read that DateTime::add expects a DateInterval, I tried
$date = new \DateTime('17.03.2016');
$time = new \DateTime('20:20');
$result = $date->add($time);
Which was no good and returned nothing to $result.
To make a DateInterval from '20:20', I only found very complex solutions...
Maybe I should use timestamps?
$date = strtotime($datestring);
$timeObj = new \DateTime($timestring);
// quirk to only get time in seconds from string date
$time = $timeObj->format('H') * 3600 + $timeObj->format('i') * 60 + $timeObj->format('s');
$datetime = $date+$time;
$result = new \DateTime;
$result->setTimestamp($datetime);
In my case, this returns the desired result, with the correct timezone offset. But what do you think, is this robust? Is there a better way?
If you want to add 20 hours and 20 minutes to a DateTime:
$date = new \DateTime('17.03.2016');
$date->add($new \DateInterval('PT20H20M'));
You do not need to get the result of add(), calling add() on a DateTime object will change it. The return value of add() is the DateTime object itself so you can chain methods.
See DateInterval::__construct to see how to set the intervals.
DateTime (and DateTimeImmutable) has a modify method which you could leverage to modify the time by adding 20 hours and 20 minutes.
Updated
I've included examples for both DateTime and DateTimeImmutable as per the comment made, you don't need to assign the outcome of modify to a variable because it mutates the original object. Whereas DateTimeImmutable creates a new instance and doesn't mutate the original object.
DateTime
<?php
$start = new DateTimeImmutable('2018-10-23 00:00:00');
echo $start->modify('+20 hours +20 minutes')->format('Y-m-d H:i:s');
// 2018-10-23 20:20:00
Using DateTime: https://3v4l.org/6eon8
DateTimeImmutable
<?php
$start = new DateTimeImmutable('2018-10-23 00:00:00');
$datetime = $start->modify('+20 hours +20 minutes');
var_dump($start->format('Y-m-d H:i:s'));
var_dump($datetime->format('Y-m-d H:i:s'));
Output
string(19) "2018-10-23 00:00:00"
string(19) "2018-10-23 20:20:00"
Using DateTimeImmutable: https://3v4l.org/oRehh

Error in PHP $date2 = $date1->format('Y-m-d')

I get the following error:
PHP Fatal error: Call to a member function format() on a non-object
in code:
$date = new DateTime();
$date1 = $date->modify('-6 months');
$date2 = $date1->format('Y-m-d');
I want to get this date of 6 months before from now and delete all entries in database which are earlier than this 6 months date:
$query = $conn->prepare("DELETE FROM files WHERE files.date < ?");
$query->bind_param('s', $date2);
$query->execute();
In MySQL "date" field is in files table of datatype "timestamp" whose value is "CURRENT_TIMESTAMP" stored by MySQL as default when a row is created.
This code get you 6 month ago from now:
date('Y-m-d', strtotime('now -6 month'))
EDIT:
and use DateTime:
echo (new DateTime('-6 months'))->format('Y-m-d');
try below code:
<?php
$date = new DateTime('-6 months');
echo $date2 = $date->format('Y-m-d');
?>
It appears you are using an outdated version of php.
Starting with php 5.3+ DateTime::modify returns the datetime object is was called upon prior to that null was returned.
You don't need to assign the result of modify to a new variable as it modifies the current object and does not return a new one.
To make it work on 5.2:
<?php
$date = new DateTime();
$date->modify('-6 months');
$dateS = $date->format('Y-m-d');
var_dump($dateS);
You should however update your php to a supported version.
PHP 5.4+ short-example:
$dateS = (new DateTime('-6 months'))->format('Y-m-d');
Seems like the call to
$date->modify('-6 months');
encounters an error and does not return a DateTime instance but probably false (see documentation).
Which PHP version are you using? I could not reproduce that error with the given example on PHP 5.5.9
Maybe you could just use the strtotime function
EDIT:
I took the Wayback Machine from Internet Archive and found that older versions of PHP ( i.e. 5.1.0) returned NULL instead of the DateTime object: see for yourself. In that case it seems like you apply the modification on your date directly so you need to change your code to
$date = new DateTime();
$date->modify('-6 months');
$dateString = $date->format('Y-m-d');
$query = $conn->prepare("DELETE FROM files WHERE files.date < ?");
$query->bind_param('s', $dateString);
$query->execute();

date_add() changing 2 variables in PHP rather than 1

Here is an example of the code I used:
<?php
date_default_timezone_set("Europe/London");
$date1 = date_create("2014-04-05");
$date2 = $date1;
date_add($date2, new DateInterval("P1M"));
echo "Date 1: ".date_format($date1, "Y-m-d")."<br/>";
echo "Date 2: ".date_format($date2, "Y-m-d")."<br/>";
?>
The result for this would be:
Date 1: 2014-05-05
Date 2: 2014-05-05
I was expecting the result of:
Date 1: 2014-04-05
Date 2: 2014-05-05
How can I get the expected result and fix this?
I can only use PHP, HTML and CSS so no jQuery or Javascript please.
The clone keyword is what you need.
$date2 = clone $date1;
When an object is cloned, a shallow copy of all of the object's properties. Any properties that are references to other variables, will remain references.
If your object $date2 holds a reference to another object $date1 which it uses and when you replicate the parent object you want to create a new instance of this other object so that the replica has its own separate copy.
Source
This is due to how objects are assigned by reference since PHP 5; after assignment, changes made to one object are reflected in the other as well.
The generic solution is to clone the object:
$date2 = clone $date1;
In this case you could also use the DateTimeImmutable interface (introduced in 5.5) which creates new instances whenever you attempt to modify it, e.g. using ->add().
$date1 = new DateTimeImmutable('2014-04-05');
$date2 = $date1;
$date2 = $date2->add(new DateInterval('P1M'));
echo "Date 1: ".date_format($date1, "Y-m-d")."<br/>";
echo "Date 2: ".date_format($date2, "Y-m-d")."<br/>";
This code can be made easier by doing this:
$date1 = new DateTimeImmutable('2014-04-05');
$date2 = $date1->add(new DateInterval('P1M'));

Convert date into timestamp where strtotime has already been used

I' am trying to convert the date of next 7 days into timestamp so that I can compare against my date timestamp in database to get some results.
This function is used to get the next 7 days from today
$next_date = date("d/m/Y", strtotime("7 day"))
Output
30/04/2014
Now I' am again running strtotime() on $next_date variable who holds the next 7days and converting to timestamp.
echo strtotime($next_date);
This is not working. I followed this stackoverflow answer and few others.
As an alternative suggestion you could look at PHP's internal DateTime() and DateInterval() classes. It makes it a bit easier to convert between formats and do date/time addition and subtraction imho. DateInterval requires at least PHP version 5.3.
An example:
// create a current DateTime
$currDate = new DateTime();
// copy the current DateTime and
// add an interval of 7 days
$nextDate = clone $currDate;
$nextDate->add(new DateInterval('P7D'));
// both objects are easily converted to timestamps
echo $currDate->getTimestamp(); // e.g: 1398296728
echo $nextDate->getTimestamp(); // e.g: 1398901528
// and both can be easily formatted in other formats
echo $currDate->format('d/m/Y'); // e.g: 24/04/2014
echo $nextDate->format('d/m/Y'); // e.g: 01/05/2014
EDIT
For completeness, here's another example of how you can add seven days to a DateTime object:
$now = new DateTimeImmutable();
$then = $now->modify('+7 days');
var_dump($now->format('Y-m-d'), $then->format('Y-m-d'));
Yields:
string(10) "2016-05-24"
string(10) "2016-05-31"
You can also use DateTime - the difference in this use case is that DateTime::modify() will modify the instance $now where DateTimeImmutable::modify() will return a new DateTimeImmutable object - so if you need to create a new object whilst retaining the old one, it's probably the most succinct approach.
Hope this helps :)
http://www.php.net/manual/en/datetime.construct.php
http://www.php.net/manual/en/dateinterval.construct.php
Just store the value from strtotime first?
$timestamp_in_7_days = strtotime('7 day');
$next_date = date('d/m/Y', $timestamp_in_7_days);
There is no need to throw the time back and forth between unix timestamp and date-format.

php check if specified time has expired

I am trying to compare the current datetime, with a datetime from the database using string, as the following:
$today = new DateTime("now");
$todayString = $today->format('Y-m-d H:i:s');
if($todayString >= $rows["PrioritizationDueDate"])
{...}
$todayString keeps giving me the time 7 hours earlier (i.e now its 11:03pm, its giving me 16:04).
More, is it better to compare this way, or should i compare using datetime objects?
$todayString keeps giving me the time 7 hours earlier
you have to setup a timezone for the DateTime object I believe.
is it better to compare this way
I doubt so.
The general way is to compare in the query, using SQL to do all date calculations and return only matching rows.
Set a correct timezone in the constructor to DateTime.
$today = new DateTime("now", new DateTimeZone('TimezoneString'));
Where TimezoneString is a valid timezone string.
Edit: For a more complete example using DateTime objects, I would use DateTime::diff in conjunction with DateTime::createFromFormat.
$rows["PrioritizationDueDate"] = '2011-11-20 10:30:00';
$today = new DateTime("now", new DateTimeZone('America/New_York'));
$row_date = DateTime::createFromFormat( 'Y-m-d H:i:s', $rows["PrioritizationDueDate"], new DateTimeZone('America/New_York'));
if( $row_date->diff( $today)->format('%a') > 1)
{
echo 'The row timestamp is more than one day in the past from now.';
}
Demo
First set time zone using this function
date_default_timezone_set('UTC');
Then either you can use function strtotime() or get difference directly...

Categories