php:通过UTC偏移量设置时区

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/7276304/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-26 02:23:01  来源:igfitidea点击:

php: setting a timezone by UTC offset

phpdatetimetimezone

提问by shealtiel

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

使用 javascript 我知道我的用户时区是 UTC +3。

Now I want to create DateTime object with this knowledge:

现在我想用这些知识创建 DateTime 对象:

$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?

我究竟做错了什么?我该如何解决?

回答by minaz

how about this...

这个怎么样...

$original = new DateTime("now", new DateTimeZone('UTC'));
$timezoneName = timezone_name_from_abbr("", 3*3600, false);
$modified = $original->setTimezone(new DateTimezone($timezoneName));

回答by Matt Johnson-Pint

You said:

你说:

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

使用 javascript 我知道我的用户时区是 UTC +3。

You probably ran something like this:

你可能运行了这样的东西:

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

This returns the currentoffset from UTC in minutes, with positive values falling west of UTC. It does notreturn a time zone!

这以分钟为单位返回与UTC的当前偏移量,正值落在 UTC 以西。它并没有返回时区!

A time zone is not an offset. A time zone hasan 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
  • 时区示例: "America/New_York"
    • 对应的标准偏移: UTC-5
    • 对应的日光偏移: 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.

另请参阅时区标记 wiki“时区 != 偏移量” 。

In your example case, you probably received a value of -180from javascript, representing a currentoffset 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 alwaysthe 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.

在您的示例中,您可能收到-180来自 javascript的值,表示UTC+3的当前偏移量。但这只是那个特定时间点的偏移量!如果您遵循minaz 的回答,您将得到一个时区,该时区假设 UTC+3始终是正确的偏移量。如果实时时区类似于"Africa/Nairobi"从未使用过除 UTC+3 之外的任何内容,那么这将起作用。但就您所知,您的用户可能在"Europe/Istanbul",夏季使用 UTC+3,冬季使用 UTC+2。

回答by Matthew

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

自 PHP 5.5.10 起, DateTimeZone 接受类似 "+3" 的偏移量:

https://3v4l.org/NUGSv

https://3v4l.org/NUGSv

回答by William Entriken

Modern answer:

现代答案:

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

Documentation:

文档:

http://php.net/manual/en/datetimezone.construct.php

http://php.net/manual/en/datetimezone.construct.php

回答by Grayda

For anyone who comes across this, I was facing the same problem, so in the end I extended the DateTime class and overrode the __construct()method to accept an offset (in minutes) instead of a timezone.

对于遇到此问题的任何人,我都面临着同样的问题,因此最后我扩展了 DateTime 类并覆盖了该__construct()方法以接受偏移量(以分钟为单位)而不是时区。

From there, my custom __construct()works out what the offset is in hours and minutes (e.g. -660 = +11:00) and then uses parent::__construct()to hand my date, custom formatted to include my offset, back to the original DateTime.

从那里,我的自定义计算__construct()出以小时和分钟为单位的偏移量(例如 -660 = +11:00),然后使用parent::__construct()我的日期,自定义格式以包括我的偏移量,返回到原始 DateTime。

Because I'm always dealing with UTC times in my application, my class also modifies the UTC time by subtracting the offset, so passing Midnight UTC and an offset of -660 will show me 11am

因为我总是在我的应用程序中处理 UTC 时间,我的班级还通过减去偏移量来修改 UTC 时间,因此传递午夜 UTC 和 -660 的偏移量将显示上午 11 点

My solution is detailed here: https://stackoverflow.com/a/35916440/2301484

我的解决方案在这里详细说明:https: //stackoverflow.com/a/35916440/2301484

回答by Joey Rivera

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

至于我可以在文档告诉DateTimeZone,你需要通过一个有效的时区,这里是有效的。检查其他人,那里的东西可能对你有帮助。

回答by zod

did you try this

你试过这个吗

http://php.net/manual/en/function.strtotime.php

http://php.net/manual/en/function.strtotime.php

 <?php
    echo strtotime("now"), "\n";
    echo strtotime("10 September 2000"), "\n";
     echo strtotime("+5 hours");
    echo strtotime("+1 day"), "\n";
    echo strtotime("+1 week"), "\n";
    echo strtotime("+1 week 2 days 4 hours 2 seconds"), "\n";
    echo strtotime("next Thursday"), "\n";
    echo strtotime("last Monday"), "\n";
    ?>

回答by zod

DateTimeZone requires a timezone not an offest

DateTimeZone 需要一个时区而不是一个时区

回答by Michael Clark

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.

注意:由于接受的答案,我的生产中断了。

回答by Bruce Tong

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.

感谢 Joey Rivera 的链接,我被引导到了一个解决方案。就像其他人在这里所说的那样,时区不是您需要有效时区的偏移量。

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.

我自己发现使用 YYYY-MM-DD HH:MM 格式要方便得多。例子。

$original = new DateTime("2017-05-29 13:14", new DateTimeZone('Asia/Singapore'));