Yii2 timeZone conversion despite timeZone and defaultTimezone settings are the same


(Durino13) #1

Can somebody help me regarding the timeZone conversion in Yii2 please? This is my code:

Yii::$app->formatter->timeZone = 'America/Sao_Paulo';
Yii::$app->formatter->defaultTimeZone = 'America/Sao_Paulo';
$val = '2019-12-31 23:59:59';
$value = (new DateTime($val, new DateTimeZone('America/Sao_Paulo')));
var_dump(Yii::$app->formatter->timeZone);
var_dump(Yii::$app->formatter->defaultTimeZone);
var_dump($value);
var_dump(Yii::$app->formatter->asDatetime($value));

This web page states:

If no timezone conversion should be performed, you need to set $defaultTimeZone and $timeZone to the same value.

The output I get is this:

'America/Sao_Paulo' (length=17)
'America/Sao_Paulo' (length=17)
'America/Sao_Paulo' (length=17)
(DateTime)[303]
  public 'date' => string '2019-12-31 23:59:59.000000' (length=26)
  public 'timezone_type' => int 3
  public 'timezone' => string 'America/Sao_Paulo' (length=17)
'01.01.2020 00:59:59' (length=19)

As you can see, all my timezones are set to America/Sao_Paulo. Despite that, the date changes from 2019-12-31 23:59:59 to 01.01.2020 00:59:59. I would expect the result to be

31.12.2019 23:59:59

What am I doing wrong?


(Andro) #2

Hi,

you are passing the $value (which is a PHP DateTime object to the formater without specifing the format to be php. See https://www.yiiframework.com/doc/guide/2.0/en/output-formatting#date-and-time for details
Try

var_dump(Yii::$app->formatter->asDatetime($value, "php:d.m.y H:i:s"));

I suspect this to be the issue.

Besides this: Did you check, if your server/php time & date config part is correct?


(Durino13) #3

Hi Andro,

thank you for your time, however specifying the format ‘php:d.m.y H:i:s’ does not sovle the problem. Changing the timezone in the OS does not have affect either. As far as I remember, when I had the defaultTimezone and timeZone set to the same value, no conversion occurred in the past. For some reason, it doesn’t work now and I can’t figure out why.


(Andro) #4

And did you tried with a set format without the “php:” prefix?
What is the timezone you defined in your application config? Or did you set it specifically in the formatter?


(Durino13) #5

We set the timezone in the config and the formatter most likely inherits this settings, because I see, it has also the ‘Sao_Paulo’ timezone. I have pin pointed the problem and I can see, that the conversion is done by the IntlDateFormatter object:

Again, I would expect no time conversion, when the ‘defaultTimeZone’ and ‘timeZone’ settings in Yii2 are the same.


(Durino13) #6

This is my config:

    return [
    'timeZone' => 'America/Sao_Paulo',
    'components' => [
        'formatter' => [
            'dateFormat' => 'php:d/m/Y',
            'datetimeFormat' => 'php:d/m/Y H:i:s',
            'defaultTimeZone' => 'America/Sao_Paulo'
        ]
    ]
];

(Andro) #7

Maybe it’s a rounding error then, that comes from IntlDateFormatter if the float value at the seconds part gets processed?

Try to format the Datetime object to return the ‘date’ string without the .000000 part.


(Fredyr69) #8

I have this personal function adapted to my requirements, I hope it helps you
private function CompuraFechaHora($hora_actual)
{
// captura el la hora de internet
date_default_timezone_set(‘America/Caracas’);
setlocale(LC_TIME, ‘es_VE.UTF-8’);
$fecha_actual=strftime("%Y-%m-%d");
$hora_actual=strftime("%H:%M:%S");
// caso contrario que no la tenga la va tomar del servidor
$hoy = getdate();$hora= $hoy[‘hours’];$minutos= $hoy[‘minutes’];$segundos= $hoy[‘seconds’];
if ($hora_actual==’’){
$hora_actual = $hora;
}

    return $hora_actual;
        }

(Durino13) #9

It’s not a rounding problem. This seems to be a IntlDateFormatter problem:

https://3v4l.org/0IBPv

Different PHP versions produce different results. Maybe, this has something to do with the ICU version installed in the OS. My ICU version on my local computer is this:

marusiju@T470s ~/Workspace/ewb/plugins (master) $ php -i |grep -i icu
ICU version => 64.2
ICU Data version => 64.2
ICU TZData version => 2019a
ICU Unicode version => 12.1
libmongoc ICU => disabled
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

There’s a newer version of ICU available (65.1), but I don’t know, how to upgrade it properly. I was able to build the source code of this 65.1 version, but my php installation still uses the old one.