PHP DateTime from integer values - php

If have $day, $month, and $year as integer values and want to create a DateTime object in PHP 7.
Creating a string representation to let it parse into a date, such as:
$date = new DateTime("$year-$month-$day");
looks quite ridiculous to me. I tried to set the date after creation, such as:
$date = (new DateTime())->setDate($year, $month, $day);
but since new DateTime() uses the current timestamp the time part of the object is still set to the current time (instead of 00:00:00). So I'd have to set the time value as well, what seems inefficcient to me as well:
$date = (new DateTime())->setDate($year, $month, $day)->setTime(0, 0);
What is therefore the best (i.e. most performant) way to create a new DateTime instance for a date when I already have day, month and year as integer values?
UPDATE
For some users seem to misinterpret my question: I'm asking rather for a performant than for an aesthetic solution. ;-)
Yes new DateTime("$year-$month-$day") is short and nice, but is it the recommended way to let PHP parse a date string I already have split to its int values?

I understand the concern, converting integers into a string which is then parsed by some automagic as some matching date format does seem somewhere between inefficient and insane to instantiate DateTime objects from what are already integers. Alas, there's no alternative constructor in standard PHP DateTime classes that would offer any alternative.
Personally I always feel icky letting PHP auto-parse any sort of date string to hope it gets it right, so I'd actually prefer the more explicit alternative:
DateTime::createFromFormat('Y-m-d', "$year-$month-$day")
But that is mostly personal preference, new DateTime("$year-$month-$day") should accomplish exactly the same thing as long as your variables actually contain the values you think they do.
If you're only after a conversion to UNIX timestamps, there's mktime which accepts explicit integer arguments, albeit it in a weird order:
mktime(0, 0, 0, $month, $day, $year)

Related

Convert timestamp coming from SQL database to String

I am saving the timestamp in SQL as bigint(20). The number is correct and in android or https://www.epochconverter.com it works fine.
However I am not able to create a date-string based on the timestamp received from database.
First of all, the timestamp seems to come from database as a String, so I can't just say echo date("d.m.Y, $timestamp). The result is the famous 31.12.1969.
So I tried echo date("d.m.Y, strtotime($timestamp)). However, even though strtotime is said to be able to convert almost everything to a timestamp, a simple String containing a timestamp is not possible. Results still remained on the last day of Brian Adams probably favorite year.
Some progress I made by casting the $timestamp to a float value like so: echo date("d.m.Y", floatval($timestamp));. However, now things got really confusing for me. I seemed to have successfully converted my timestamp, however, date() gave me the dates around 02.09.52299.
The timestamps I am using are timestamps of current time, e.g. 1588489252657, which currently leads to the date 23.03.52307.
So all I want is to come to a date based on the timestamp 1588489252657 to see the 03.05.2020 on my screen.
Thanks for any advice!
<?php
$timestamp = 1588489252657; // Timestamp in Milliseconds
$seconds = round($timestamp/1000, 0); // Timestamp Rounded to Seconds
$date = new DateTime(); // Create PHP DateTime Object
$date->setTimestamp($seconds); // Set the Timestamp
echo $date->format('Y-m-d H:i:s'); // Specify the Required Format
The answers are pretty much in the comment sections. But I have shared this answer since this is another approach in OOP fashion. You can leverage the power of PHP's DateTime Class.
PHP Official Documentation For DateTime Class Link Below:
PHP DateTime Class
You have to transform the timestamp to seconds first.
$timestamp = 1588489252657;
$dateInUnixSeconds = round($timestamp / 1000, 0);
$date = \DateTimeImmutable::createFromFormat('U', (string) $dateInUnixSeconds);
echo $date->format('d.m.Y');
PS:
I recommend you to use the \DateTimeImmutable object to avoid mutability problems.
https://github.com/Chemaclass/php-best-practices/blob/master/technical-skills/immutability.md

Reformatting datetime

Ok, so I've got a time string like this:
2013-08-09T15:00:00
Now as far as I can tell, I'll need to convert this to a timestamp, before I can change the formatting - is that correct, or is there a shorter step? For example using one of the classes here:
http://philsturgeon.co.uk/blog/2012/08/why-php-datetime-rocks
I'm not quite sure what the "T" represents (besides time, obviously) and I'm not sure what format that is.
I want to get it into standard 12 hour time.
Use DateTime()
$dt = new DateTime('2013-08-09T15:00:00');
echo $dt->format('Y-m-d h:i:s');

Converting between illogically formatted dates (changing /slash/ to -dash- )

I am rebuilding a web application from an old one with many inconsistencies. I have to migrate all the data over from the old database to our new structure.
In the old database, dates were stored in the MySQL DB as VARCHAR. We are based in the UK, so dates were written in the format DD/MM/YYYY. I need to convert these dates to MySQL's native DATE() format.
Problem is this - PHP defaults to assuming the dates are in 'American' format (MM/DD/YYYY) because they were originally split with / rather than - - and - forces PHP to assume they are 'European' format.
I am doing this so far to convert them:
$start_date = date('Y-m-d', strtotime($query->row('startdate')));
Where $query->row('startdate') is the column in the old database which was storing the dates. Problem is, I need to first switch all the 21/03/1994s to 21-03-1994.
How can I do this?
$start_date = date('Y-m-d', strtotime(str_replace('/', '-', $query->row('startdate'))));
Or better yet - just change the data in the database:
UPDATE `table` SET `startdate` = REPLACE(`startdate`, '/', '-');
... and then convert the field to type DATE.
---- EDIT ----
Actually, Col. Shrapnel has a point ... I'd overlooked the fact that the date needs reversing as well so it's YYYY-MM-DD; assuming the original date is in the format DD/MM/YYYY a better query might be something like:
UPDATE `table` SET `date` = CONCAT(SUBSTRING(`date`, 7), '-', SUBSTRING(`date`, 4, 2), '-', SUBSTRING(`date`, 1, 2))
Which will reverse the component parts into a string that can be converted to a DATE ... it won't quite work if the original date string doesn't use leading zeroes 1/6/2011 for instance... would need to do something a little cleverer in that case.
WHY bother with all this date time stuff when you need mere a simplest string manipulation of 2 moves long?
$tmp = explode("/",$query->row('startdate'));
$date = "$tmp[2]-$tmp[1]-$tmp[0]";
but, as chris said, you dno't have to involve PHP in this operation as you can convert it using single SQL query using similar string manipulations in the query.
MySQL has a Replace() function that may be the easiest way to do this.
This is the 5.0 API reference:
http://dev.mysql.com/doc/refman/5.0/en/string-functions.html#function_replace
Use str_replace like this:
$start_date = date('Y-m-d', strtotime(str_replace('-','/',$query->row('startdate'))));
That is of course ugly and quick solution - YMMV.
If you're bound to PHP, why not parse the data, normalize it and then continue? E.g. with sscanf:
$r = sscanf($varcharDate, '%d/%d/%d', $day, $month, $year);
if ($r !== 3)
{
throw new Exception(sprintf('Invalid date format given: %s', $varcharDate));
}

Zend_Date adding the timezone to a subtraction result

I have this code:
<?php
$start = new Zend_Date("2011-09-06T10:00:00+02:00",Zend_Date::ISO_8601);
$end = new Zend_Date("2011-09-06T10:01:00+02:00",Zend_Date::ISO_8601);
echo $end->sub($start);
?>
In short: I create two dates, with a minute's difference between them. Then I print out the difference (subtraction) between them.
The result, however, is:
01-01-1970 02:01:00
Basically, what I understand from this behaviour is that Zend_Date operates on dates without taking timezone into consideration, and then puts the timezone back in the result. Of course, this means that the subtraction result is off by the value of the timezone (+2h in my case).
What's the best way to get around this?
Yes, when echo'ing a Zend_Date, it will take your timezone into account. To get the difference formatted for GMT dates, you have to set the timezone explicitly:
$start = new Zend_Date("2011-09-06T10:00:00+02:00",Zend_Date::ISO_8601);
$end = new Zend_Date("2011-09-06T10:01:00+02:00",Zend_Date::ISO_8601);
echo $end->sub($start)->setTimezone('GMT')->get(Zend_Date::ISO_8601);
This would output: 1970-01-01T00:01:00+00:00
On a sidenote, if you do not need the dynamic localization features of Zend_Date it's best to avoid it in favor or PHP's native DateTime API. There is really no reason to use Zend_Date just because it exists in ZF. PHP's own DateTime API is faster and easier to use. Getting the time difference with the DateTime API would be
$start = new DateTime("2011-09-06T10:00:00+02:00");
$end = new DateTime("2011-09-06T10:01:00+02:00");
echo $start->diff($end)->format('%H:%I:%S');
which would output 00:01:00

How to format datetime most easily in PHP?

To change 2009-12-09 13:32:15 to 09/12/2009
here:
echo date("d/m/Y", strtotime('2009-12-09 13:32:15'))
You can use strtotime to get the timestamp of the first date, and date to convert it to a string using the format you want.
$timestamp = strtotime('2009-12-09 13:32:15');
echo date('d/m/Y', $timestamp);
And you'll get :
09/12/2009
[edit 2012-05-19] Note that strtotime() suffers a couple of possibly important limitations:
The format of the date must be YYYY-MM-DD; it might work in some other cases, but not always !
Also, working with UNIX Timestamps, as done with date() and strtotime() means you'll only be able to work with dates between 1970 and 2038 (possibly a wider range, depending on your system -- but not and illimited one anyway)
Working with the DateTime class is often a far better alternative:
You can use either DateTime::__construct() or DateTime::createFromFormat() to create a DateTime object -- the second one is only available with PHP >= 5.3, but allows you to specify the date's format, which can prove useful,
And you can use the DateTime::format() method to convert that object to any date format you might want to work with.
Using the date() method.
print date("d/m/Y", strtotime("2009-12-09 13:32:15"));
$long_date = '2009-12-09 13:32:15';
$epoch_date = strtotime($long_date);
$short_date = date('m/d/Y', $epoch_date);
The above is not the shortest way of doing it, but having the long date as an epoch timestamp ensures that you can reuse the original long date to get other date format outputs, like if you wanted to go back and have just the time somewhere else.

Categories