0

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

F j, Y

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

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

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

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

由于不知道用户如何设置她/他的日期,我有一个我不能简单地说的问题F = month, j = day, Y = yearphpdate()函数允许的一切,在系统中都是允许的。

问题:我怎样才能“匹配”那些?是否有一些我监督过的本机功能,它告诉我某事是否是月/日/年/小时/...?

编辑:最大。我可以使用的 PHP 版本是 PHP 5.2.1

4

4 回答 4

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')
);
于 2012-09-29T15:13:28.007 回答
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',
));

注意:从DateTime5.2.0 开始可用

于 2012-09-29T15:13:02.067 回答
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 等效于 PHP 5.2(或更低版本)

还要注意,因为这是 wordpress,所以可能会翻译月份名称。

而且我很确定您也可以以时间戳格式获取帖子的日期。对于插件而言,仅根据帖子 ID 获取该值而不是解析某些字符串可能会更轻松。

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

看起来 Wordpress 仍然没有给出关于 PHP 版本的警告,它们以某种方式停止使用浏览器和他们自己的软件;)没有必要模仿这种糟糕的做法。告诉您的用户他们处于危险之中并把他们吓跑(或者做闪亮的弹出气泡以一种不那么具有威胁性的方式传达信息。为您的用户提供善意的服务,那么双方都会有所收获双方,做一些优雅的后备来展示你的好态度)。

另请参阅:是否有与 PHP 5.3 不兼容的 Wordpress 版本?

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

于 2012-09-30T18:32:45.480 回答
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

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

于 2012-09-29T15:14:09.627 回答