Give value to a date object from another and change only one - php

I'm new to php and I'm still trying to understand object usage.
This is my script:
$Date1=date_create_from_format('Y-m-d', '2017-01-01');
$Date2=$Date1;
$Date2->modify('last day of');
echo '</br>Date1='.$Date1->format('Y-m-d');//output: Date1=2017-01-31
echo '</br>Date2='.$Date2->format('Y-m-d');//output: Date2=2017-01-31
My goal is to have two different date objects:
the 1st from the string date;
the 2nd containing the last day of the month
How can I do that?

Use clone to create identical copy of object
$Date1=date_create_from_format('Y-m-d', '2017-01-01');
$Date2=clone $Date1;
$Date2->modify('last day of');
echo '</br>Date1='.$Date1->format('Y-m-d');
echo '</br>Date2='.$Date2->format('Y-m-d');

Try this:
$Date2 = clone $Date1;

$Date1 = DateTimeImmutable::createFromFormat('Y-m-d' '2017-01-01');
The method you are using creates a mutable object, but you're looking for an immutable one. The immutable one will return a new date object instead of changing the current one.
See documentation for the DateTimeImmutable class.

Related

Laravel date changing when I update a variable

I'm writing a scope query and I'm passing in a fetch_date to pull things from the DB table based on the created_at timestamp.
I'm trying to find all records for a month, but the variable $fetch_date keeps changing whenever I try the following:
//$fetch_date is a carbon instance and is equal to the month the user selected
//ie: Carbon {#221 ▼
// +"date": "2016-07-01 00:00:00.000000"
//Create the next_month
$next_month = $fetch_date->addMonth();
//Format next_month as a string
$next_month = $next_month->format('Y-m-d');
//Format fetch_date as a string
$fetch_date = $fetch_date->format('Y-m-d');
dd($fetch_date);
//This now gives me 2016-08-01 - why?
Why does the fetch_date change? I'm essentially trying to keep the $fetch_date as the current month and the $next_month to simply be the start of the next month.
I'm guessing there's a real simple reason to this I'm just overlooking.
Because calling the addMonth method has side effects.
If you look at Carbon's source, you'll see that all addMonth is doing is calling addMonths with a value of 1, which in turn is simply calling DateTime::modify. It's not explicitly spelled out in the documentation, but from the examples it's pretty plain that calling the method modifies the stored time value:
Example #1 DateTime::modify() example
<?php
$date = new DateTime('2006-12-12');
$date->modify('+1 day');
echo $date->format('Y-m-d');
?>
To avoid this, keep a copy of of the time around and modify that:
$also_fetch_date = clone $fetch_date;
$next_month = $also_fetch_date->addMonth();
// ...
Seems you are adding a month to the fetch_date variable.
Try this:
$next_month = Carbon::createFromFormat('Y-m-d', $fetch_date->format('Y-m-d'));
$next_month->addMonth();
dd($next_month->format('Y-m-d'));
Take a look at the documentation of Carbon: http://carbon.nesbot.com/docs/
Maybe will help you

Trying to define my own time type in PHP

So I am trying to define a time type and I am not quite sure how to do it. The answers I find online give examples of defining a time type with the current time (i.e date("h:i:sa")) however I am trying to define a hard coded version.The format I want is (HH:mm:ss) (hour:minutes:seconds) The reason why I need the variable to be declared as time type is so that they can be used later on to be compared.
<?php
$my_time = '10:00:00';
$your_time = '11:00:00';
if($my_time > $your_time){
echo "You have less time";
}
?>
Use DateTime to create proper objects, then you can use standard comparison operators.
$my_time = DateTime::createFromFormat('H:i:s', '10:00:00');
$your_time = DateTime::createFromFormat('H:i:s', '11:00:00');
var_dump($my_time > $your_time);
Fiddle
The PHP DateTime Class is what you need.
//instantiate a DateTime Object
$time = new DateTime();
//Use the DateTime obj to create two new DateTime objects
$yourTime = $time->createFromFormat('h:i:s', '12:30:30'); //third param here can define tz
$theirTime = $time->createFromFormat('h:i:s', '12:10:15');
//Use diff() to return a DateInterval
$dateInterval = $yourTime->diff($theirTime);
//Format the DateInterval as a string
$differenceBetweenYoursAndTheirs = $dateInterval->format('%h:%i:%s');
//Do something with your interval
echo "The difference between {$yourTime->format('h:i:s')} and {$theirTime->format('h:i:s')} is $differenceBetweenYoursAndTheirs";

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: Add difference from two DateTime object to another date using DateTime::modify

How do I add the difference between two DateTime objects to another DateTime object? I tried some code similar to the one below, but it didn't work.
$first_time=new DateTime('01/01/2000 00:00:00');
$second_time=new DateTime('01/01/2000 00:00:50');
$diff=$first_time->diff($second_time);
$time=new DateTime('01/01/2012 12:00:00');
$time->modify('+'.$diff->format('%s').' seconds');
echo $time;
//Should echo: "01/01/2012 12:00:50"
Can somebody help me out?
format() does not calculate the absolut number of seconds of the Interval, it just give you the values of the intern attributes. Since you want to add, why not simply use add()? diff() returns a DateInterval object, and this is what add() needs.
$first_time=new DateTime('01/01/2000 00:00:00');
$second_time=new DateTime('01/01/2000 00:00:50');
$diff=$first_time->diff($second_time);
$time=new DateTime('01/01/2012 12:00:00');
$time->add($diff);
echo $time;

Categories