Php 将字符串格式化为适当的UTC偏移量

Php 将字符串格式化为适当的UTC偏移量,php,regex,utc,Php,Regex,Utc,我有这样的字符串: -4:00 3:15 +8:30 我需要将其格式化为UTC偏移值,如: -0400 +0315 +0815 如何将示例字符串转换为最终字符串?我知道它可能使用了str\u replace和sprintf的组合,但我无法计算出来 谢谢 要支持的输入格式的一组正则表达式替换可能是可读性和可维护性最强的。要支持的输入格式的一组正则表达式替换可能是可读性和可维护性最强的。首先,检查输入字符串是否匹配。如果有,则从结果中删除整个匹配字符串,如果只有两部分,则前导符号丢失。在这种情况

我有这样的字符串:

-4:00
3:15
+8:30
我需要将其格式化为UTC偏移值,如:

-0400
+0315
+0815
如何将示例字符串转换为最终字符串?我知道它可能使用了
str\u replace
sprintf
的组合,但我无法计算出来


谢谢

要支持的输入格式的一组正则表达式替换可能是可读性和可维护性最强的。

要支持的输入格式的一组正则表达式替换可能是可读性和可维护性最强的。

首先,检查输入字符串是否匹配。如果有,则从结果中删除整个匹配字符串,如果只有两部分,则前导符号丢失。在这种情况下,在开头加一个加号,并将小时的长度填充为2。最后将该数组转换为字符串

foreach (array('-1:50','1:50','+1:50','-12:00','12:00','+12:00') as $input) {
  echo $input . ': ';

  if (preg_match('/^([-+])?([1-9][0-9]?):([0-9]{2})$/DX', $input, $asMatch) === 1) {
    unset($asMatch[0]);
    if ($asMatch[1] === '') {
      array_unshift($asMatch, '+');
    }
    $asMatch[2] = str_pad($asMatch[2], 2, '0', STR_PAD_LEFT);
    echo implode('', $asMatch);
  }

  echo "\n";
}

首先,检查输入字符串是否匹配。如果有,则从结果中删除整个匹配字符串,如果只有两部分,则前导符号丢失。在这种情况下,在开头加一个加号,并将小时的长度填充为2。最后将该数组转换为字符串

foreach (array('-1:50','1:50','+1:50','-12:00','12:00','+12:00') as $input) {
  echo $input . ': ';

  if (preg_match('/^([-+])?([1-9][0-9]?):([0-9]{2})$/DX', $input, $asMatch) === 1) {
    unset($asMatch[0]);
    if ($asMatch[1] === '') {
      array_unshift($asMatch, '+');
    }
    $asMatch[2] = str_pad($asMatch[2], 2, '0', STR_PAD_LEFT);
    echo implode('', $asMatch);
  }

  echo "\n";
}

分为三个步骤:

$offset = preg_replace('/:/','',$offset);
$offset = preg_replace('/\b(?=\d{3}$)/', '0', $offset);
$offset = preg_replace('/^(?=\d)/m', '+', $offset);

如果一次只传递一个偏移量,则可以删除第二个正则表达式上的
m
标志。

分三步操作:

$offset = preg_replace('/:/','',$offset);
$offset = preg_replace('/\b(?=\d{3}$)/', '0', $offset);
$offset = preg_replace('/^(?=\d)/m', '+', $offset);

如果一次只传递一个偏移量,可以删除第二个正则表达式上的
m
标志。

对我来说,这看起来像是一个非常简单的重新格式化():


0
被视为正数(
+
+0000
)。

这看起来像是一个非常简单的重新格式化():



0
被视为正数(
+
+0000
中所述)。

我仍然没有关闭正则表达式。你知道我会怎么做吗?@Henning Makholm:我会首先选择
sscanf
作为输入格式。它也是一种正则表达式,但没有那么复杂。我仍然没有关闭正则表达式。你知道我会怎么做吗?@Henning Makholm:我会首先选择
sscanf
作为输入格式。它也是一种正则表达式,但没有那么复杂。谢谢,但这不起作用<代码>-12:00变为
=-1200
。事实上,所有负值都会拾取一个
=
符号。所有正值都保留
,并且没有前导零。@Sardine我更新了我的答案并添加了6个测试用例。它们现在都可以工作了。简单取决于视图:如果输入已经被验证为有效,那么您的解决方案非常好。如果不是,那么您将得到一个结果,但它不是预期的结果,并且代码无法标记它。关键在于您对(用户)输入的信任程度。@Shi:检查sscanf的返回值没有问题。顺便说一句,您的代码不会进行错误检查,它将返回一个空字符串,而不是一个错误。只是说,应该进行错误检查,这是对的。谢谢,但这不起作用<代码>-12:00变为
=-1200
。事实上,所有负值都会拾取一个
=
符号。所有正值都保留
,并且没有前导零。@Sardine我更新了我的答案并添加了6个测试用例。它们现在都可以工作了。简单取决于视图:如果输入已经被验证为有效,那么您的解决方案非常好。如果不是,那么您将得到一个结果,但它不是预期的结果,并且代码无法标记它。关键在于您对(用户)输入的信任程度。@Shi:检查sscanf的返回值没有问题。顺便说一句,您的代码不会进行错误检查,它将返回一个空字符串,而不是一个错误。只是说,你是对的,应该进行错误检查。这非常接近。像
-10:30
这样的值不会丢失
。另外,在最初的问题中忽略了这一点,有些值没有
。例如,有些值类似于
-9
。我如何才能让它们拾取前导和尾随的0?谢谢你!我想我已经解决了这两个问题,但我没有进行测试。我要回家了,但如果这不起作用,我会在晚些时候检查。这很接近。像
-10:30
这样的值不会丢失
。另外,在最初的问题中忽略了这一点,有些值没有
。例如,有些值类似于
-9
。我如何才能让它们拾取前导和尾随的0?谢谢你!我想我已经解决了这两个问题,但我没有进行测试。正在回家,但如果这不起作用,我将稍后进行检查。如果您仍在寻找一个简单的解决方案:
$offset=vsprintf('%+03d:%02d',sscanf('offset',%d:%d')-。如果您仍在寻找一个简单的解决方案:
$offset=vsprintf('%+03d:%02d',sscanf($offset,%d:%d')-.+1为简单起见,不使用
preg\u replace
。细微的挑剔:输出中应该省略冒号。@fireeyedboy:由于格式字符串,输出很容易更改;)-现在更正,添加了一些更多的价值观,以及演示。+1我喜欢它是多么简单。但如果已正确指定偏移,则会中断。为简单起见,请尝试使用-900.+1,不要使用
preg\u replace
。细微的挑剔:输出中应该省略冒号。@fireeyedboy:由于格式字符串,输出很容易更改;)-现在更正,添加了一些更多的价值观,以及演示。+1我喜欢它是多么简单。但如果已正确指定偏移,则会中断。试试-900。