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
Related
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")
I'm trying to validate input in mm/yyyy format by round tripping a string. The problem:
<?php
$datestr = "06/2017";
$realdate = DateTime::createFromFormat('m/Y', $datestr);
$datestr2 = date_format($realdate,'m/Y');
echo "date in: $datestr\n";
echo "date out: $datestr2\n";
?>
yields the following:
date in: 06/2017
date out: 07/2017
Why is the second value incremented a month?
Because you did not specify a day it assumes today (the 31st). There is no June 31st so PHP assumes July 1st.
Assuming you are always working with the date formats you use in your example, you can easily work around this by specifying the first of the month for your dates:
$datestr = "01/06/2017";
$realdate = DateTime::createFromFormat('d/m/Y', $datestr);
$datestr2 = date_format($realdate,'m/Y');
echo "date in: $datestr\n";
echo "date out: $datestr2\n";
Demo
It is not necessary to include the day '01'. A ! in the Format resets all fields (year, month, day, hour, minute, second). Without !, all fields will be set to the current date and time. (-> PHP Manual)
$datestr = "06/2017";
$realdate = DateTime::createFromFormat('!m/Y', $datestr);
var_dump($realdate);
/*
object(DateTime)#2 (3) {
["date"]=> string(26) "2017-06-01 00:00:00.000000"
["timezone_type"]=> int(3)
["timezone"]=> string(13) "Europe/Berlin"
}
*/
With the ! a non-existent day is always set to 1 and the time to 00:00:00. If only the day is set, as in John Conde's solution, the date always contains the current time.
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
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.
YouTube returns the Updated date and Submitted on date as follows: 2010-08-22T04:46:18.000Z
Is there a PHP function, or a date mask that parses this?
$dt = DateTime::createFromFormat("Y-m-d\TH:i:s.uP", "2010-08-22T04:46:18.000Z");
var_dump($dt);
// object(DateTime)#1 (3) {
// ["date"]=>
// string(26) "2010-08-22 04:46:18.000000"
// ["timezone_type"]=>
// int(2)
// ["timezone"]=>
// string(1) "Z"
// }
This uses the DateTime class. It is timezone and fractional seconds aware. To display the date use the format method:
echo $dt->format("Y-m-d H:i:s e");
// 2010-08-22 04:46:18 Z
To convert the date to local timezone use the setTimezone method:
$dt->setTimezone(new DateTimeZone(date_default_timezone_get()));
echo $dt->format("Y-m-d H:i:s e");
// 2010-08-21 21:46:18 America/Los_Angeles
sounds like strtotime is what you're looking for.
EDIT: if this doesn't work, take a look at the Date and Time classes - there are methods for parsing dates in specified formats (like this - doesn't return a timestamp directly, but if you construct a DateTime from this, you can use it's getTimestamp-method)
Try this:
$date=substr("2010-08-22T04:46:18.000z",0,strlen("2010-08-22T04:46:18.000z")-1);
$stamp=strtotime($date);
The "z" at the end seems to be the problem for strtotime.