PHP DateTime Manager基于语言环境

时间:2016-12-20 15:52:00

标签: php datetime internationalization timezone locale

我正在开展一个支持多个国家的项目,到目前为止是欧洲各国。

我将日期存储在所有国家/地区的UTC时区日期库中。 当我选择我想显示每个国家的相应时间。 例如,如果保存的日期时间是[2016-12-20 07:00:00] UTC

所以德国应该是2016-12-20 08:00:00 对于英国应该2016-12-20 07:00:00

所以不是检查它是哪个国家

usermod

我正在考虑创建一个DateTime Manager来管理设置TimeZone。

我想出了以下尝试

if($country === 'DE'){
   return (new DateTime($time))->setTimeZone(new DateTimeZone('Europe/Berlin'));
}else if ($country === 'UK'){
return (new DateTime($time))->setTimeZone(new DateTimeZone('Europe/London'));
}

但是当我尝试: var_dump(new DateTime()); //输出:

<?php

namespace App\Library\Values;

use App\Library\System\Locale;

final class DateTimeImmutableTimeZone extends \DateTimeImmutable
{
    /**
     * @var array
     */
    private $timezones = [
        'GB' => 'Europe/London',
        'DE' => 'Europe/Berlin',
        'FR' => 'Europe/Paris',
        'ES' => 'Europe/Madrid',
        'IT' => 'Europe/Rome',
        'SE' => 'Europe/Stockholm',
        'NL' => 'Europe/Amsterdam',
        'BE' => 'Europe/Brussels',
        'DK' => 'Europe/Copenhagen',
    ];

    /**
     * @param Locale $locale
     */
    public function __construct(Locale $locale)
    {
        $this->setTimezone(
            new \DateTimeZone($this->timezones[(string)$locale->country()])
        );
    }
}

var_dump(new DateTimeImmutableTimeZone(new Locale())); //输出:

DateTimeImmutable {#1673
  +"date": "2016-12-20 07:00:00"
  +"timezone_type": 3
  +"timezone": "UTC"
}

我不确定有什么问题? 另外我不确定这种写方法是否具有这样的TimeZone管理器类

2 个答案:

答案 0 :(得分:0)

如果您只想拥有一个根据国家/地区代码创建不同DateTime对象的类,请尝试此操作。

它是您的代码的修改版本,不使用package require类和immutable

Locale

现在var_dump的结果如下所示:

class DateTimeManager
{
    /**
     * @var array
     */
    private $timezones = [
        'GB' => 'Europe/London',
        'DE' => 'Europe/Berlin',
        'FR' => 'Europe/Paris',
        'ES' => 'Europe/Madrid',
        'IT' => 'Europe/Rome',
        'SE' => 'Europe/Stockholm',
        'NL' => 'Europe/Amsterdam',
        'BE' => 'Europe/Brussels',
        'DK' => 'Europe/Copenhagen',
    ];

    private $currentLocal;

    /**
     * @param string country
     */
    public function __construct($country)
    {
        if(!in_array($country, array_keys($this->timezones))){
            throw new InvalidArgumentException(sprintf("Country %s not found.", $country));
        }
        $this->currentLocal = $this->timezones[$country];
    }

    /**
     * Return a new DateTime object for the timestamp
     * @param $time
     *
     * @return \DateTime
     */
    public function getDateTime($time = null){
        return (new DateTime($time))->setTimezone(new DateTimeZone($this->currentLocal));
    }
}

对于你的第二个问题,这并不容易。取决于您对该类的确切要求以及使用它的上下文。

每次你需要这样的东西时,只用我的var_dump(new Datetime()); var_dump((new DateTimeManager("DE"))->getDateTime()); var_dump((new DateTimeManager("GB"))->getDateTime()); object(DateTime)#1 (3) { ["date"]=> string(26) "2016-12-20 17:42:03.860627" ["timezone_type"]=> int(3) ["timezone"]=> string(13) "Europe/Berlin" } object(DateTime)#2 (3) { ["date"]=> string(26) "2016-12-20 17:42:03.860854" ["timezone_type"]=> int(3) ["timezone"]=> string(13) "Europe/Berlin" } object(DateTime)#1 (3) { ["date"]=> string(26) "2016-12-20 16:42:03.861053" ["timezone_type"]=> int(3) ["timezone"]=> string(13) "Europe/London" } 函数写出一行就不好了。但是在更大的代码库中,它可以让您更轻松。

答案 1 :(得分:0)

我会解决你问题的这一部分:

  

...我不确定这种写方法是否具有此类TimeZone管理器类

不,这不是正确的做法。许多国家都有不止一个时区。您无法单独从国家/地区选择时区。示例:USRUAUBRMN许多其他。

即使在您提供的列表中,ES(西班牙)也有两个时区。 Europe/Madrid适用于大陆,Atlantic/Canary适用于加那利群岛。他们相隔一个小时。

此外,时区和区域设置是两个完全独立且不相关的主题。像en-US这样的语言环境意味着我希望将英语与美国(美国)方言和惯例一起使用。这并不意味着我位于美国。例如,我很可能正在日本旅行。