Why is this time difference when I use "IntlDateFormatter"?
<?php
// php v7.1
$pattern = 'yyyy-MM-dd HH:mm:ss';
$timezone = "Europe/Budapest";
$inputDateTimeStr = '1890-01-01 00:00:00';
$locale = 'hu_HU';
$intlDateFormatter = new \IntlDateFormatter( $locale, \IntlDateFormatter::MEDIUM, \IntlDateFormatter::SHORT, \IntlTimeZone::createTimeZone($timezone), \IntlDateFormatter::GREGORIAN, $pattern
);
$dateTime = new \DateTime($inputDateTimeStr);
$dateTime->setTimezone(new \DateTimeZone($timezone));
$outputDateTimeStr = $intlDateFormatter->format($dateTime->getTimestamp());
print ' in: ' . $inputDateTimeStr
. ' out: ' . $outputDateTimeStr // string(19) "1890-01-01 00:16:20"
. ' diff: ' . ( strtotime($outputDateTimeStr) - strtotime($inputDateTimeStr) ) . ' seconds';
Output: in: 1890-01-01 00:00:00 out: 1890-01-01 00:16:20 diff: 980 seconds
I think, the intlDateFormatter and DateTime are before 1890 not compatible.
The Middle European Time (MET) was introduced step for step in Europe after 1890.
At the beginning of 1890 each place had its own time, depending on its longitude.
The following code shows this for 4 examples.
$refDate = date_create('1890-01-01 UTC');
$ts = $refDate->getTimeStamp();
$pattern = 'yyyy-MM-dd HH:mm:ss';
$timezones = [
"Europe/Paris", //2.3522° E
"Europe/Berlin", //13.4050° E
"Europe/Prague", //14.4378° E
"Europe/Budapest"//19.0402° E
];
$locale = 'hu_HU';
foreach($timezones as $timezone){
$intlDateFormatter = new \IntlDateFormatter(
$locale,
\IntlDateFormatter::MEDIUM,
\IntlDateFormatter::SHORT,
\IntlTimeZone::createTimeZone($timezone),
\IntlDateFormatter::GREGORIAN,
$pattern
);
$outputDateTimeStr = $intlDateFormatter->format($ts);
echo $timezone.": ".$outputDateTimeStr."<br>";
}
Output
Europe/Paris: 1890-01-01 00:09:21
Europe/Berlin: 1890-01-01 00:53:28
Europe/Prague: 1890-01-01 00:57:44
Europe/Budapest: 1890-01-01 01:16:20
DateTime delivers other results.
Related
how to create date using string date and user language
function createDate(string $date , string $culture)
{
Carbon::setLocale( $culture);
$datetime = Carbon::create($datetime );
return $date ->isoformat('L');
}
if current user in english work well
but if current user in french not working
$datetime='12/20/2022 10:20:20 '; $culture ="en" // en format MM/DD/YYYY =====\> OK
$datetime='20/12/2022 10:20:20 '; $culture ="Fr" // Fr format DD/MM/YYYY ======\>Exception
You can simply set a format for each input type (language) in an array and then use Carbon::createFromFormat.
function createFromInput(string $input, string $lang){
$inputFormat = ['en' => 'm/d/Y H:i:s', 'fr' => 'd/m/Y H:i:s', 'de' => 'd.m.Y H:i:s'];
return Carbon::createFromFormat($inputFormat[$lang],$input);
}
Examples for using the function:
$lang = 'en';
$input = '12/20/2022 10:20:20';
echo createFromInput($input, $lang);
//2022-12-20 10:20:20
$lang = 'fr';
$input = '20/12/2022 10:20:20';
echo createFromInput($input, $lang);
//2022-12-20 10:20:20
Variant for DateTime:
function createFromInput(string $input, string $lang){
$inputFormat = ['en' => 'm/d/Y H:i:s', 'fr' => 'd/m/Y H:i:s', 'de' => 'd.m.Y H:i:s'];
return DateTime::createFromFormat($inputFormat[$lang],$input);
}
$lang = 'en';
$input = '12/20/2022 10:20:20';
echo createFromInput($input, $lang)->format('Y-m-d H:i:s');
//2022-12-20 10:20:20
$lang = 'fr';
$input = '20/12/2022 10:20:20';
echo createFromInput($input, $lang)->format('Y-m-d H:i:s');
//2022-12-20 10:20:20
To try on https://3v4l.org/Q3hoA
Can anyone suggest an easy method to convert date and time to different timezones in php?
You can use the datetime object or their function aliases for this:
Example (abridged from PHP Manual)
date_default_timezone_set('Europe/London');
$datetime = new DateTime('2008-08-03 12:35:23');
echo $datetime->format('Y-m-d H:i:s') . "\n";
$la_time = new DateTimeZone('America/Los_Angeles');
$datetime->setTimezone($la_time);
echo $datetime->format('Y-m-d H:i:s');
Edit regarding comments
but i cannt use this method because i need to show date in different time zones as the user login from different locations
That's not a problem. When a user logs in, you determine his timezone and set it to your DateTime object just like shown. I'm using a similar approach in one of my projects and it works like a charm.
in the database i need to get the dates in any single timezone, then only it can be processed properly
You store the time either as a timestamp or a datetime in one timezone. When you query a DateTime field, you either convert the time in a DateTime object to this timezone or - if your db supports it - query with the selected timezone.
An even simpler method looks like this:
date_default_timezone_set('Europe/London'); // your user's timezone
$my_datetime='2013-10-23 15:47:10';
echo date('Y-m-d H:i:s',strtotime("$my_datetime UTC"));
As described in the PHP manual, strtotime() accepts a timezone too, you just have to append it to your datetime.
I recommend you to store all your datetimes in UTC because that way you won't have problems with the daylight savings.
This worked for me and it's pretty clean too!
function convert_to_user_date($date, $format = 'n/j/Y g:i A', $userTimeZone = 'America/Los_Angeles', $serverTimeZone = 'UTC')
{
try {
$dateTime = new DateTime ($date, new DateTimeZone($serverTimeZone));
$dateTime->setTimezone(new DateTimeZone($userTimeZone));
return $dateTime->format($format);
} catch (Exception $e) {
return '';
}
}
function convert_to_server_date($date, $format = 'n/j/Y g:i A', $userTimeZone = 'America/Los_Angeles', $serverTimeZone = 'UTC')
{
try {
$dateTime = new DateTime ($date, new DateTimeZone($userTimeZone));
$dateTime->setTimezone(new DateTimeZone($serverTimeZone));
return $dateTime->format($format);
} catch (Exception $e) {
return '';
}
}
//example usage
$serverDate = $userDate = '2014-09-04 22:37:22';
echo convert_to_user_date($serverDate);
echo convert_to_server_date($userDate);
None of these answers worked for me (I skipped trying code that was overly bulky in size). I also think it's weird to change the default timezone just for a single conversion.
Here is my solution:
function changeTimeZone($dateString, $timeZoneSource = null, $timeZoneTarget = null)
{
if (empty($timeZoneSource)) {
$timeZoneSource = date_default_timezone_get();
}
if (empty($timeZoneTarget)) {
$timeZoneTarget = date_default_timezone_get();
}
$dt = new DateTime($dateString, new DateTimeZone($timeZoneSource));
$dt->setTimezone(new DateTimeZone($timeZoneTarget));
return $dt->format("Y-m-d H:i:s");
}
So, to convert to the server default, you would just pass one timezone:
changeTimeZone("2016-10-24 16:28", "Asia/Tokyo");
To convert from the server default to the user, you would leave the 2nd parameter null or blank:
changeTimeZone("2016-10-24 16:28", "", "Asia/Tokyo");
And to switch between 2 timezones unrelated to the default, you would provide 2 timezones:
changeTimeZone("2016-10-24 16:28", "America/New_York", "Asia/Tokyo");
UTC to local:
<?php
$datetime = date("Y-m-d H:i:s");
$utc = new DateTime($datetime, new DateTimeZone('UTC'));
$utc->setTimezone(new DateTimeZone('America/Sao_Paulo'));
echo $utc->format('Y-m-d H:i:s');
?>
DateTime::setTimezone -- date_timezone_set — Sets the time zone for the DateTime object
Object oriented style
<?php
$date = new DateTime('2000-01-01', new DateTimeZone('Pacific/Nauru'));
echo $date->format('Y-m-d H:i:sP') . "\n";
$date->setTimezone(new DateTimeZone('Pacific/Chatham'));
echo $date->format('Y-m-d H:i:sP') . "\n";
?>
Procedural style
<?php
$date = date_create('2000-01-01', timezone_open('Pacific/Nauru'));
echo date_format($date, 'Y-m-d H:i:sP') . "\n";
date_timezone_set($date, timezone_open('Pacific/Chatham'));
echo date_format($date, 'Y-m-d H:i:sP') . "\n";
?>
The above examples will output:
2000-01-01 00:00:00+12:00
2000-01-01 01:45:00+13:45
// Convert date from one zone to another..
/*
$zone_from='Asia/Kolkata';
$zone_to='America/Phoenix';
date_default_timezone_set($zone_from);
$convert_date="2016-02-26 10:35:00";
echo $finalDate=zone_conversion_date($convert_date, $zone_from, $zone_to);
*/
function zone_conversion_date($time, $cur_zone, $req_zone)
{
date_default_timezone_set("GMT");
$gmt = date("Y-m-d H:i:s");
date_default_timezone_set($cur_zone);
$local = date("Y-m-d H:i:s");
date_default_timezone_set($req_zone);
$required = date("Y-m-d H:i:s");
/* return $required; */
$diff1 = (strtotime($gmt) - strtotime($local));
$diff2 = (strtotime($required) - strtotime($gmt));
$date = new DateTime($time);
$date->modify("+$diff1 seconds");
$date->modify("+$diff2 seconds");
return $timestamp = $date->format("Y-m-d H:i:s");
}
<?php
$time='6:02';
$dt = new DateTime($time, new DateTimeZone('America/New_York'));
//echo $dt->format('Y-m-d H:i:s') . PHP_EOL;
$dt->setTimezone(new DateTimeZone('Asia/Kolkata'));
echo $dt->format('H:i') . PHP_EOL;
?>
Try this:
function convertDate($dt, $timeZone) {
$UTC = new DateTimeZone("UTC");
$date= date('Y-m-d H:i:s', strtotime($dt));
$dateConv = new DateTime( $dt, $UTC );
$dateFormat ='m/d/Y h:i A';
$date->setTimezone(new DateTimeZone($timeZone));
return $date->format($dateFormat);
}
I need a function to convert a date in the Persian calendar to its counterpart Gregorian date. I wrote the below function following Example #3 of this page. Unfortunately, it does not work. What is the reason and what is the correct method to do that using the Intl extension?
function convert($time, $fromCalendar = 'gregorian', $toCalender = 'persian', $fromFormat = 'yyyy-MM-dd HH:mm:ss',
$toFormat = 'yyyy-MM-dd HH:mm:ss', $timezone = null, $local = 'fa_IR')
{
$formatter = IntlDateFormatter::create($local . '#calendar:' . $fromCalendar, null, null, $timezone, null, $fromFormat);
$formatter->setCalendar(IntlCalendar::createInstance(null, $local . '#calendar:' . $toCalender));
$output = $formatter->format($formatter->parse($time));
if ($output) return $output;
return $formatter->getErrorMessage();
}
A good introduction to Intl can be found here: http://devzone.zend.com/1500/internationalization-in-php-53/
I used https://github.com/salarmehr/cosmopolitan to convert from Gregorian to other calendars. The question is converting from other calendars to Gregorian.
This seems promising: http://www.phpclasses.org/package/4852-PHP-Convert-and-format-dates-of-the-Persian-calendar.html
Then you would just do:
$persian=new persian_date();
echo $persian->date('y-m-d H:i:s');
The following code convert a date of a gregorian calendar (western calendar) to a date of foreign calendar and the it will convert the date of a foreign calendar backt to a date of a gregorian calendar.
The conversion with the chinese calender show to be buggy.
<?php
// detect the allowed calendars
$bundle = new ResourceBundle('', 'ICUDATA');
$cnames = [];
$calendars = $bundle->get('calendar');
foreach ($calendars as $n => $v) {
$cnames[] = $n;
}
echo('allowed calendars'); // https://stackoverflow.com/questions/32540529/get-list-of-calendars-timezones-locales-in-php-icu-intldateformatter
echo print_r($cnames, true);
echo("\n\n");
// test the calendars
foreach ([
'buddhist',
'chinese', // chinese calendar has a bug
'coptic',
'dangi',
'default',
'ethiopic',
'ethiopic-amete-alem',
'gregorian',
'hebrew',
'indian',
'islamic',
'islamic-civil',
'japanese',
'persian',
'roc',
'funktioniertnicht',
] as $calendar) {
echo($calendar . "\n");
$intlDateFormatterFromGregorian = new IntlDateFormatter(
'de_DE#calendar=gregorian',
IntlDateFormatter::MEDIUM, //date format
IntlDateFormatter::SHORT, //time format
'Europe/Berlin',
IntlDateFormatter::TRADITIONAL
);
$timeStamp = $intlDateFormatterFromGregorian->parse('13 Sep 2022 13:46');
$intlDateFormatterToForeignCalender = IntlDateFormatter::create("de_DE#calendar=" . $calendar,
IntlDateFormatter::MEDIUM,
IntlDateFormatter::SHORT,
'Europe/Berlin',
IntlDateFormatter::TRADITIONAL);
$foreignDateDefaultFormat = $intlDateFormatterToForeignCalender->format($timeStamp);
echo($foreignDateDefaultFormat . "\n");
// Formatierung nach ICU-Regeln
$intlDateFormatterToForeignCalender->setPattern('MM-dd-YYYY GG HH:mm:ss');
$specialDateFormat = $intlDateFormatterToForeignCalender->format($timeStamp);
echo($specialDateFormat . "\n");
$intlDateFormatterFromForeignCalendar = new IntlDateFormatter(
'de_DE#calendar=' . $calendar,
IntlDateFormatter::MEDIUM,//date format
IntlDateFormatter::SHORT, //time format
'Europe/Berlin',
IntlDateFormatter::TRADITIONAL
);
$timeStamp = $intlDateFormatterFromForeignCalendar->parse($foreignDateDefaultFormat);
echo('tstamp: ' . $timeStamp . "\n");
$intlaDateFormatterToGregorianCalendar = IntlDateFormatter::create("de_DE#calendar=gregorian",
IntlDateFormatter::MEDIUM,
IntlDateFormatter::SHORT,
'Europe/Berlin',
IntlDateFormatter::GREGORIAN
);
$defaultGregorianDateFormat = $intlaDateFormatterToGregorianCalendar->format($timeStamp);
echo('This should be `09/13/22 13:46`' . "\n" . $defaultGregorianDateFormat . "\n\n");
}
Here's the scenario
I would like to know if a date like '2011-03-04' and time like '17:06:00' in a specific TimeZones like 'IST/PDT/CDT' is elapsed by using php?
Is there any function available to check this
$strDate = '2011-03-04 17:06:00';
$TZ = 'IST';
$strDate = '2011-02-01 11:16:30';
$TZ = 'CDT';
$strDate = '2010-08-04 07:20:00';
$TZ = 'IST';
$strDate = '2011-02-27 09:55:00';
$TZ = 'PST';
I've tried/searched all over the net but no joy, please help
Yeah i tried it using DateTime but it doesnt work for me.. My server is in IST TimeZone
$date = new DateTime('2011-03-04 17:06:00');
$date->setTimeZone(new DateTimeZone("PST"));
$newtime = $date->getTimestamp();
$time = time();
if ($time > $usertime)
echo 'time passed';
else
echo 'time NOT passed';
Thanks to tobyS but it too falied
$elapsedTime = new DateTime(
'2011-03-04 17:00:00', // I set it to 5PM. Now the time is 5:45 PM here in INDIA
new DateTimeZone( 'IST' )
);
$elapsedInt = $elapsedTime->diff( new DateTime() );
echo ( $elapsedInt->invert ? 'Future' : 'Past' ) . "\n";
You can create a DateTime object from your time data and use its diff() method against the current time.
Example code:
<?php
$elapsedTime = new DateTime(
'2010-08-04 07:20:00',
new DateTimeZone( 'IST' )
);
$notElapsedTime = new DateTime(
'2012-08-04 07:20:00',
new DateTimeZone( 'IST' )
);
$elapsedInt = $elapsedTime->diff( new DateTime() );
echo ( $elapsedInt->invert ? 'Future' : 'Past' ) . "\n";
$notElapsedInt = $notElapsedTime->diff( new DateTime() );
echo ( $notElapsedInt->invert ? 'Future' : 'Past' ) . "\n";
?>
PHP doesn't understand those timezones:
$timezone = 'America/New_York';
$date = new DateTime($strDate, new DateTimeZone($timezone));
Can anyone suggest an easy method to convert date and time to different timezones in php?
You can use the datetime object or their function aliases for this:
Example (abridged from PHP Manual)
date_default_timezone_set('Europe/London');
$datetime = new DateTime('2008-08-03 12:35:23');
echo $datetime->format('Y-m-d H:i:s') . "\n";
$la_time = new DateTimeZone('America/Los_Angeles');
$datetime->setTimezone($la_time);
echo $datetime->format('Y-m-d H:i:s');
Edit regarding comments
but i cannt use this method because i need to show date in different time zones as the user login from different locations
That's not a problem. When a user logs in, you determine his timezone and set it to your DateTime object just like shown. I'm using a similar approach in one of my projects and it works like a charm.
in the database i need to get the dates in any single timezone, then only it can be processed properly
You store the time either as a timestamp or a datetime in one timezone. When you query a DateTime field, you either convert the time in a DateTime object to this timezone or - if your db supports it - query with the selected timezone.
An even simpler method looks like this:
date_default_timezone_set('Europe/London'); // your user's timezone
$my_datetime='2013-10-23 15:47:10';
echo date('Y-m-d H:i:s',strtotime("$my_datetime UTC"));
As described in the PHP manual, strtotime() accepts a timezone too, you just have to append it to your datetime.
I recommend you to store all your datetimes in UTC because that way you won't have problems with the daylight savings.
This worked for me and it's pretty clean too!
function convert_to_user_date($date, $format = 'n/j/Y g:i A', $userTimeZone = 'America/Los_Angeles', $serverTimeZone = 'UTC')
{
try {
$dateTime = new DateTime ($date, new DateTimeZone($serverTimeZone));
$dateTime->setTimezone(new DateTimeZone($userTimeZone));
return $dateTime->format($format);
} catch (Exception $e) {
return '';
}
}
function convert_to_server_date($date, $format = 'n/j/Y g:i A', $userTimeZone = 'America/Los_Angeles', $serverTimeZone = 'UTC')
{
try {
$dateTime = new DateTime ($date, new DateTimeZone($userTimeZone));
$dateTime->setTimezone(new DateTimeZone($serverTimeZone));
return $dateTime->format($format);
} catch (Exception $e) {
return '';
}
}
//example usage
$serverDate = $userDate = '2014-09-04 22:37:22';
echo convert_to_user_date($serverDate);
echo convert_to_server_date($userDate);
None of these answers worked for me (I skipped trying code that was overly bulky in size). I also think it's weird to change the default timezone just for a single conversion.
Here is my solution:
function changeTimeZone($dateString, $timeZoneSource = null, $timeZoneTarget = null)
{
if (empty($timeZoneSource)) {
$timeZoneSource = date_default_timezone_get();
}
if (empty($timeZoneTarget)) {
$timeZoneTarget = date_default_timezone_get();
}
$dt = new DateTime($dateString, new DateTimeZone($timeZoneSource));
$dt->setTimezone(new DateTimeZone($timeZoneTarget));
return $dt->format("Y-m-d H:i:s");
}
So, to convert to the server default, you would just pass one timezone:
changeTimeZone("2016-10-24 16:28", "Asia/Tokyo");
To convert from the server default to the user, you would leave the 2nd parameter null or blank:
changeTimeZone("2016-10-24 16:28", "", "Asia/Tokyo");
And to switch between 2 timezones unrelated to the default, you would provide 2 timezones:
changeTimeZone("2016-10-24 16:28", "America/New_York", "Asia/Tokyo");
UTC to local:
<?php
$datetime = date("Y-m-d H:i:s");
$utc = new DateTime($datetime, new DateTimeZone('UTC'));
$utc->setTimezone(new DateTimeZone('America/Sao_Paulo'));
echo $utc->format('Y-m-d H:i:s');
?>
DateTime::setTimezone -- date_timezone_set — Sets the time zone for the DateTime object
Object oriented style
<?php
$date = new DateTime('2000-01-01', new DateTimeZone('Pacific/Nauru'));
echo $date->format('Y-m-d H:i:sP') . "\n";
$date->setTimezone(new DateTimeZone('Pacific/Chatham'));
echo $date->format('Y-m-d H:i:sP') . "\n";
?>
Procedural style
<?php
$date = date_create('2000-01-01', timezone_open('Pacific/Nauru'));
echo date_format($date, 'Y-m-d H:i:sP') . "\n";
date_timezone_set($date, timezone_open('Pacific/Chatham'));
echo date_format($date, 'Y-m-d H:i:sP') . "\n";
?>
The above examples will output:
2000-01-01 00:00:00+12:00
2000-01-01 01:45:00+13:45
// Convert date from one zone to another..
/*
$zone_from='Asia/Kolkata';
$zone_to='America/Phoenix';
date_default_timezone_set($zone_from);
$convert_date="2016-02-26 10:35:00";
echo $finalDate=zone_conversion_date($convert_date, $zone_from, $zone_to);
*/
function zone_conversion_date($time, $cur_zone, $req_zone)
{
date_default_timezone_set("GMT");
$gmt = date("Y-m-d H:i:s");
date_default_timezone_set($cur_zone);
$local = date("Y-m-d H:i:s");
date_default_timezone_set($req_zone);
$required = date("Y-m-d H:i:s");
/* return $required; */
$diff1 = (strtotime($gmt) - strtotime($local));
$diff2 = (strtotime($required) - strtotime($gmt));
$date = new DateTime($time);
$date->modify("+$diff1 seconds");
$date->modify("+$diff2 seconds");
return $timestamp = $date->format("Y-m-d H:i:s");
}
<?php
$time='6:02';
$dt = new DateTime($time, new DateTimeZone('America/New_York'));
//echo $dt->format('Y-m-d H:i:s') . PHP_EOL;
$dt->setTimezone(new DateTimeZone('Asia/Kolkata'));
echo $dt->format('H:i') . PHP_EOL;
?>
Try this:
function convertDate($dt, $timeZone) {
$UTC = new DateTimeZone("UTC");
$date= date('Y-m-d H:i:s', strtotime($dt));
$dateConv = new DateTime( $dt, $UTC );
$dateFormat ='m/d/Y h:i A';
$date->setTimezone(new DateTimeZone($timeZone));
return $date->format($dateFormat);
}