从 PHP 中的字符串中识别日期格式

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

我正在尝试更新数据库中的所有日期字段,为所有表中的每个日期添加 5 天。

我设法将日期和行 ID 拉入数组,然后生成 SQL 代码语句来更新它们。但是,每个表都有不同的日期格式,有些包含时间,有些不包含时间。我想在日期上添加 5 天,然后将其保存回来。目前,如果所有日期都具有相同的格式,我可以这样做,但这还不足以解决我的问题。

我想要的是一个可以从日期字符串生成字符串格式的代码。例如:

日期字符串

2014-12-04
我希望代码表明该日期具有
Y-m-d
格式。如果日期字符串是
2017-04-03 11:11:48.653
我希望代码说这个日期格式是
Y-m-d h:i:s

php sql-server date
3个回答
6
投票

如果您不需要保留格式(即您可以在添加五天的同时更改数据库中的格式),则可以将字符串扔到

strtotime
。如果可能的话,它会尝试检测格式:

$timestamp = strtotime($string_with_unknown_format);

或者,您可以使用正则表达式检查不同的格式:

function extractDateTimeFormat($string) {
    if (preg_match('/^\d{4}-\d{2}-\d{2}$/', $string))
        return 'Y-m-d';

    if (preg_match('/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$/', $string))
        return 'Y-m-d H:i:s';

    if (preg_match('/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}\.\d{3}$/', $string))
        return 'Y-m-d H:i:s.v';

    if (preg_match('/^\d{2}\/\d{2}\/\d{4}$/', $string))
        return 'm/d/Y';

    if (preg_match('/^\d{2}\.\d{2}\.\d{4}$/', $string))
        return 'd.m.Y';
}

但是,这可能会让人厌烦,具体取决于您期望的格式数量。另一方面 - 能有多少个?

下一个替代方案是直接在字符串中用占位符替换数字 - 这会更灵活,但可能不太可预测。在这种情况下,行的顺序很重要。如果您需要添加 12 小时格式 (

AM
/
PM
),您需要在
H:i:s
行之前插入行,否则将无法工作。

function extractDateTimeFormat($string) {
    $string = preg_replace('/\b\d{4}-\d{2}-\d{2}\b/', 'Y-m-d');
    $string = preg_replace('/\b\d{2}\/\d{2}\/\d{4}\b/', 'm/d/Y');
    $string = preg_replace('/\b\d{2}\.\d{2}\.\d{4}\b/', 'd.m.Y');
    $string = preg_replace('/\b\d{2}:\d{2}\b:\d{2}\b/', 'H:i:s');
    $string = preg_replace('/\b\d{2}:\d{2}\b/', 'H:i');
    $string = preg_replace('/\.\d{3}\b/', '.v');

    if (preg_match('/\d/', $string) 
        return false;

    return $string;
}

这样,您将独立检测日期和时间格式,因此您不必考虑每种可能的组合。
您必须检查实时数据哪种方法效果更好。


5
投票

格式化日期并了解什么日期格式的最佳方法,解决方案适合那些正在以日期格式进行开发的人。我还添加了 ISO8601 日期格式

function date_extract_format( $d, $null = '' ) {
    // check Day -> (0[1-9]|[1-2][0-9]|3[0-1])
    // check Month -> (0[1-9]|1[0-2])
    // check Year -> [0-9]{4} or \d{4}
    $patterns = array(
        '/\b\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}.\d{3,8}Z\b/' => 'Y-m-d\TH:i:s.u\Z', // format DATE ISO 8601
        '/\b\d{4}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])\b/' => 'Y-m-d',
        '/\b\d{4}-(0[1-9]|[1-2][0-9]|3[0-1])-(0[1-9]|1[0-2])\b/' => 'Y-d-m',
        '/\b(0[1-9]|[1-2][0-9]|3[0-1])-(0[1-9]|1[0-2])-\d{4}\b/' => 'd-m-Y',
        '/\b(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])-\d{4}\b/' => 'm-d-Y',

        '/\b\d{4}\/(0[1-9]|[1-2][0-9]|3[0-1])\/(0[1-9]|1[0-2])\b/' => 'Y/d/m',
        '/\b\d{4}\/(0[1-9]|1[0-2])\/(0[1-9]|[1-2][0-9]|3[0-1])\b/' => 'Y/m/d',
        '/\b(0[1-9]|[1-2][0-9]|3[0-1])\/(0[1-9]|1[0-2])\/\d{4}\b/' => 'd/m/Y',
        '/\b(0[1-9]|1[0-2])\/(0[1-9]|[1-2][0-9]|3[0-1])\/\d{4}\b/' => 'm/d/Y',

        '/\b\d{4}\.(0[1-9]|1[0-2])\.(0[1-9]|[1-2][0-9]|3[0-1])\b/' => 'Y.m.d',
        '/\b\d{4}\.(0[1-9]|[1-2][0-9]|3[0-1])\.(0[1-9]|1[0-2])\b/' => 'Y.d.m',
        '/\b(0[1-9]|[1-2][0-9]|3[0-1])\.(0[1-9]|1[0-2])\.\d{4}\b/' => 'd.m.Y',
        '/\b(0[1-9]|1[0-2])\.(0[1-9]|[1-2][0-9]|3[0-1])\.\d{4}\b/' => 'm.d.Y',

        // for 24-hour | hours seconds
        '/\b(?:2[0-3]|[01][0-9]):[0-5][0-9](:[0-5][0-9])\.\d{3,6}\b/' => 'H:i:s.u',
        '/\b(?:2[0-3]|[01][0-9]):[0-5][0-9](:[0-5][0-9])\b/' => 'H:i:s',
        '/\b(?:2[0-3]|[01][0-9]):[0-5][0-9]\b/' => 'H:i',

        // for 12-hour | hours seconds
        '/\b(?:1[012]|0[0-9]):[0-5][0-9](:[0-5][0-9])\.\d{3,6}\b/' => 'h:i:s.u',
        '/\b(?:1[012]|0[0-9]):[0-5][0-9](:[0-5][0-9])\b/' => 'h:i:s',
        '/\b(?:1[012]|0[0-9]):[0-5][0-9]\b/' => 'h:i',

        '/\.\d{3}\b/' => '.v'
    );
    //$d = preg_replace('/\b\d{2}:\d{2}\b/', 'H:i',$d);
    $d = preg_replace( array_keys( $patterns ), array_values( $patterns ), $d );

    return preg_match( '/\d/', $d ) ? $null : $d;
}


function date_formating( $date, $format = 'd/m/Y H:i', $in_format = false, $f = '' ) {
    $isformat = date_extract_format( $date );
    $d = DateTime::createFromFormat( $isformat, $date );
    $format = $in_format ? $isformat : $format;
    if ( $format ) {
        if ( in_array( $format, [ 'Y-m-d\TH:i:s.u\Z', 'DATE_ISO8601', 'ISO8601' ] ) ) {
            $f = $d ? $d->format( 'Y-m-d\TH:i:s.' ) . substr( $d->format( 'u' ), 0, 3 ) . 'Z': '';
        } else {
            $f = $d ? $d->format( $format ) : '';
        }
    }
    return $f;
} // end function


function date_convert_format( $old = '' ) {
    $old = trim( $old );
    if ( preg_match( '/^[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])$/', $old ) ) { // MySQL-compatible YYYY-MM-DD format
        $new = $old;
    } elseif ( preg_match( '/^[0-9]{4}-(0[1-9]|[1-2][0-9]|3[0-1])-(0[1-9]|1[0-2])$/', $old ) ) { // DD-MM-YYYY format
        $new = substr( $old, 0, 4 ) . '-' . substr( $old, 5, 2 ) . '-' . substr( $old, 8, 2 );
    } elseif ( preg_match( '/^(0[1-9]|[1-2][0-9]|3[0-1])-(0[1-9]|1[0-2])-[0-9]{4}$/', $old ) ) { // DD-MM-YYYY format
        $new = substr( $old, 6, 4 ) . '-' . substr( $old, 3, 2 ) . '-' . substr( $old, 0, 2 );
    } elseif ( preg_match( '/^(0[1-9]|[1-2][0-9]|3[0-1])-(0[1-9]|1[0-2])-[0-9]{2}$/', $old ) ) { // DD-MM-YY format
        $new = substr( $old, 6, 4 ) . '-' . substr( $old, 3, 2 ) . '-20' . substr( $old, 0, 2 );
    } else { // Any other format. Set it as an empty date.
        $new = '0000-00-00';
    }
    return $new;
}

$date_1 = '13/05/2020 19:20:15.156457';
$date_2 = '25-05-2020 10:20';
$date_3 = '2020.05.20 10:20';
$date_4 = '2020.25.05 18:20';
$date_5 = '05/05/2020 12:20';
$date_6 = '05.05.2020 10:20';
$date_7 = '2020-20-05';
//-----------------------------
echo "1($date_1): " . date_formating( $date_1, false, true ) . PHP_EOL;
// echo-> isformat: d/m/Y H:i:s.u
// 1(13/05/2020 19:20:15): 2020-05-13 19:20
echo "2($date_2): " . date_formating( $date_2 ) . PHP_EOL;
// echo-> isformat: d-m-Y H:i
// 2(25-05-2020 10:20): 25/05/2020 10:20
echo "3($date_3): " . date_formating( $date_3 ) . PHP_EOL;
// echo-> isformat: Y.m.d H:i
// 3(2020.05.20 10:20): 20/05/2020 10:20
echo "4($date_4): " . date_formating( $date_4 ) . PHP_EOL;
// echo-> isformat: Y.d.m H:i
// 4(2020.25.05 18:20): 25/05/2020 18:20
echo "5($date_5): " . date_formating( $date_5 ) . PHP_EOL;
// echo-> isformat: d/m/Y H:i
// 5(05/05/2020 12:20): 05/05/2020 12:20
echo "6($date_6): " . date_formating( $date_6 ) . PHP_EOL;
// echo-> isformat: d.m.Y H:i
// 6(05.05.2020 10:20): 05/05/2020 10:20
echo "7($date_7): " . date_formating( $date_7, false, true ) . PHP_EOL;
// echo-> isformat: Y-d-m
// 7(2020-20-05): 2020-20-05
echo "Date ISO8601: = " . date_formating( $date_1, 'DATE_ISO8601' ) . PHP_EOL;
// echo-> isformat: d/m/Y H:i:s.u
// Date ISO8601: = 2020-05-13T19:20:15.156Z
echo "7($date_7): = " . date_convert_format( $date_7 );
// 7(2020-20-05): = 2020-20-05

0
投票

不是问题的直接答案,但这是 Clary 的修改代码,用于从文本中检测日期和时间,并且还检测不带年份的日期

function extract_dateTime($message, $returnFormat = 'Y-m-d H:i:s'){
$date_patterns = [
    // '/\b\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}.\d{3,8}Z\b/' => 'Y-m-d\TH:i:s.u\Z', // format DATE ISO 8601
    '/\b\d{4}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])\b/' => 'Y-m-d',
    '/\b\d{4}-(0[1-9]|[1-2][0-9]|3[0-1])-(0[1-9]|1[0-2])\b/' => 'Y-d-m',
    '/\b(0[1-9]|[1-2][0-9]|3[0-1])-(0[1-9]|1[0-2])-\d{4}\b/' => 'd-m-Y',
    '/\b(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])-\d{4}\b/' => 'm-d-Y',

    '/\b(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])\b/' => 'm-d',
    '/\b(0[1-9]|[1-2][0-9]|3[0-1])-(0[1-9]|1[0-2])\b/' => 'd-m',
    '/\b(0[1-9]|[1-2][0-9]|3[0-1])-(0[1-9]|1[0-2])\b/' => 'd-m',
    '/\b(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])\b/' => 'm-d',


    '/\b\d{4}\/(0[1-9]|[1-2][0-9]|3[0-1])\/(0[1-9]|1[0-2])\b/' => 'Y/d/m',
    '/\b\d{4}\/(0[1-9]|1[0-2])\/(0[1-9]|[1-2][0-9]|3[0-1])\b/' => 'Y/m/d',
    '/\b(0[1-9]|[1-2][0-9]|3[0-1])\/(0[1-9]|1[0-2])\/\d{4}\b/' => 'd/m/Y',
    '/\b(0[1-9]|1[0-2])\/(0[1-9]|[1-2][0-9]|3[0-1])\/\d{4}\b/' => 'm/d/Y',

    '/\b(0[1-9]|[1-2][0-9]|3[0-1])\/(0[1-9]|1[0-2])\b/' => 'd/m',
    '/\b(0[1-9]|1[0-2])\/(0[1-9]|[1-2][0-9]|3[0-1])\b/' => 'm/d',
    '/\b(0[1-9]|[1-2][0-9]|3[0-1])\/(0[1-9]|1[0-2])\b/' => 'd/m',
    '/\b(0[1-9]|1[0-2])\/(0[1-9]|[1-2][0-9]|3[0-1])\b/' => 'm/d',


    '/\b\d{4}\.(0[1-9]|1[0-2])\.(0[1-9]|[1-2][0-9]|3[0-1])\b/' => 'Y.m.d',
    '/\b\d{4}\.(0[1-9]|[1-2][0-9]|3[0-1])\.(0[1-9]|1[0-2])\b/' => 'Y.d.m',
    '/\b(0[1-9]|[1-2][0-9]|3[0-1])\.(0[1-9]|1[0-2])\.\d{4}\b/' => 'd.m.Y',
    '/\b(0[1-9]|1[0-2])\.(0[1-9]|[1-2][0-9]|3[0-1])\.\d{4}\b/' => 'm.d.Y',

    '/\b(0[1-9]|1[0-2])\.(0[1-9]|[1-2][0-9]|3[0-1])\b/' => 'm.d',
    '/\b(0[1-9]|[1-2][0-9]|3[0-1])\.(0[1-9]|1[0-2])\b/' => 'd.m',
    '/\b(0[1-9]|[1-2][0-9]|3[0-1])\.(0[1-9]|1[0-2])\b/' => 'd.m',
    '/\b(0[1-9]|1[0-2])\.(0[1-9]|[1-2][0-9]|3[0-1])\b/' => 'm.d',

];

$time_patterns = [
    // for 24-hour | hours seconds
    // '/\b(?:2[0-3]|[01][0-9]):[0-5][0-9](:[0-5][0-9])\.\d{3,6}\b/' => 'H:i:s.u',
    '/\b(?:2[0-3]|[01][0-9]):[0-5][0-9](:[0-5][0-9])\b/' => 'H:i:s',
    '/\b(?:2[0-3]|[01][0-9]):[0-5][0-9]\b/' => 'H:i',

    // for 12-hour | hours seconds
    // '/\b(?:1[012]|0[0-9]):[0-5][0-9](:[0-5][0-9])\.\d{3,6}\b/' => 'h:i:s.u',
    '/\b(?:1[012]|0[0-9]):[0-5][0-9](:[0-5][0-9])\b/' => 'h:i:s',
    '/\b(?:1[012]|0[0-9]):[0-5][0-9]\b/' => 'h:i',
];

$dateTimeStr = null;
$dateTimeFormat = null;

foreach($date_patterns as $date_pattern => $format){
    if(preg_match($date_pattern, $message, $matches)){
        $dateTimeFormat = $format;
        $dateTimeStr = $matches[0];
        break;
    }
}
if($dateTimeFormat) $dateTimeFormat .= ' ';
if($dateTimeStr) $dateTimeStr .= ' ';
foreach($time_patterns as $time_pattern => $format){
    if(preg_match($time_pattern, $message, $matches)){
        $dateTimeFormat .= $format;
        $dateTimeStr .= $matches[0];
        break;
    }
}

$d = DateTime::createFromFormat( $dateTimeFormat, $dateTimeStr );
return $d->format( $returnFormat );
}
© www.soinside.com 2019 - 2024. All rights reserved.