Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/256.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/http/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
PHP解析时间与控制台?_Php - Fatal编程技术网

PHP解析时间与控制台?

PHP解析时间与控制台?,php,Php,当输入的格式不同(如下面的输出示例所示)时,如何以秒为单位计算时间输入 使用此格式,所有零件都是可选的: 5d 4h 3m 2s -> 5 days, 4 hours, 3 minutes and 2 seconds 4h 2s -> 4 hours and 2 seconds 3m -> 3 minutes 05: 04: 03: 02 -> 5 days, 4 hours, 3 minutes and 2 seconds 4:03:02 -> 4 hours,

当输入的格式不同(如下面的输出示例所示)时,如何以秒为单位计算时间输入

使用此格式,所有零件都是可选的:

5d 4h 3m 2s -> 5 days, 4 hours, 3 minutes and 2 seconds
4h 2s -> 4 hours and 2 seconds
3m -> 3 minutes
05: 04: 03: 02 -> 5 days, 4 hours, 3 minutes and 2 seconds
4:03:02 -> 4 hours, 3 minutes and 2 seconds
05: 00: 03: 02 -> 5 days, 3 minutes and 2 seconds
02 -> 2 seconds
使用此格式,零件有时是可选的:

5d 4h 3m 2s -> 5 days, 4 hours, 3 minutes and 2 seconds
4h 2s -> 4 hours and 2 seconds
3m -> 3 minutes
05: 04: 03: 02 -> 5 days, 4 hours, 3 minutes and 2 seconds
4:03:02 -> 4 hours, 3 minutes and 2 seconds
05: 00: 03: 02 -> 5 days, 3 minutes and 2 seconds
02 -> 2 seconds
我希望得到以下输出:

> php time.php 1d 6h 20m 2s
> 109.202 seconds
> php time.php 3:50
> 230 seconds
> php time.php 4: 23: 45: 02
> 431.102 seconds
> php time.php 23m
> 1.380 seconds
到目前为止,我已经能够将输入秒转换为时间格式,但在5个小时的努力后,我放弃了上述问题:


您可以使用
preg\u match\u all
将输入拆分为成对的数字和后缀,然后迭代这些数字和后缀以计算秒数:

function seconds($input) {
    preg_match_all("/(\d+)(\S)/", "$input:", $matches, PREG_SET_ORDER);
    $letters = "smhd";
    $durations = ["s" => 1, "m" => 60, "h" => 60*60, "d" => 60*60*24];
    $seconds = 0;
    foreach (array_reverse($matches) as list($all, $num, $code)) {
        $i = strpos($letters, $code);
        if ($i === false) $code = $letters[$i = 0];
        $letters = substr($letters, $i+1);
        $seconds += $durations[$code] * $num;
    }
    return $seconds;
}

function test($input) {
    $seconds = number_format(seconds($input));
    echo "$input => $seconds seconds\n";
}

test("1d 6h 20m 2s");  // 109.202 seconds
test("3:50");          // 230 seconds
test("4: 23: 45: 02"); // 431.102 seconds
test("23m");           // 1.380 seconds

以下内容可能有些过分,但也可能说明如果您希望代码可扩展且易于重用,如何解决此问题:

<?php
declare(strict_types=1);

error_reporting(-1);
ini_set('display_errors', 'On');

interface TimeStringParser
{
    public function accepts(string $input): bool;

    public function parse(string $input): int;
}

final class InputWithUnits implements TimeStringParser
{
    public function accepts(string $input): bool
    {
        foreach (preg_split('/\s+/', $input) as $chunk) {
            if (! preg_match('/^\d+(d|h|m|s)$/', $chunk)) {
                return false;
            }
        }

        return true;
    }

    public function parse(string $input): int
    {
        if (! $this->accepts($input)) {
            throw new \InvalidArgumentException('Invalid input.');
        }

        $result = 0;
        if (preg_match_all('/((?<value>\d+)(?<unit>d|h|m|s))/', $input, $matches)) {
            foreach ($matches['unit'] as $i => $unit) {
                $value = (int) $matches['value'][$i];
                switch ($unit) {
                    case 'd': $result += $value * 86400; break;
                    case 'h': $result += $value * 3600; break;
                    case 'm': $result += $value * 60; break;
                    case 's': $result += $value * 1; break;
                }
            }
        }

        return $result;
    }
}

final class InputWithoutUnits implements TimeStringParser
{
    public function accepts(string $input): bool
    {
        foreach (explode(':', $input) as $chunk) {
            if (! preg_match('/^\d+$/', trim($chunk))) {
                return false;
            }
        }

        return true;
    }

    public function parse(string $input): int
    {
        if (! $this->accepts($input)) {
            throw new \InvalidArgumentException('Invalid input.');
        }

        $multiplier = [1, 60, 3600, 86400];
        $result = 0;

        foreach (array_reverse(explode(':', $input)) as $chunk) {
            $value = (int) trim($chunk);
            $result += $value * array_shift($multiplier);
        }

        return $result;
    }
}

final class ParserComposite implements TimeStringParser
{
    private $parsers;

    public function __construct(TimeStringParser ...$parsers)
    {
        $this->parsers = $parsers;
    }

    public function accepts(string $input): bool
    {
        foreach ($this->parsers as $parser) {
            if ($parser->accepts($input)) {
                return true;
            }
        }

        return false;
    }

    public function parse(string $input): int
    {
        foreach ($this->parsers as $parser) {
            if ($parser->accepts($input)) {
                return $parser->parse($input);
            }
        }

        throw new \InvalidArgumentException('Invalid input.');
    }
}

$parser = new ParserComposite(
    new InputWithUnits(),
    new InputWithoutUnits()
);

$testCases = [
    '5d 4h 3m 2s',
    '4h 2s',
    '3m',
    '05: 04: 03: 02',
    '4:03:02',
    '05: 00: 03: 02',
    '02',
    '23m',
    '2e-5'
];

foreach ($testCases as $testCase) {
    if ($parser->accepts($testCase)) {
        printf("%-'.20s: %8d\n", $testCase, $parser->parse($testCase));
    }
    else {
        printf("%-'.20s: unsupported\n", $testCase);
    }
}

你开始编码了吗,还是你希望这里的人能帮你完成这一切?真不知道为什么有人认为这个问题值得投票表决?@RiggsFolly这个问题本身与现在大多数其他问题相比是一个有趣的问题。它只是没有显示出任何努力。我添加了一些代码。好的,你要做的第一件事是测试输入,看看使用了哪种格式,这样你就知道如何正确解读它的内容。谢谢你的这段代码。非常感谢您的努力,而且效果也很好。