我有一个从数据库选项返回的字符串,允许用户设置她/他的日期格式:
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
答案 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
映射到day
,F
到month
等等。