ISO 8601の日付文字列をどのように検証しますか(例:2011-10-02T23:25:42Z)。
ISO 8601の日付にはいくつかの表現が考えられることは知っていますが、上記の例で示した形式の検証にのみ関心があります。
ありがとう!
これは私にとってはうまくいきました。正規表現を使用して日付が目的の形式であることを確認してから、日付を解析して再作成し、出力が入力と一致することを確認します。
<?php
$date = '2011-10-02T23:25:42Z';
var_dump(validateDate($date));
$date = '2011-17-17T23:25:42Z';
var_dump(validateDate($date));
function validateDate($date)
{
if (preg_match('/^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})Z$/', $date, $parts) == true) {
$time = gmmktime($parts[4], $parts[5], $parts[6], $parts[2], $parts[3], $parts[1]);
$input_time = strtotime($date);
if ($input_time === false) return false;
return $input_time == $time;
} else {
return false;
}
}
さらに展開して checkdate を使用し、月の日と年も有効であることを確認できます。
編集:最も簡単な方法は、文字列を使用してDateTime
オブジェクトを作成することです。
$dt = new DateTime($dateTimeString);
DateTime
コンストラクターが文字列を解析できない場合、例外がスローされます。
DateTime :: __construct():位置18で時間文字列(2011-10-02T23:25:72Z)の解析に失敗しました(2):予期しない文字
タイムゾーン指定子を省略した場合、設定されたデフォルトのタイムゾーンが使用されることに注意してください。
2番目に簡単な方法は、正規表現を使用することです。このようなものはそれをカバーするために
if (preg_match('/^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})(Z|(\+|-)\d{2}(:?\d{2})?)$/', $dateString, $parts)) {
// valid string format, can now check parts
$year = $parts[1];
$month = $parts[2];
$day = $parts[3];
// etc
}
軽量ソリューションを共有したいと思います。理想的ではありませんが、誰かに役立つかもしれません。
function validISO8601Date($value)
{
if (!is_string($value)) {
return false;
}
$dateTime = \DateTime::createFromFormat(\DateTime::ISO8601, $value);
if ($dateTime) {
return $dateTime->format(\DateTime::ISO8601) === $value;
}
return false;
}
注意!
一部の有効なISO8601日付は失敗します以下のリストを見てください
NOT VALID --> '' // Correct
NOT VALID --> 'string' // Correct
VALID --> '2000-01-01T01:00:00+1200' // This is the only format function returns as valid
NOT VALID --> '2015-01 first' // Correct
NOT VALID --> '2000-01-01T01:00:00Z' // Must be valid!
NOT VALID --> '2000-01-01T01:00:00+01' // Must be valid!
http://www.pelagodesign.com/blog/2009/05/20/iso-8601-date-validation-that-doesnt-suck/ を参照してください。これにより、この正規表現を使用できるようになります。
^([\+-]?\d{4}(?!\d{2}\b))((-?)((0[1-9]|1[0-2])(\3([12]\d|0[1-9]|3[01]))?|W([0-4]\d|5[0-2])(-?[1-7])?|(00[1-9]|0[1-9]\d|[12]\d{2}|3([0-5]\d|6[1-6])))([T\s]((([01]\d|2[0-3])((:?)[0-5]\d)?|24\:?00)([\.,]\d+(?!:))?)?(\17[0-5]\d([\.,]\d+)?)?([zZ]|([\+-])([01]\d|2[0-3]):?([0-5]\d)?)?)?)?$
有効なISO8601の日付と一致するため、これはあなたの質問に正確には答えないと思いますが、それで問題がなければ、これは完全に機能します。
これが私が使っている機能です。これはdrew010の回答に似ていますが、「+ 01:00」または「-01:00」で終わるタイムスタンプに対しても機能します。
function isTimestampIsoValid($timestamp)
{
if (preg_match('/^'.
'(\d{4})-(\d{2})-(\d{2})T'. // YYYY-MM-DDT ex: 2014-01-01T
'(\d{2}):(\d{2}):(\d{2})'. // HH-MM-SS ex: 17:00:00
'(Z|((-|\+)\d{2}:\d{2}))'. // Z or +01:00 or -01:00
'$/', $timestamp, $parts) == true)
{
try {
new \DateTime($timestamp);
return true;
}
catch ( \Exception $e)
{
return false;
}
} else {
return false;
}
}