将日期/时间字符串分解为assoc数组

时间:2012-09-29 15:09:00

标签: php arrays date

我有一个从数据库选项返回的字符串,允许用户设置她/他的日期格式:

F j, Y

然后(今天)然后在我的get_date()函数中返回以下值:

string 'September 24, 2012' (length=18)

现在我需要一个拆分该字符串的关联数组:

array( 
    'day'   => 24,
    'month' => 'September',
    'year'  => 2012
)

由于不知道用户如何设定她/他的约会对象,我遇到的问题是我不能简单地说F = month, j = day, Y = year。系统允许php date() function允许的所有内容。

  

问题:如何“匹配”这些?是否有一些我已经监督过的本地功能,它会告诉我某些事情是一个月/日/年/小时/ ....

修改:最多我可以使用的PHP版本是PHP 5.2.1

4 个答案:

答案 0 :(得分:4)

如果你有PHP 5.3或更高版本,请使用DateTime::createFromFormat

$date = DateTime::createFromFormat($inputFormat, $gotDate);

$result = array(
    'day' => (int)$date->format('j'),
    'month' => $date->format('F'),
    'year' => (int)$date->format('Y')
);

答案 1 :(得分:1)

在我看来,你不应该首先将该字符串存储在数据库中,而是使用时间戳。

如果你这样做,你可以使用类似的东西:

$dateTime = new DateTime($theTimestamp);
$date = array(
    'day' => $dateTime->format('j'),
    'month' => $dateTime->format('F'),
    'year' => $dateTime->format('y'),
);

如果你想在数组中灵活选择你想要的东西,你可以创建一个像:

这样的函数
function buildDateArray($theTimestamp, $elements) {
    $dateTime = new DateTime($theTimestamp);
    $date = array();
    foreach($elements as $key => $format) {
        $date[$key] = $dateTime->format($format);
    }
}

$theArray = buildDateArray($theTimestamp, array(
    'day' => 'j',
    'month' => 'F',
    'year' => 'y',
));

注意:DateTime自5.2.0起可用

答案 2 :(得分:1)

正如您现在所写的那样,您手边没有PHP 5.3(真的很可惜),所以您需要“手动”解析字符串。在PCRE正则表达式旁边,还有sscanf。例如:

$date = 'September 24, 2012';
$result = sscanf($date, '%s %2d, %4d', $month, $day, $year);
$parsed = array(
    'day'   => $day,
    'month' => $month,
    'year'  => $year
);
var_dump($parsed);

输出:

array(3) {
  'day' =>
  int(24)
  'month' =>
  string(9) "September"
  'year' =>
  int(2012)
}

这将根据您的格式解析输入日期字符串。如果您需要更灵活,则需要动态构建模式,以及将值与结果数组相关联。

我编译了另一个执行此操作的示例。它可能有点脆弱(我添加了一些注释),但它确实有效。当然,我会把它包装成一个函数,更好地处理错误条件,但我保持代码原始,以便更好地显示它是如何工作的:

// input variables:
$date = 'September 24, 2012';
$format = 'F j, Y';

// define the formats:
$formats = array(
    'F' => array('%s',  'month'),  # A full textual representation of a month, such as January or March
    'j' => array('%2d', 'day'),    # Day of the month, 2 digits with or without leading zeros
    'Y' => array('%4d', 'year'),   # A full numeric representation of a year, 4 digits
    # NOTE: add more formats as you need them
);

// compile the pattern and order of values
$pattern = '';
$order = array();
for($l = strlen($format), $i = 0; $i < $l; $i++) {
    $c = $format[$i];

    // handle escape sequences
    if ($c === '\\') {
        $i++;
        $pattern .= ($i < $l) ? $format[$i] : $c;
        continue;
    }

    // handle formats or if not a format string, take over literally
    if (isset($formats[$c])) {
        $pattern .= $formats[$c][0];
        $order[] = $formats[$c][1];
    } else {
        $pattern .= $c;
    }
}

// scan the string based on pattern
// NOTE: This does not do any error checking
$values = sscanf($date, $pattern);

// combine with their names
// NOTE: duplicate array keys are possible, this is risky,
//       write your own logic this is for demonstration
$result = array_combine($order, $values);

// NOTE: you can then even check by type (string/int) and convert
//       month or day names into integers

var_dump($result);

这种情况下的结果是:

array(3) {
  'month' =>
  string(9) "September"
  'day' =>
  int(24)
  'year' =>
  int(2012)
}

照顾好笔记。在我编写之前,我已经检查了PHP手册中的用户注释,但是那里提供的功能仅用于解析一个特定模式,而这个变体应该在某种程度上是可扩展的。如果您只有这种格式,则可以自然地非动态地创建sscanf字符串。

另请参阅:date_create_from_format equivalent for PHP 5.2 (or lower)

另外请注意,因为这是wordpress,月份名称可能会被翻译。

而且我很确定你也能以时间戳格式获得帖子的日期。对于插件而言,根据帖子ID获取该值而不是解析某些字符串可能不那么繁琐。

最后一点:只有Wordpress拥有最低版本的PHP,并不意味着你的插件也需要最低版本。特别是在你概述的情况下,PHP 5.2不再获得任何支持(它已经死了),你可以帮助你的插件用户告诉他们应该更新他们的PHP版本。

似乎Wordpress仍然错过了关于PHP版本的警告,他们以某种方式停止浏览器和他们自己的软件;)没有必要模仿这种不好的做法。告诉你的用户他们处于危险之中并吓跑他们(或者做一些闪亮的弹出气泡来以一种不那么威胁的方式传达信息。让你的用户有良好的意图服务,那么两者都有所收获双方,做一些优雅的后备来表现你的良好态度。)

另请参阅:Is there a Wordpress version that is incompatible with PHP 5.3?

如果您有兴趣,可以在PHP.net上找到PHP的当前发布周期:https://wiki.php.net/rfc/releaseprocess

答案 3 :(得分:0)

已经在本机php DateTime类中找到答案的第一部分:只需使用date_parse( get_date() );自PHP 5.2起可用

// @example
'year' => int 2012
'month' => int 9
'day' => int 24
'hour' => boolean false
'minute' => boolean false
'second' => boolean false
'fraction' => boolean false
'warning_count' => int 0
'warnings' => 
   array
   empty
'error_count' => int 0
'errors' => 
   array
   empty
'is_localtime' => boolean false

这个答案仍然没有解决问题,我不知道如何将j映射到dayFmonth等等。