I've realised my DateTime function is not converting and returning false.
Example date/time as provided by Amazon. This is what I am trying to convert from:
2020-07-28T23:00:00Z
Function which accepts the date as provided by Amazon and tries to convert it.
protected function dateUtcToEuropeLondon($date)
{
try {
$dt = new DateTime($date, new DateTimeZone('UTC'));
$dt->setTimezone(new DateTimeZone('Europe/London'));
return $dt;
} catch (Exception $e) {
return false;
}
}
Full function.
// Detect if custom shipping date exists
$date = (isset($order_details->EarliestShipDate)) ? $order_details->EarliestShipDate : '';
// Set custom meta field so we can easily access it via WC_Order
if (!empty($date)) {
$date = $this->dateUtcToEuropeLondon(strtotime($date));
if ($date instanceof DateTime) {
update_post_meta($order_id, '_wpl_shipping_date', $date->format('Y-m-d\TH:i:s'));
}
}
For starters, I checked what value I got back from:
$date = $this->dateUtcToEuropeLondon(strtotime('2020-07-28T23:00:00Z'));
it was nothing: ''.
The problem is that you're trying to create a DateTime object using a UNIX timestamp (via strtotime) which is all numbers. What DateTime is expecting is the more 'human friendly' d/m/y style format - so you'll need to specify that what you're giving it is a 'unixtime' string, rather than a 'datetime' string -- subtle difference.
Try changing
$dt = new DateTime($date, new DateTimeZone('UTC'));
to
$dt = new DateTime('#'.$date, new DateTimeZone('UTC'));
Using an # at the start of the string will tell your DateTime object that you're sending in a unix timestamp. Once it's happy, it will then allow your function to determine the correct timezone from UTC to Europe/London (GMT/BST).
Related
When the client sends a string like:
2019-07-20T10:00+02:00
I want the API to store the datetime in a UTC DateTimeImmutable as:
2019-07-20T08:00
How can this be easily achieved?
new DateTimeImmutable('2019-07-20T10:00+02:00');
always stores it as 2019-07-20T10:00
You can change the timezone with the setTimezone method.
$dateTime = new DateTimeImmutable('2019-07-20T10:00+02:00');
echo $dateTime->format(DateTimeInterface::RFC3339_EXTENDED) . PHP_EOL;
// 2019-07-20T10:00:00.000+02:00
$dateTime = $dateTime->setTimezone(new DateTimeZone("UTC"));
echo $dateTime->format(DateTimeInterface::RFC3339_EXTENDED);
// 2019-07-20T08:00:00.000+00:00
My input is a timezone value (say "america/los_angeles"), and its output should be a timezone abbreviation(say "PST").
Input: "america/los_angeles"
Output: "PST"
Input: "Asia/Kolkata"
Output: "IST"
I know this can be done by mapping the timezone value to its corresponding abbreviation but it is time consuming.
So is there any PHP built-in function, though which I can achieve this?
Just use date('T') function to get the timezone. You'll need to set it though:
$input = 'america/los_angeles';
date_default_timezone_set($input);
echo date('T');
The reference is in the manual. T (capital) corresponds to Timezone abbreviation
Another variation would be to use DateTime classes:
$input = 'Asia/Kolkata';
$dt = new DateTime(null, new DateTimeZone($input));
echo $dt->format('T');
Edit: Take note, you'll also need to take into account if the input is correct or not, this throws an exception is its invalid.
You can just handle it via try/catch:
$input = 'Asia/Kolkata';
try {
$dt = new DateTime(null, new DateTimeZone($input));
echo $dt->format('T');
} catch(Exception $e) {
echo $e->getMessage();
}
From the php's documentation page:
$dateTime = new DateTime();
$dateTime->setTimeZone( new DateTimeZone( 'America/Los_Angeles' ) );
return $dateTime->format( 'T' );
Will return PST
I have an object, and in the constructor for said object I pass another object that is posted from an API. The relevant constructor code is:
$this->timeStamp = new \DateTime($location->timeStamp, new \DateTimeZone('UTC'));
if ($apiTime instanceof \DateTimeZone) {
$timeZone = $apiTime;
} else {
$timeZone = new \DateTimeZone('UTC');
}
$this->localTimeStamp = date_create($location->timeStamp, new \DateTimeZone('UTC'))->setTimeZone($timeZone);
$this->localTimeStampFake = $this->localTimeStamp;
$this->localTimeStampFormatted = date_create($this->localTimeStamp->format('Y-m-d H:i:s'), $timeZone)->format('m/d/Y g:iA T');
The $location object's timeStamp propery is formatted like so: "2013-10-28T16:30:55.000Z". Most of the time, the passed dates get formatted correctly in the end, something like: "11/12/2013 9:36AM CST". Occasionally, though, I get this: "11/18/2013 7:47PM +00:00"
In those cases, I can see that the timezone did not correctly get converted (we typically don't want UTC, and in the case of this constructor, we are always passing a new DateTimeZone instance and passing to that class "US/Central" or whatever timezone the user happens to be in). Any ideas as to what may be causing this behavior?
See note for the 2nd parameter of DateTime::__construct($time, $timezone) method:
The $timezone parameter and the current timezone are ignored when the $time parameter either is a UNIX timestamp (e.g. #946684800) or specifies a timezone (e.g. 2010-01-28T15:00:00+02:00).
That means, if you enter $time in format like yours: 2013-10-28T16:30:55.000Z, given timezone as 2nd parameter to DateTime constructor will be ignored. See examples where all given timezones are ignored, and timezone from input is used (Z = Zulu = UTC = +00:00).
$dt = new DateTime('2013-10-28T16:30:55.000Z', new DateTimezone('Africa/Dakar'));
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// this parameter is ignored
If you wish to change timezone for given DateTime object, you can use setTimezone() method, after you created the DateTime object (demo):
$dt = new DateTime('2013-10-28T16:30:55.000Z');
$dt->setTimezone(new DateTimezone('Africa/Dakar'));
Try something like this:
$this->timeStamp = new \DateTime($location->timeStamp);
$local = clone $this->timeStamp;
if ($apiTime instanceof \DateTimeZone) $local->setTimezone($apiTime);
$this->localTimeStamp = $local;
$this->localTimeStampFormatted = $local->format('m/d/Y g:iA T');
I had this construction error when trying to creating a new DateTime object using a timestamp:
Exception: DateTime::_construct(): Failed to parse time string (1372622987) at position 8 (8): Unexpected character in DateTime->_construct()
The object creation code is:
$start_date = new DateTime( "#{$dbResult->db_timestamp}" );
Where $dbResult->db_timestamp is a valid unix timestamp taken from a database. The timestamp in question was:
1372622987
I would understand this error for invalid formats being passed, but this is a genuine timestamp.
The reason this is very strange: I since ran a script to create a new DateTime object with the timestamp passed in as a hard coded value, and it reported no errors.
This seems to have been a one off, but I need an explanation if there is one, as I can't afford for this to happen again.
You should use setTimestamp instead, if you hardcode it:
$start_date = new DateTime();
$start_date->setTimestamp(1372622987);
in your case
$start_date = new DateTime();
$start_date->setTimestamp($dbResult->db_timestamp);
Use the createFromFormat method:
$start_date = DateTime::createFromFormat("U", $dbResult->db_timestamp);
UPDATE
I now recommend the use of Carbon
change your code to this
$start_date = new DateTime( "#" . $dbResult->db_timestamp );
and it will work fine
This worked for me.
/**
* return date in specific format, given a timestamp.
*
* #param timestamp $datetime
* #return string
*/
public static function showDateString($timestamp)
{
if ($timestamp !== NULL) {
$date = new DateTime();
$date->setTimestamp(intval($timestamp));
return $date->format("d-m-Y");
}
return '';
}
$start_date = new DateTime();
$start_date->setTimestamp($dbResult->db_timestamp);
I am creating a script that allows the user to choose their own timezone...
and enter the date $ time..So the user entered date/time must be converted to GMT format while storing into the database.
While retrieving from the database it should be again converted into original format.
Here DST concept must also be included.
So here date can be in a variable which can be a string or array(multidimensional array also)
So i tried like this.....
function ConvertOneTimezoneToAnotherTimezone($time,$currentTimezone,$timezoneRequired)
{
$current_zone = new DateTimeZone($currentTimezone);
//$gmt = new DateTimeZone('GMT');
$date = new DateTime($time, $current_zone);
//$date->setTimezone($gmt);
$date->setTimezone(new DateTimeZone($timezoneRequired));
return $date->format('Y-m-d H:i:s');
// Convert it back to Original timezone
$date->setTimezone($current_zone);
return $date->format('Y-m-d H:i:s');
}
$time='2011-03-29 11:15:00.000';
echo "Current Date/Time is=".ConvertOneTimezoneToAnotherTimezone($time,'Asia/Kolkata','America/New_York');
but here i am only able to convert into different timezones,but i want a single function which converts date/time and also while retrieving gives original format......
please anybody help me......
<?php
function ConvertOneTimezoneToAnotherTimezone($originalDateTime, $originalTimeZone, $targetTimeZone) {
$format = 'Y-m-d H:i:s';
$dateTime = new DateTime($originalDateTime, new DateTimeZone($originalTimeZone));
$original = $dateTime->format($format);
$dateTime->setTimezone(new DateTimeZone($targetTimeZone));
$target = $dateTime->format($format);
return compact('original', 'target');
}
$dateTime = '2011-03-29 11:15:00.000';
$converted = ConvertOneTimezoneToAnotherTimezone($dateTime,'Asia/Kolkata','America/New_York');
echo sprintf('Original Date/Time is=%s', $converted['original']), PHP_EOL;
echo sprintf('Converted Date/Time is=%s', $converted['target']), PHP_EOL;
something like this
http://service-kl.com/code/tz_demo2/?cou=USA