php: setting a timezone by UTC offset

2019-01-06 14:35发布

Using javascript I know that my users timezone is UTC +3.

Now I want to create DateTime object with this knowledge:

$usersNow = new DateTime('now', new DateTimeZone("+3"));

I receive as a respsonse:

'Unknown or bad timezone (+2)'

What am I doing wrong? How can I fix?

10条回答
啃猪蹄的小仙女
2楼-- · 2019-01-06 15:02

This one takes Matthew's answer a step further to change the timezone of a date to any integer offset.

public static function applyHourOffset(DateTime $dateTime, int $hourOffset):DateTime
{
    $dateWithTimezone = clone $dateTime;

    $sign = $hourOffset < 0 ? '-' : '+';
    $timezone = new DateTimeZone($sign . abs($hourOffset));
    $dateWithTimezone->setTimezone($timezone);

    return $dateWithTimezone;
}

Note: I had a breakage in production due to the accepted answer.

查看更多
Animai°情兽
3楼-- · 2019-01-06 15:08

I was directed to a solution thanks to Joey Rivera's link. Like what the others have said here, timezone is not an offset you do need a valid timezone.

This is what I am using for myself

$singapore_time = new DateTime("now", new DateTimeZone('Asia/Singapore'));


var_dump( $singapore_time );

I myself have found it to be much more convenient to work with YYYY-MM-DD HH:MM format. example.

$original = new DateTime("2017-05-29 13:14", new DateTimeZone('Asia/Singapore'));
查看更多
看我几分像从前
4楼-- · 2019-01-06 15:09

Since PHP 5.5.10, DateTimeZone accepts an offset like "+3" :

https://3v4l.org/NUGSv

查看更多
神经病院院长
5楼-- · 2019-01-06 15:11

how about this...

$original = new DateTime("now", new DateTimeZone('UTC'));
$timezoneName = timezone_name_from_abbr("", 3*3600, false);
$modified = $original->setTimezone(new DateTimezone($timezoneName));
查看更多
Lonely孤独者°
6楼-- · 2019-01-06 15:11

You said:

Using javascript I know that my users timezone is UTC +3.

You probably ran something like this:

var offset = new Date().getTimezoneOffset();

This returns the current offset from UTC in minutes, with positive values falling west of UTC. It does not return a time zone!

A time zone is not an offset. A time zone has an offset. It can have multiple different offsets. Often there are two offsets, one for standard time and one for daylight saving time. A single numeric value cannot represent this alone.

  • Example of a time zone: "America/New_York"
    • Corresponding standard offset: UTC-5
    • Corresponding daylight offset: UTC-4

Besides the two offsets, also wrapped up in that time zone are the dates and times for transitioning between the two offsets so you know when they apply. There's also a historical record of how the offsets and transitions may have changed over time.

See also "Time Zone != Offset" in the timezone tag wiki.

In your example case, you probably received a value of -180 from javascript, representing a current offset of UTC+3. But that's just the offset for that particular point in time! If you follow minaz's answer, you will get a time zone that makes the assumption that UTC+3 is always the correct offset. That would work if the real time zone is something like "Africa/Nairobi" which has never used anything except UTC+3. But for all you know your user could be in "Europe/Istanbul", which uses UTC+3 in the summer and UTC+2 in the winter.

查看更多
甜甜的少女心
7楼-- · 2019-01-06 15:14

As far as I can tell from the docs on DateTimeZone, you need to pass a valid time zone and here are the valid ones. Check the others, something there may help you.

查看更多
登录 后发表回答