所以我有两个字符串:
$date_format = "yyyy-dd-mm";
$actual_date = "2014-05-12";
现在,它可以采用不同的格式(不同的分隔符,y,m,d的不同位置),例如:
$date_format = "yyyy/dd/mm";
$actual_date = "2014/05/12";
OR
$date_format = "dd|mm|yyyy";
$actual_date = "05|12|2014";
但是2种格式的字符串总是匹配。
分隔符也可能有所不同,但大部分都是 - 或/或\或| 。我只想比较yyyy,mm和dd,并将这些值中的任何内容分配给这些变量。
如何确保通过比较两个字符串来提取年份,月份和日期?
所以,我需要这样的东西:
$yyyy = 2014;
$mm = 12;
$dd = 5;
我想避免对年,月日期和分隔符的每种可能组合使用多个if条件。
答案 0 :(得分:1)
晚会到这里没有人; - /
<强> Working code at Viper-7 - PHP 5.3.18 强>
要求: 匹配有限数量的日期格式。检查它们是否有效并将它们转换为“标准”格式。
我们希望通过编辑“数据”来添加“新”日期格式,而不是以“if'son”控制语句的格式添加新的“代码”。
好的,让我们看看我们可以对所请求的,提供的“日期”格式应用哪些规则:
如果输入日期与每种格式的所有上述规则相匹配,那么我们可以相当确定它是有效的。
那么,如何在“数据”结构中表示那些可以轻松添加到新“格式”中的“规则”?使用'array:
示例:
$patterns = array(
"yyyy-dd-mm" => array('order' => array('yyyy', 'mm', 'dd'),
'sepchar' => '-',
'ranges' => array('yyyy' => array('minLength' => 4, 'maxLength' => 4, 'from' => 1900, 'to' => 3000),
'mm' => array('minLength' => 1, 'maxLength' => 2, 'from' => 1, 'to' => 12),
'dd' => array('minLength' => 1, 'maxLength' => 2, 'from' => 1, 'to' => 31)
),
),
);
现在,我们需要一些代码来使用数组'日期格式规则'条目并应用所有检查并返回我们可用于创建标准日期的信息。
完成工作的例程:
/**
* Try and match the input date against the pattern
*
* @param string $pattern
* @param array $rules
*
* @return array('match' => boolean,
* 'yyyy' => value,
* 'mm' => value,
* 'dd' => value,
* )
* so you can format for input into 'DateTime' object...
*/
function checkPattern($date, array $rules) {
$result = array('match' => false, 'yyyy' => '', 'dd' => '', 'mm' => '');
$sepCount = substr_count($date, $rules['sepchar']);
if ($sepCount !== 2) { // valid seperators
return $result;
}
$dateParts = explode($rules['sepchar'], $date);
// check the parts are in the correct order...
foreach($rules['order'] as $reqdPart) { // $reqdPart is the key into 'ranges'...
$datePart = current($dateParts);
// build result array with the input date parts
$result[$reqdPart] = $datePart; // assume input date is valid
// check individual parts agains the 'ranges' checks
$result['match'] = ( strlen($reqdPart) >= $rules['ranges'][$reqdPart]['minLength']
&& strlen($reqdPart) <= $rules['ranges'][$reqdPart]['maxLength'])
&& ( intval($datePart) >= $rules['ranges'][$reqdPart]['from']
&& intval($datePart) <= $rules['ranges'][$reqdPart]['to']);
next($dateParts);
if (!$result['match']) { // ok so far?
break;
}
}
// add any extra test here to try and validate the data...
return $result;
}
备注强>
使用$ pattern数组运行输入的代码。这是评论。
// process the input dates - report as matched and which pattern...
foreach($input as $date) {
reset($patterns); // use internal array iterator...
$result = array('match' => false); // stop the pattern matching if we find one
while (current($patterns) !== false && !$result['match']) {
$currentPattern = key($patterns); // save for use later
$result = checkPattern($date, current($patterns));
next($patterns); // next pattern to check
}
if ($result['match']) {
$dt = new DateTime($result['yyyy'] .'-'. $result['mm'] .'-'. $result['dd']);
echo '<br />Matched: ', $date, ' with format: ', $currentPattern,
'(', $dt->format("Y-m-d") ,')' ;
}
else {
echo '<br />Failed: ', $date;
}
}
示例输入:
$input = array("2014-05-12", "2014/05/12", "05|12|2014",
'12/never/2014', /* rubbish */
'1/1/2014', /* uk: dd/md/yyyy */
'7-20-2014', /* usa: mm-dd-yyyy */
'1/14/2014', /* uk: invalid dd/md/yyyy */
'14-20-2014' /* usa: invalid mm-dd-yyyy */
);
示例输出:
Matched: 2014-05-12 with format: yyyy-dd-mm(2014-05-12)
Matched: 2014/05/12 with format: yyyy/dd/mm(2014-05-12)
Matched: 05|12|2014 with format: dd|mm|yyyy(2014-12-05)
Failed: 12/never/2014
Matched: 1/1/2014 with format: dd/mm/yyyy(2014-01-01)
Matched: 7-20-2014 with format: mm-dd-yyyy(2014-07-20)
Failed: 1/14/2014
Failed: 14-20-2014
完整的'模式'数组:
$patterns = array(
"yyyy-dd-mm" => array('order' => array('yyyy', 'mm', 'dd'),
'sepchar' => '-',
'ranges' => array('yyyy' => array('minLength' => 4, 'maxLength' => 4, 'from' => 1900, 'to' => 3000),
'mm' => array('minLength' => 1, 'maxLength' => 2, 'from' => 1, 'to' => 12),
'dd' => array('minLength' => 1, 'maxLength' => 2, 'from' => 1, 'to' => 31)
),
),
"dd|mm|yyyy" => array('order' => array('dd', 'mm', 'yyyy'),
'sepchar' => '|',
'ranges' => array('yyyy' => array('minLength' => 4, 'maxLength' => 4, 'from' => 1900, 'to' => 3000),
'mm' => array('minLength' => 1, 'maxLength' => 2, 'from' => 1, 'to' => 12),
'dd' => array('minLength' => 1, 'maxLength' => 2, 'from' => 1, 'to' => 31)
),
),
"yyyy/dd/mm" => array('order' => array('yyyy', 'mm', 'dd'),
'sepchar' => '/',
'ranges' => array('yyyy' => array('minLength' => 4, 'maxLength' => 4, 'from' => 1900, 'to' => 3000),
'mm' => array('minLength' => 1, 'maxLength' => 2, 'from' => 1, 'to' => 12),
'dd' => array('minLength' => 1, 'maxLength' => 2, 'from' => 1, 'to' => 31)
),
),
// usa format
"mm-dd-yyyy" => array('order' => array('mm', 'dd', 'yyyy'),
'sepchar' => '-',
'ranges' => array('yyyy' => array('minLength' => 4, 'maxLength' => 4, 'from' => 1900, 'to' => 3000),
'mm' => array('minLength' => 1, 'maxLength' => 2, 'from' => 1, 'to' => 12),
'dd' => array('minLength' => 1, 'maxLength' => 2, 'from' => 1, 'to' => 31)
),
),
// uk format
"dd/mm/yyyy" => array('order' => array('dd', 'mm', 'yyyy'),
'sepchar' => '/',
'ranges' => array('yyyy' => array('minLength' => 4, 'maxLength' => 4, 'from' => 1900, 'to' => 3000),
'mm' => array('minLength' => 1, 'maxLength' => 2, 'from' => 1, 'to' => 12),
'dd' => array('minLength' => 1, 'maxLength' => 2, 'from' => 1, 'to' => 31)
),
),
);