查找日期/时间字符串是否包含时区信息

3
我有一个存储为字符串的日期/时间信息表格。由于规划不当,一些字符串中包含时区信息(例如,“2014-01-13 04:22 -8”),而其他字符串则没有(例如,“2014-01-13 04:22”)。无论哪种类型的字符串都可以与strtotime()或new DateTime()配合使用,但是一旦这样做,有关是否存在时区的信息就会丢失——没有时区的字符串将被分配服务器的默认时区。是否有函数可用于查找字符串是否包含时区标识符?
似乎编写正则表达式很容易解决此问题,但经验告诉我,日期格式具有足够的变化和奇怪的特殊情况,因此尽可能使用内置函数总是更好的选择。
2个回答

2

一个类似于正则表达式的:

$str = "2014-01-13 04:22 -8"
$has_timezone = preg_match(/[-+][0-9]{1,2}$/, $str);

寻找字符串末尾跟随着 1 或 2 个数字的加号 + 或减号 -

如果您的输入还包含:

2004-10-10

-10 将被识别为时区,因此建议添加[空格]检测:

$has_timezone = preg_match(/\s[-+][0-9]{1,2}$/, $str);

如果您的时间戳字符串始终如下:

YYYY-mm-dd HH:ii[ timezone]

如果只是简单的 strlen 检查就足够了。16 = 无时区,17+ = 有时区。


就像我说的那样,我不太愿意手动解析日期,但我必须承认你的最后一个解决方案听起来非常可靠。 - octern

1
一旦您创建了DateTime对象,就不一定会丢失有关日期/时间字符串中是否存在时区的信息。如果在DateTime对象上执行var_dump(),则会得到如下输出:-
object(DateTime)[1]
  public 'date' => string '2014-01-13 04:22:00' (length=19)
  public 'timezone_type' => int 1
  public 'timezone' => string '-08:00' (length=6)

如您所见,时区类型和传递的时区值都在那里,只需要将它们取出即可。

在您的情况下,我认为您只需要知道日期/时间字符串中是否传递了 TZ 字符串。如果有,则时区类型将为 1;如果没有,则默认系统时区将被使用,并且将是类型 3。

您无法直接获取时区类型,但以下函数将为您获取它,然后您可以相应地采取行动。

function getTZType(\DateTime $date)
{
    ob_start();
    var_export($date);
    $dateString = ob_get_clean();
    preg_match('%=>.\d%', $dateString, $matches);
    return (int)explode(' ', $matches[0])[1];
}

$date = new \DateTime('2014-01-13 04:22 -8');
echo getTZType($date);

该函数返回一个整数1、2或3,对应于我在这里中解释的时区类型。 看它工作
该方法将允许您避免在日期/时间字符串上使用正则表达式,使用的正则表达式是在已知和可靠格式的字符串上使用的。

谢谢!对于未来的读者,我想澄清一下,这种情况下无法适用于时区格式可能会变化的情况。例如,“2014-01-13 04:22:00 America/Los_Angeles”是一个有效的日期时间字符串,并将转换为timezone_type = 3的对象。这与我的默认时区相同,因此我无法将它们区分开来。但是,我的时区字符串具有不同于默认时区的一致类型,因此这对我有效。 - octern

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接