分隔一长串日期和时间

Separate a long string of Dates and Times

我在 PHP 中有以下字符串:

$date_range_create_event = "Jan 12, 2019 08:00 PM - Feb 14, 2019 06:00 AM";

我想把它分成 4 个部分,然后能够将它们作为变量访问:

我想让这个动态化。我可以通过代码做些什么来自动分离它吗?

编辑:

这是我试图提取的开始日期:

$start_date = substr($date_range_create_event, 0, strpos($date_range_create_event, ' ', strpos($date_range_create_event, ' ')+1));

尝试array_map('date_parse', preg_split('~\s*-\s*~', $date_range_create_event));

这给出了一个类似于下面的数组。剩下的喊就很简单了。

array(2) {
  [0] =>
  array(12) {
    'year' =>
    int(2019)
    'month' =>
    int(1)
    'day' =>
    int(12)
    'hour' =>
    int(20)
    'minute' =>
    int(0)
    'second' =>
    int(0)
    'fraction' =>
    double(0)
    'warning_count' =>
    int(0)
    'warnings' =>
    array(0) {
    }
    'error_count' =>
    int(0)
    'errors' =>
    array(0) {
    }
    'is_localtime' =>
    bool(false)
  }
  [1] =>
  array(12) {
    'year' =>
    int(2019)
    'month' =>
    int(2)
    'day' =>
    int(14)
    'hour' =>
    int(6)
    'minute' =>
    int(0)
    'second' =>
    int(0)
    'fraction' =>
    double(0)
    'warning_count' =>
    int(0)
    'warnings' =>
    array(0) {
    }
    'error_count' =>
    int(0)
    'errors' =>
    array(0) {
    }
    'is_localtime' =>
    bool(false)
  }
}

我们可以尝试使用正则表达式拆分和匹配的组合:

$input = "Jan 12, 2019 08:00 PM - Feb 14, 2019 06:00 AM"; 
$parts = preg_split ("/\s+-\s+/", $input);
foreach($parts as $date) {
    if (preg_match("/([a-z]{3} \d{1,2}, \d{4}) (\d{2}:\d{2} (?:AM|PM))/i", $date, $results)) {
        echo "date: " . $results[1] . "\n";
        echo "time: " . $results[2] . "\n";
    }
}

date: Jan 12, 2019
time: 08:00 PM
date: Feb 14, 2019
time: 06:00 AM

一种不需要所有繁重的正则表达式的方法是以两种不同的方式使用爆炸。

首先我们在“-”上展开不同的 DateTime,然后我们循环并在 space 上展开。
我们知道日期有三个space因为有年月日
使用 array_splice 分解三项作为日期,然后剩下的就是时间。

$date_range_create_event = "Jan 12, 2019 08:00 PM - Feb 14, 2019 06:00 AM";

$dates = explode(" - ", $date_range_create_event);

foreach($dates as &$date){
    $temp = explode(" ", $date);
    $date = ["date" => implode(" ",array_splice($temp, 0,-2)), "time" => implode(" ", $temp)];
}
unset($date);

https://3v4l.org/K4qE7

您可以从字符串的每个拆分部分(在 - 周围)创建一个 DateTime 对象,然后输出您需要的 date/time 的任何部分,以任何形式结果对象所需的格式:

$date_range_create_event = "Jan 12, 2019 08:00 PM - Feb 14, 2019 06:00 AM";
list($start, $end) = array_map(function ($d) { return new DateTime($d); }, explode('-', $date_range_create_event));
echo "Start date = " . $start->format('M j, Y') . "\n";
echo "Start date = " . $start->format('Y-m-d') . "\n";
echo "Start time = " . $start->format('h:i A') . "\n";
echo "Start time = " . $start->format('H:i') . "\n";
echo "End date = " . $end->format('M j, Y') . "\n";
echo "End time = " . $end->format('h:i A') . "\n";

输出:

Start date = Jan 12, 2019 
Start date = 2019-01-12 
Start time = 08:00 PM 
Start time = 20:00 
End date = Feb 14, 2019 
End time = 06:00 AM

将输入解析为 DateTime 对象还有一些优点,例如可以轻松计算事件的持续时间:

$duration = $start->diff($end);
echo "Event is " . $duration->format('%h') . " hours and " . $duration->format('%i') . " minutes long\n";

输出:

Event is 10 hours and 0 minutes long

Demo on 3v4l.org

如果您只想将字符串拆分为四个部分,那么您可以在一个 preg_ 调用中完成此操作,以分解两个分隔符。

代码:(Demo)

$date_range_create_event = "Feb 13, 2019 03:00 PM - Mar 1, 2019 11:00 PM";

$parts = preg_split ("/ - | (?=\d\d:)/", $date_range_create_event);
var_export($parts);

输出:

array (
  0 => 'Feb 13, 2019',
  1 => '03:00 PM',
  2 => 'Mar 1, 2019',
  3 => '11:00 PM',
)

由此,您可以使用 list() 或 php7+ "array deconstruction" 将值赋给变量。

模式说,每次遇到就拆分:

  1. a space、连字符、space 或
  2. a space(后跟 2 小时数字,然后是冒号)使用 (?=...) 前瞻,这样时间子字符串就不会 "consumed" 作为定界的一部分进程中的子字符串。