将 Windows 时区转换为 PHP 设置的等效时区

问题描述 投票:0回答:3

我正在开发一个由使用 PHP 和 MySQL 的 Web 服务器组成的应用程序,该服务器在 Windows 上运行,用户可以通过设置为

http://localhost
的 Web 浏览器访问该应用程序。但我希望它适用于美国所有时区,包括亚利桑那州大部分不遵守夏令时的地区。要配置此脚本,我需要使 PHP 使用与 Windows 相同的时区。

我有一个 PHP 脚本,可以从 Windows 上的命令行获取时区。然后需要将结果转换为 PHP 列表中的等效时区。

不幸的是,我没有看到一个简单的方法来做到这一点。这是脚本:


       $comp_timezone = exec('systeminfo | findstr  /C:"Time Zone"');
// results are: "Time Zone: (UTC-07:00) Arizona"
date_default_timezone_set($comp_timezone);
我需要做的是将
$comp_timezone
的字符串结果转换为函数
date_default_timezone_set
可以使用的内容,但如上面的示例所示,亚利桑那州不作为 php 的时区存在,最接近的时区是
America/Phoenix

那么如何将

systeminfo
时区转换为 PHP 时区?

php windows datetime timezone command-line-arguments
3个回答
5
投票

一些事情:

  1. systeminfo
    命令仅向您显示Windows时区的显示名称。您将需要标识符。您可以使用
    tzutil.exe /g
    返回此信息 - 尽管这仍然对您没有帮助。

  2. PHP 使用 IANA 时区,而不是 Windows 时区。有关两种不同类型时区的更多信息,请参阅时区标签 wiki

  3. 两者之间的转换由此文件中的CLDR处理。

  4. 对于 PHP,您可以通过 Internationalization Package 访问 CLDR 数据。通过添加(或取消注释)到您的

    php.ini
    文件来启用此功能:

    extension=php_intl.dll
    
  5. 然后您可以简单地调用以下函数来返回本地时区作为 IANA 标识符。 (在内部,它依赖于ICU和CLDR来翻译。)

    IntlTimeZone::createDefault()->getID()
    

    这将在您的示例中返回

    "America/Phoenix"
    。然后,您可以将它与任何 PHP 的正常时区函数一起使用,包括
    date_default_timezone_set
    (如果您愿意)。

  6. 即使您可以这样做,请仔细考虑一下您是否真的应该这样做。在大多数情况下,依赖 Web 应用程序(或任何服务器端应用程序)的系统本地时区设置是一种反模式。改变时区太容易了。这是一个全局设置,通常不需要任何管理员权限。如果您的数据不是基于 UTC,然后您尝试将其从一台服务器迁移到另一台服务器,也会出现问题。在绝大多数情况下,最好在应用程序逻辑级别考虑时区,而不是系统范围或应用程序范围,并且托管代码的服务器的时区通常应被视为不相关


0
投票

阅读马特解决方案:)


我的解决方案是循环

DateTimeZone::listIdentifiers()
并尝试找到匹配项,即:.

$comp_timezone = exec('systeminfo | findstr  /C:"Time Zone"');
//Time Zone: (UTC +01:00) Lisbon
//we match the last word of $comp_timezone
preg_match_all('/(\w+)$/', $comp_timezone, $rawTz, PREG_PATTERN_ORDER);
$rawTz = $rawTz[1][0]; //Lisbon

foreach (DateTimeZone::listIdentifiers() as $timezone) {
            if(preg_match("/.*?\/$rawTz/", $timezone)){
                echo $timezone;
                //Europe/Lisbon
            }
        }

现场演示


备注:

  1. America/Arizona
    DateTimeZone
    中不作为有效
    PHP
    存在。
  2. DateTimeZone
    仅适用于
    PHP 5 >= 5.2.0, PHP 7

0
投票

Windows 附带 自己的时区列表(例如:

W. Europe Standard Time
)。

PHP 使用 IANA 时区数据库(也称为 tz 数据库甚至 Olson 数据库)。

Unicode CLDR 提供 XML 文件,允许映射 IANA 名称和 Windows 名称。 例如,请参阅以下 XML 元素:

<!-- ... -->
<mapZone other="W. Europe Standard Time" territory="001" type="Europe/Berlin"/>
<mapZone other="W. Europe Standard Time" territory="AD" type="Europe/Andorra"/>
<!-- ... -->

如您所见,一个 Windows 时区名称可能对应多个 IANA 时区名称。

编写了一个脚本,它创建了代表两个常量的 PHP 代码,这两个常量允许相当轻松地解析名称,解析上面的 XML。

以下是此类常量的摘录:

const WINDOWS_TO_PHP = [
    // ...
    'W. Europe Standard Time' => ['Europe/Andorra', 'Europe/Berlin', /*... */],
    // ...
];

const PHP_TO_WINDOWS = [
    // ...
    'Europe/Andorra' => 'W. Europe Standard Time',
    'Europe/Berlin' => 'W. Europe Standard Time',
    // ...
];

通过使用这些常量,您只需编写即可检索 PHP 时区名称

$phpTimeZoneNames = WINDOWS_TO_PHP['W. Europe Standard Time'] ?? [];

并检索从 PHP 代码名称开始的 Windows 时区名称:

$windowsTimeZoneName = PHP_TO_WINDOWS['Europe/Andorra'] ?? '';
© www.soinside.com 2019 - 2024. All rights reserved.