Laravel Carbon error with year in difference between dates - php

Good afternoon...
I try to make the difference in years between the current date and a date in the database like this:
$final = '2016-05-10'; //date database
$hoy = \Carbon\Carbon::now(); //today
$fecha_ingreso = \Carbon\Carbon::createFromFormat('Y-m-d', $final);
$diff = $hoy->diffInYears($fecha_ingreso); //diff
But when doing a var_dump() of $fecha_ingreso it shows me the following:
object(Carbon\Carbon)#259 (3) { ["date"]=> string(26) "2155-05-10 22:27:09.000000" ["timezone_type"]=> int(3) ["timezone"]=> string(3) "UTC" }
The day and the month are ok but the year is not, why can this error be ??
Thank you very much for the help.

I assume you want the difference in number of years, try this.
$dbDate = \Carbon\Carbon::parse('2016-05-10');
$diffYears = \Carbon\Carbon::now()->diffInYears($dbDate);
// $diffYears is 1

Related

parse int to datetime with carbon

I have an example value of : 20160530105130
Which I want to convert to a datetime.
I have tried Carbon::createFromFormat('Ym',$value)
But that just errors.
I also tried with timestamp, but again error.
Anyone have an idea how I can achive this?
Create a DateTime or Carbon object from the string and use the year and month there.
$str = '20160530105130';
$dt = DateTime::createFromFormat('!Ym????????',$str);
var_dump($dt);
//object(DateTime)#2 (3) { ["date"]=> string(26) "2016-05-01 00:00:00.000000"
Demo: https://3v4l.org/bOJdU
With carbon:
$str = '20160530105130';
$dt = Carbon::createFromFormat('!Ym????????',$str);
echo $dt; //2016-05-01 00:00:00
Alternatively, the string can also be completely parsed with DateTime. The day and time can then be set to the desired values using the modify method. This variant makes it easier to read what is being done.
$str = '20160530105130';
$dt = date_create($str)->modify('first day of this month 00:00');
//object(DateTime)#2 (3) { ["date"]=> string(26) "2016-05-01 00:00:00.000000"
Carbon::createFromFormat('YmdHis', "$value")

Calculate months diff between dates without days

is there a good way to calculate months diff between dates without days? I mean I have two not full dates for example:
2017-09 and 2018-11. I need to calculate how many months is between this two dates. I read something about this and I know I can for example use:
$firstDate = "2017-09";
$secondDate = "2018-11";
$firstDate = new DateTime($firstDate . "-01");
$secondDate = new DateTime($secondDate . "-01");
$interval = date_diff($firstDate, $secondDate);
var_dump($interval->format('%m months'));exit();
This show me 2 months.
How can I reach this? And is there a way to calculate this without adding days "-01" to end of my dates?
I want to calculate difference of months for dates without write "-01" in this dates. Only year and month.
You need the years also.
Also you had a parse error on the date 2017-0901 is not valid either 2017-09 or 2017-09-01.
$firstDate = "2017-09";
$secondDate = "2018-11";
$firstDate = new DateTime($firstDate);
$secondDate = new DateTime($secondDate);
$interval = date_diff($firstDate, $secondDate);
echo $interval->format('%y')*12+$interval->format('%m') . " months";
// 14 months
https://3v4l.org/XGdXg
Just use plain arithmetic. We're clearly not concerned about timezones, daylight saving, calendar changes, etc. so we're also not concerned about parsing the date "in some timezone, based on some calendar". What we're left with is just plain arithemtics, using months. A year is 12 months. And now we're almost done already.
function ym_as_months($v) {
$v = array_map("intval", explode("-", $v));
return $v[0]*12 + $v[1];
}
$firstDate = "2017-09";
$firstMonths = ym_as_months($firstDate);
$secondDate = "2018-11";
$secondMonths = ym_as_months($secondDate);
$diff = $secondMonths - $firstMonths;
echo "There are $diff months between $firstDate and $secondDate.";
And we get:
There are 14 months between 2017-09 and 2018-11.
Perfect.
Of course, depending on how you get those date stamps in your application, it might be far easier to not even pass them in as string, but simply as two numbers from the get go, in which case this becomes even less work.
Alternatively, do your conversion as the very last step, as per another answer here.
I will suggest using Carbon for dates related calculations in PHP as it really makes everything easy.
To calculate months between two dates with Carbon, you simply need to do this
//year & month
$startDate = Carbon::create('2017', '9');
$endDate = Carbon::create('2018','11');
$diff = $startDate->diffInMonths($endDate);
https://secure.php.net/manual/en/datetime.createfromformat.php
$a = DateTime::createFromFormat('Y-m', '2017-09');
$b = DateTime::createFromFormat('Y-m', '2018-11');
$diff = $a->diff($b);
var_dump(
$a, $b,
$diff->format("%y years, %m months"),
sprintf("%d months", $diff->y * 12 + $diff->m)
);
Output:
object(DateTime)#1 (3) {
["date"]=>
string(26) "2017-09-06 18:33:58.000000"
["timezone_type"]=>
int(3)
["timezone"]=>
string(16) "Europe/Amsterdam"
}
object(DateTime)#2 (3) {
["date"]=>
string(26) "2018-11-06 18:33:58.000000"
["timezone_type"]=>
int(3)
["timezone"]=>
string(16) "Europe/Amsterdam"
}
string(17) "1 years, 2 months"
string(9) "14 months"

PHP Date after time change in Europe

This morning I ran unit tests and they failed.
Tests took offers from last 48 hours by calculating time with:
date('U', time() - 48 * 3600)
When I used:
(new DateTime('-48 hours'))->format('U')
it shown one hour difference.
May the reason be that on sunday in Poland time was moved one hour backwards
I presume your server runs with Europe/Warsaw as default time zone. PHP date/time calculations are often incorrect if they cross DST boundaries, as it's the case here. I suggest you do all maths in UTC and convert from/to local time as needed.
Please compare:
$warsaw = new DateTimeZone('Europe/Warsaw');
$utc = new DateTimeZone('UTC');
$start = new DateTime('2018-10-28 04:30:00', $warsaw);
$start->modify('-4 hours');
var_dump($start);
$start = new DateTime('2018-10-28 04:30:00', $warsaw);
$start->setTimezone($utc);
$start->modify('-4 hours');
$start->setTimezone($warsaw);
var_dump($start);
object(DateTime)#3 (3) {
["date"]=>
string(26) "2018-10-28 00:30:00.000000"
["timezone_type"]=>
int(3)
["timezone"]=>
string(13) "Europe/Warsaw"
}
object(DateTime)#4 (3) {
["date"]=>
string(26) "2018-10-28 01:30:00.000000"
["timezone_type"]=>
int(3)
["timezone"]=>
string(13) "Europe/Warsaw"
}
The Unix timestamp version of your code should be unaffected because a Unix timestamp is a fixed moment in time (thus doesn't switch with time zones).

Why convert Timestamp '2016-10-06T09:50:54.000Z' with php

This code :
$timestamp = 2016-10-06T09:50:54.000Z;
How do I separate or convert from the timestamp into a date and time?
example :
TimeStamp 2016-10-06T09:50:54.000Z
Date 2016-10-06
Jam(GMT +7) 04:55:45
Please help to solve this problem. Thanks
$d = new DateTime('2016-10-06T09:50:54.000Z');
echo $d->format('Y-m-d\TH:i:s.u'); // 2016-10-06T09:50:54.000000
echo $d->format('Y-m-d'); // 2016-10-06
// convert to GMT+7 timezone
$d->setTimezone(new DateTimeZone('GMT+7'));
echo $d->format('h:i:s'); // 04:50:54
<?php
$timestamp = "2016-10-06T09:50:54.000Z";
$datetime = new Datetime('2016-10-06T09:50:54.000Z');
echo "Date".$datetime->format('Y-m-d')."<br>";
echo "Jam".$datetime->format('H:i:s');
?>
Take a look at this short example:
<?php
$datetime = new Datetime('2016-10-06T09:50:54.000Z');
var_dump($datetime->format('Y-m-d H:i:s'));
The output obviously is: string(19) "2016-10-06 09:50:54"
Using different format strings you can convert your date time object into whatever representation you want to. 'Y-m-d' will give the date in international format for example.
Take a look at the great documentation: http://php.net/manual/en/class.datetime.php
Not much of a mystery:
<?php
$timestamp = '2016-10-06T09:50:54.000Z';
$dt = new DateTime($timestamp);
var_dump($dt);
$dt->setTimezone(new DateTimeZone('Asia/Jakarta'));
var_dump($dt);
object(DateTime)#1 (3) {
["date"]=>
string(26) "2016-10-06 09:50:54.000000"
["timezone_type"]=>
int(2)
["timezone"]=>
string(1) "Z"
}
object(DateTime)#1 (3) {
["date"]=>
string(26) "2016-10-06 16:50:54.000000"
["timezone_type"]=>
int(3)
["timezone"]=>
string(12) "Asia/Jakarta"
}
Unlike strings, giving format to a proper date is trivial.
I don't know what time zone Jam is but I suggest you assign a city so you can account for DST (I've used Asia/Jakarta in my sample code, the complete list can be found at List of Supported Timezones). Just relying on a UTC offset like +7 may make your code unreliable during the summer.

php/mysql: strToTime error manipulating dates

I have some code for rendering dates that was working great for a couple of years and is now broken. I don't know if it has something to do with my host changing version of PHP or somehow an error crept in.
Basically, dates such as 11/30/15 are now getting rendered as 11/30/-1
Here is an example of what is going on:
$olddate = $row['date'];//in database this looks like:0000-00-00 00:00:00
$newdate = nicedate($olddate);
echo "starting date time: ".$olddate;//displays as 'starting date time: 0000-00-00 00:00:00'
echo "after transforming it with nice date: ".$newdate; //displays as 'after transforming it with nice date: 11/30/-1'
I also tried just running strtotime and get this:
echo "after transforming it with strtotime: ".nicedate($row['starttime']);//-62169966000
// gets nice data
function nicedate($datetime) {
$niceDate = strtotime($datetime);
$niceDate = date("m/d/y",$niceDate);
return $niceDate;
}
As you can see here https://3v4l.org/8gqCK it really depends on which PHP version you are using.
PHP will render the string 0000-00-00 00:00:00 to -0001-11-30 00:00:00.000000
This is an example output from DateTime:
object(DateTime)#1 (3) {
["date"]=>
string(27) "-0001-11-30 00:00:00.000000"
["timezone_type"]=>
int(3)
["timezone"]=>
string(13) "Europe/Berlin"
}
The OUTPUT also depends on the time zone:
object(DateTime)#1 (3) {
["date"]=>
string(27) "-0001-11-29 23:06:32.000000"
["timezone_type"]=>
int(3)
["timezone"]=>
string(3) "UTC"
}
This would output:
...with nice date: 11/29/-1
And here strtotime():
int(-62169987208)
So you see the date function were changed on different version, what you can do now ist just to check if the date is 0000-00-00 00:00:00:
function nicedate ( $datetime ) {
if( $datetime == "0000-00-00 00:00:00" ) return "Some value or false?";
...
...
}
You also have a look at the MySQL mode: NO_ZERO_IN_DATE
Updated approach due to the comments below:
function nicedate( $datetime ) {
if( !validateDate( $datetime ) ) return "something";
$dateTimeObject = DateTime::createFromFormat('Y-m-d H:i:s', $datetime );
return $dateTimeObject->format( "m/d/y" );
}
function validateDate($date) {
$d = DateTime::createFromFormat('Y-m-d H:i:s', $date);
return $d && $d->format('Y-m-d H:i:s') == $date;
}
function was copied from this answer or php.net
This is because 0000-00-00.... is not a valid date. What happens is simple, from year, month, day,... is alway one (1) substracted from the last.
0000 -1 = -1// year
00 - 1 = 11// month, because 12 is the highest value that datetime recognizes as month
00 - 1 = 30// day, because 31 is the highest value that datetime recognizes as day
For hours, minutes, seconds,.. it's ok, because zero is a valid value for time.
That's why it is rendered like this: -0001-11-30 00:00:00.000000

Categories