Timezone inconsistency in momentjs and php - php

We are having problems to get the datetime representation in php and momentjs in sync. Lets say we are having a datetime with a time zone in Moscow:
2013-06-10T10:40:00.000+04:00
The user should see the time in local: 2013-06-10T10:40:00. No matter if he sits in Spain or USA. Following php code would produce the proper time that we need:
$date = new DateTime('2013-06-10T10:40:00.000+04:00');
echo $date->format('d.m.Y H:i:s');
The output is:
10.06.2013 10:40:00
But if we parse the same datetime string in frontend with momentjs:
moment('2013-06-10T10:40:00.000+04:00').format('D.M.YYYY h:mm:ss');
The output is:
10.6.2013 8:40:00
The browsers time zone is Europe/Berlin (+02:00). Using utc() calculates the date the wrong way also. What we need is a local time of the place, so in case of php it is the right one. Giving a parse string to momentjs:
moment('2013-06-10T10:40:00.000+04:00', "YYYY-MM-DD HH:mm").format('D.M.YYYY h:mm:ss')
would do the trick, so the time zone is deleted. But we actually should set the parse string globally, but how?
Thanks for suggestions.

I believe you are affected by moment.js issue 611 - which is actually a feature request, since JavaScript doesn't do this natively anyway. There is a somewhat acceptable workaround in the issue comments. Please add your own feedback there as well. Thanks.
UPDATE
With the release of moment.js version 2.1.0, you can now do this:
var input = "2013-06-10T10:40:00.000+04:00";
var m = moment(input).zone(input);
var s = m.format('D.M.YYYY h:mm:ss');
The extra call to .zone(input) will extract just the offset portion (+04:00) from the string and set it to the zone used for formatting. There are other options as well. See moment#zone in the docs.
UPDATE #2
With the release of moment.js version 2.3.0, this is now a single call:
var m = moment.parseZone(input);

Try setting the PHP timezone to Europe/Berlin
date_default_timezone_set("Europe/Berlin")
Might be your PHP installation/server is using a different timezone.

Related

Change the ISO 8601 date format using PHP

I am trying to get the current date/time using Data Type: ISODateTime and Format: YYYY-MM-DDTHH:MM:SS e.g. 2012-02-06T08:35:30. I searched how I would do this in PHP and found that I can use;
$formatedDate = date("c");
Although the output of this is almost correct is not quite what I need and I can't figure out how to alter it, the current output of this is;
2014-07-01T10:53:10+02:00
My problem is I need to remove the "+02:00" and also this time is an hour ahead of my local time, which is what I need. Therefore, in this example, I would require;
2014-07-01T09:53:10
Any help would be really appreciated. Thanks.
You could just format the date manually.
$formattedDate = date('Y-m-d\TH:i:s');
To get your local time, use date_default_timezone_set() to set the appropriate timezone (before declaring $formattedDate).
// Change 'America/New_York' to your timezone
date_default_timezone_set('America/New_York');
See demo
To find your timezone, see the List of Supported Timezones.

How to format an UTC date to use the Z (Zulu) zone designator in php?

I need to display and handle UTC dates in the following format:
2013-06-28T22:15:00Z
As this format is part of the ISO8601 standard I have no trouble creating DateTime objects from strings like the one above. However I can't find a clean way (meaning no string manipulations like substr and replace, etc.) to present my DateTime object in the desired format. I tried to tweak the server and php datetime settings, with little success. I always get:
$date->format(DateTime::ISO8601); // gives 2013-06-28T22:15:00+00:00
Is there any date format or configuration setting that will give me the desired string? Or I'll have to append the 'Z' manually to a custom time format?
No, there is no special constant for the desired format. I would use:
$date->format('Y-m-d\TH:i:s\Z');
But you will have to make sure that the times you are using are really UTC to avoid interpretation errors in your application.
If you are using Carbon then the method is:
echo $dt->toIso8601ZuluString();
// 2019-02-01T03:45:27Z
In PHP 8 the format character p was added:
$timestamp = new DateTimeImmutable('2013-06-28T22:15:00Z');
echo $timestamp->format('Y-m-d\TH:i:sp');
// 2013-06-28T22:15:00Z
In order to get the UTC date in the desired format, you can use something like this:
gmdate('Y-m-d\TH:i:s\Z', $date->format('U'));
To do this with the object-oriented style date object you need to first set the timezone to UTC, and then output the date:
function dateTo8601Zulu(\DateTimeInterface $date):string {
return (clone $date)
->setTimezone(new \DateTimeZone('UTC'))
->format('Y-m-d\TH:i:s\Z');
}
Edit: clone object before changing timezone.
Since PHP 7.2 DateTimeInterface::ATOM was introduced in favor of DateTimeInterface::ISO8601, although it still lives on for backward compatability reasons.
Usage
$dateTimeObject->format(DateTimeInterface::ATOM)

One timestamp with multiple formatting outputs

I want to display two dates/times on my page
the server one, taken from the MySQL Server
the client one, taken from JavaScript
Since the output wasn't right, I started digging through my code and found something weird: I formatted the same timestamp in both php and javascript (see the code below) and the results differed by 3 hours.
timestamp: 1369855189
PHP:
var_dump( date( 'H:i:s', $timestamp ) );
Output: "19:19:49"
JavaScript:
dts = new Date( timestamp * 1000 );
var hours_s = dts.getHours();
var minutes_s = dts.getMinutes();
var seconds_s = dts.getSeconds();
current_server_time = hours_s + ":" + minutes_s + ":" + seconds_s";
Output: "22:19:49"
Does anyone know why this is happening? Does anyone know a workaround?
You and your server are probably not on the same timezome.
Try with javascript:
var hours_s = dts.getUTCHours();
var minutes_s = dts.getUTCMinutes();
var seconds_s = dts.getUTCSeconds();
The timestamp will be UTC...but once you put it into a PHP date object, it will have the timezone of the server. Once you put it into JavaScript, it will have the computer's local timezone. To set the timezone of the server in PHP, you can use this (replacing the timezone with yours) and see if that fixes it for you:
date_default_timezone_set('America/Chicago')
Obviously, to change the timezone for JavaScript requires changing your computer's timezone.
Is the php being executed in a server different from the machine where the JavaScript is parsed?
Either way, there is a workaround if you can work with gmt time:
Use the gmdate in your PHP script.
Use dts.getUTCHours() (and similar functions for the rest, prefixing UTC) in your JS. Check the ECMAScript standard p. 174. for more details.
If you want to work with local time, review the locale configuration of both server and client machines.

Call to undefined method DateTime::setTimeStamp()

I've been using setTimeStamp to convert a Unix Timestamp to a datetime in the following way:
$startHireConverted = strtotime($startHire); // converts start hire to time
$endHireConverted = strtotime($endHire); // converts end hire to time
$startdt = new DateTime();
$startdt->setTimeStamp($startHireConverted);
$mysql_startdate = $startdt->format("Y-m-d H:i");
This was working nicely, but recently I've put the website live and the version of PHP can only be 5.2.12 which doesn't support the setTimeStamp method.
I've tried changing setTimeStamp to format which is getting rid of the errors and converting the datetime but it is changing it to the current datetime - 5 hours for some reason rather than the date stored in $startHire.
$startdt->format($startHireConverted);
Any ideas on how to get around this problem?
$startHire starts out as a string version of datetime.
Thankyou
I don't think you need to do the step with unix timestamp at all:
$startdt = new DateTime($startHire);
PHP manual: DateTime::__construct
But that might depend on the format you're getting $startHire in. See Supported Date and Time Formats.

Convert all dates in PHP to local time

The server my PHP script is running on is set to UTC. I can't seem to figure out a way to set all dates to the browser's timezone. All dates displayed are formatted using PHP's date() function.
I know that via JavaScript's getTimezoneOffset() function, I can get the browser's current UTC offset (-4, in my case). How can I tell PHP to use this offset? I can use date_default_timezone_set(), but how do I convert an offset, say -4, to a time zone string, say America/New_York?
Note: The server is running PHP 5.1.6 (with no DateTime class) and I am using CodeIgniter.
As per the comment above- you could use a cookie...:
Javascript:
var today = new Date();
function SetCookie(cookieName,cookieValue,nDays) {
var expire = new Date();
if (nDays==null || nDays==0) nDays=1;
expire.setTime(today.getTime() + 3600000*24*nDays);
document.cookie = cookieName+"="+escape(cookieValue)
+ ";expires="+expire.toGMTString();
}
SetCookie("datecookie", today, 30);
window.location.href=window.location.href
PHP:
echo date("m d Y", strtotime($_COOKIE['datecookie']));
Because Javascript is client based and PHP is server based, they will not communicate. To tell the server the browser time, you will need to send information from the client, perhaps via Ajax, posting the browser time. The target PHP script should then handle/output this as appropriate. One other (obtuse) option is to attempt to geolocate the user based on IP, then guesstimate the correct time for that location- however this is inefficient for this purpose.
"I know I can use date_default_timezone_set(), but how do I convert an offset, say -4, to a time zone string, say America/New_York?"
Simply look at the comments associated with the documentation for that function. Comment #99006 does the work for you. You just need to get the timezone offset from the user.

Categories