【问题标题】:PHP DateTime Manager based on locale基于语言环境的 PHP 日期时间管理器
【发布时间】:2016-12-20 15:51:59
【问题描述】:

我正在做一个支持多个国家的项目,目前是欧洲国家。

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

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

所以不要检查它是哪个国家/地区

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'));
}

等等

我正在考虑创建一个 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(新日期时间()); //输出:

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

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

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

我不知道出了什么问题? 此外,我不确定这是否是具有此类 TimeZone 管理器类的编写方法

【问题讨论】:

  • 据我从文档中可以看出,country() 类上没有函数 country()。这是(php.net/manual/de/class.locale.php)你正在使用的本地还是你自己写的?
  • @cb0 这是伪代码想象这个国家返回德国

标签: php datetime internationalization timezone locale


【解决方案1】:

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

这是您的代码的修改版本,不使用 immutable 类和 Locale

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 的结果如下所示:

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"
}

对于您的第二个问题,这并不容易。取决于你想对这个类做什么以及在什么上下文中使用它。

每次你需要这样的东西时,只写我的getDateTime函数中的那一行也不错。但是在更大的代码库中,它可以让你的事情变得更容易。

【讨论】:

  • 我的问题是如何摆脱 getDateTime()?我想用提供的语言环境获取日期时间,而不需要调用任何其他函数
【解决方案2】:

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

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

不,这不是正确的方法。许多国家有多个时区。您不能仅从国家/地区选择时区。示例:USRUAUBRMN 很多其他。

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

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

【讨论】:

    猜你喜欢
    • 2011-11-03
    • 2019-08-10
    • 1970-01-01
    • 2017-01-29
    • 1970-01-01
    • 1970-01-01
    • 2014-03-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多