日付の基礎 date()
echo date('Y-m-d'); // 本日
echo date('U'); // 現在のUNIXタイムスタンプ
echo date("H:i:s"); // 現在時刻
echo strtotime('2012-12-12'); // 文字列日付からのUNIXタイムスタンプ
echo date('Y-m-d',strtotime('2012-12-12')); // 文字列から日付
echo date('Ymdhis', strtotime('2019-1-2 3:4:5')); // → 20190102030405
2018-12-10
1544412967
04:36:07
1355266800
2012-12-12
タイムゾーンを東京に設定する | date_default_timezone_set('Asia/Tokyo');
// タイムゾーンを東京に設定する
date_default_timezone_set('Asia/Tokyo');
// 設定されているタイムゾーンを表示する
var_dump(date_default_timezone_get());
文字列から日時フォーマットを取得する関数
<?php
$data = [
'2012-12-12 12:12:12',
'2012/12/12 12:12:12',
'20121212121212',
'2012-3-10 1:15:1',
'2012-1-1 1:1:1',
'2012-1-1 1:1',
'2012-1-1 1',
'2012-1-1',
'2012-1',
'2012',
'1-1',
'12-12',
'1:1:1',
'12:12:12',
'12:12',
'12',
'2012-32-12 12:12:12',
];
echo "<table class='tbl2'><thead><tr><th>文字列</th><th>フォーマット</th>><th>フォーマット(MySQL型)</th>><th>フォーマット(時刻優先)</th></tr></thead><tbody>";
foreach($data as $str){
$format = getDateFormatFromString($str);
$format2 = getDateFormatFromString($str,['mysql_format_flg'=>1]);
$format3 = getDateFormatFromString($str,['time_priority'=>1]);
echo "<tr><td>{$str}</td><td>{$format}</td><td>{$format2}</td><td>{$format3}</td></tr>";
}
echo "</tbody></table>";
/**
* 文字列から適切な日時のフォーマットを取得する
*
* @param string $str 日付文字列
* @param $format = string フォーマット
* @param $option
* - time_priority 時刻優先フラグ 0:日付フォーマットを優先取得 , 1:時刻フォーマットを優先取得
* - mysql_format_flg MySQLフォーマットフラグ 0:PHP型の日時フォーマット , 1:MySQL型の日時フォーマット
*/
function getDateFormatFromString($str,$option=array()){
$time_priority = 0;
if(!empty($option['time_priority'])) $time_priority = $option['time_priority'];
$mysql_format_flg = 0;
if(!empty($option['mysql_format_flg'])) $mysql_format_flg = $option['mysql_format_flg'];
$format = '';
if(preg_match('/^¥d+$/', $str)){
$len = strlen($str);
if($len == 14){
$format = 'Y-m-d H:i:s';
}else if($len == 8){
$format = 'Y-m-d';
}else if($len == 6){
if($time_priority == 0){
$format = 'Y-m-d';
}else{
$format = 'H:i:s';
}
}else if($len == 4){
if($time_priority == 0){
if(preg_match('/^20¥d[2](¥/|-)([0-9]{1,2})/', $str)){
$format = 'Y';
}else{
$format = 'm-d';
}
}else{
$format = 'H:i';
}
}else if($len == 1 || $len == 2){
if($time_priority == 0){
$format = 'd';
}else{
$format = 'h';
}
}
}
else if(preg_match('/^20¥d[2](¥/|-)([0-9]{1,2})(¥/|-)([0-9]{1,2}) ([0-9]{1,2}):([0-9]{1,2}):([0-9]{1,2})/', $str)){
$format = 'Y-m-d H:i:s';
}
else if(preg_match('/^20¥d[2](¥/|-)([0-9]{1,2})(¥/|-)([0-9]{1,2}) ([0-9]{1,2}):([0-9]{1,2})/', $str)){
$format = 'Y-m-d H:i';
}
else if(preg_match('/^20¥d[2](¥/|-)([0-9]{1,2})(¥/|-)([0-9]{1,2}) ([0-9]{1,2})/', $str)){
$format = 'Y-m-d H';
}
else if(preg_match('/^20¥d[2](¥/|-)([0-9]{1,2})(¥/|-)([0-9]{1,2})/', $str)){
$format = 'Y-m-d';
}
else if(preg_match('/^20¥d[2](¥/|-)([0-9]{1,2})/', $str)){
$format = 'Y-m';
}
else if(preg_match('/^20¥d[2]/', $str)){
$format = 'Y';
}
else if(preg_match('/([0-9]{1,2})(¥/|-)([0-9]{1,2})/', $str)){
$format = 'm-d';
}
else if(preg_match('/([0-9]{1,2}):([0-9]{1,2}):([0-9]{1,2})/', $str)){
$format = 'H:i:s';
}
else if(preg_match('/([0-9]{1,2}):([0-9]{1,2})/', $str)){
$format = 'H:i';
}
if(!empty($mysql_format_flg)){
$format2='';
$ary = str_split($format);
for($i=0;$i<count($ary);$i++){
if($i % 2==0){
$format2 .= '%' . $ary[$i];
}else{
$format2 .= $ary[$i];
}
}
$format = $format2;
}
return $format;
}
?>
出力結果
文字列 | フォーマット | >フォーマット(MySQL型) | >フォーマット(時刻優先) |
---|
2012-12-12 12:12:12 | Y-m-d H:i:s | %Y-%m-%d %H:%i:%s | Y-m-d H:i:s |
2012/12/12 12:12:12 | Y-m-d H:i:s | %Y-%m-%d %H:%i:%s | Y-m-d H:i:s |
20121212121212 | Y-m-d H:i:s | %Y-%m-%d %H:%i:%s | Y-m-d H:i:s |
2012-3-10 1:15:1 | Y-m-d H:i:s | %Y-%m-%d %H:%i:%s | Y-m-d H:i:s |
2012-1-1 1:1:1 | Y-m-d H:i:s | %Y-%m-%d %H:%i:%s | Y-m-d H:i:s |
2012-1-1 1:1 | Y-m-d H:i | %Y-%m-%d %H:%i | Y-m-d H:i |
2012-1-1 1 | Y-m-d H | %Y-%m-%d %H | Y-m-d H |
2012-1-1 | Y-m-d | %Y-%m-%d | Y-m-d |
2012-1 | Y-m | %Y-%m | Y-m |
2012 | m-d | %m-%d | H:i |
1-1 | m-d | %m-%d | m-d |
12-12 | m-d | %m-%d | m-d |
1:1:1 | H:i:s | %H:%i:%s | H:i:s |
12:12:12 | H:i:s | %H:%i:%s | H:i:s |
12:12 | H:i | %H:%i | H:i |
12 | d | %d | h |
2012-32-12 12:12:12 | Y-m-d H:i:s | %Y-%m-%d %H:%i:%s | Y-m-d H:i:s |
番号文字列から日付を取得する関数
<?php
$data = [
'20120101010101',
'20121212121212',
'20121212',
'20120101',
'201212',
'201201',
'180102',
'0101',
'1212',
'2018',
'01',
'12',
'1',
'2',
'0',
'a',
null,
];
echo "<table class='tbl2'><thead><tr><th>番号文字列</th><th>日時</th><th>日時(時刻優先)</th></tr></thead><tbody>";
foreach($data as $str){
$format = convNumStr2date($str);
$format2 = convNumStr2date($str,1);
echo "<tr><td>{$str}</td><td>{$format}</td><td>{$format2}</td></tr>";
}
echo "</tbody></table>";
/**
* 文字列から適切な日時のフォーマットを取得する
*
* @param string $str 日付文字列
* @return string フォーマット
*/
function convNumStr2date($str,$time_priority=0){
if(empty($str)) return $str;
if(!preg_match('/^¥d+$/', $str)) return null;
$ary = str_split($str, 2);
$len = strlen($str);
if($len == 14){
// Y-m-d H:i:s
return "{$ary[0]}{$ary[1]}-{$ary[2]}-{$ary[3]} {$ary[4]}:{$ary[5]}:{$ary[6]}";
}else if($len == 8){
// Y-m-d
return "{$ary[0]}{$ary[1]}-{$ary[2]}-{$ary[3]}";
}else if($len == 6){
if($time_priority == 0){
if(preg_match('/^20¥d[2](¥/|-)([0-9]{1,2})/', $str)){
// Y-m-d
return "{$ary[0]}{$ary[1]}-{$ary[2]}";
}else{
// Y-m-d
return "20{$ary[0]}-{$ary[1]}-{$ary[2]}";
}
}else{
// H:i:s
return "{$ary[0]}:{$ary[1]}:{$ary[2]}";
}
}else if($len == 4){
if($time_priority == 0){
if(preg_match('/^20/', $str)){
// Y
return "{$ary[0]}{$ary[1]}";
}else{
// m-d
return "{$ary[0]}-{$ary[1]}";
}
}else{
// H:i
return "{$ary[0]}:{$ary[1]}:00";
}
}else if($len == 1 || $len == 2){
if($time_priority == 0){
return "{$ary[0]}";
}else{
return "{$ary[0]}:00:00";
}
}
return null;
}
?>
出力結果
番号文字列 | 日時 | 日時(時刻優先) |
---|
20120101010101 | 2012-01-01 01:01:01 | 2012-01-01 01:01:01 |
20121212121212 | 2012-12-12 12:12:12 | 2012-12-12 12:12:12 |
20121212 | 2012-12-12 | 2012-12-12 |
20120101 | 2012-01-01 | 2012-01-01 |
201212 | 2020-12-12 | 20:12:12 |
201201 | 2020-12-01 | 20:12:01 |
180102 | 2018-01-02 | 18:01:02 |
0101 | 01-01 | 01:01:00 |
1212 | 12-12 | 12:12:00 |
2018 | 2018 | 20:18:00 |
01 | 01 | 01:00:00 |
12 | 12 | 12:00:00 |
1 | 1 | 1:00:00 |
2 | 2 | 2:00:00 |
0 | 0 | 0 |
a | | |
| | |
部分的日時のフォーマット変換
検証
<table class='tbl2'><thead><tr>
<th>部分的日付(入力)</th>
<th>部分的日付のフォーマット</th>
<th>変換先のフォーマット</th><th>出力</th></tr></thead><tbody>
<?php
$data = [
['2012-1-12 12:34:56' , 'Y-m-d H:i:s' , 'Y/m/d H:i'],
['2012/1/12 12:34:56' , 'Y-m-d H:i:s' , 'Y-m-d H:i'],
['1-12' , 'm-d' , 'Y-m-d H:i:s'],
['2018' , 'Y' , 'Y-m-d H:i:s'],
['1:2:3' , 'H:i:s' , 'Y-m-d H:i:s'],
['08 34:56' , 'm i:s' , 'Y-m-d H:i'],
];
foreach($data as $ent){
$dt1 = $ent[0]; // 部分的日時
$format1 = $ent[1]; // 部分的日時のフォーマット
$format2 = $ent[2]; // 変換先のフォーマット
$dt2 = convDatetimeFormat($dt1,$format1,$format2); // フォーマット変換された日時
echo "<tr><td>{$dt1}</td><td>{$format1}</td><td>{$format2}</td><td>{$dt2}</td></tr>";
}
?>
</tbody></table>
/**
* 部分的日時のフォーマット変換
* @param string $str 部分的日時
* @param string $format1 部分的日時のフォーマット
* @param string $format2 変換先のフォーマット
* @param array $option オプション
* - digit2_flg 2桁そろえフラグ 0:2桁に揃えず , 1(デフォルト):2桁に揃える( 例: 8 → 08)
* @return string フォーマット変換された日時
*/
function convDatetimeFormat($str,$format1,$format2,$option=array()){
$digit2_flg = 1;
if(isset($option['digit2_flg'])) $digit2_flg = $option['digit2_flg'];
$list = preg_split("/[-\/\s:]/", $str);
$fmts1 = preg_split("/[-\/\s:]/", $format1);
$fKeys1 = array_flip($fmts1);
$fmts2 = preg_split("/[-\/\s:]/", $format2);
$str2 = $format2;
foreach($fmts2 as $i => $key){
$v = null;
if(isset($fKeys1[$key])){
$fk_i = $fKeys1[$key];
$v = $list[$fk_i];
}else{
switch ($key) {
case 'Y': $v = date('Y'); break;
case 'm': $v = '1'; break;
case 'd': $v = '1'; break;
case 'H': $v = '0'; break;
case 'i': $v = '0'; break;
case 's': $v = '0'; break;
}
}
if(!empty($digit2_flg) && strlen($v) == 1){
$v = '0' . $v;
}
$str2 = str_replace($key, $v, $str2);
}
return $str2;
}
部分文字列から日時情報を推測するクラス DatetimeGuess.php
<table class='tbl2'><thead><tr>
<th>元の日時文字列</th>
<th>datetime_a</th>
<th>format_a</th>
<th>datetime_b</th>
<th>format_b</th>
<th>format_mysql_a</th>
<th>format_mysql_b</th>
</tr></thead><tbody>
<?php
$data = [
'2018-3-31 7:39:57',
'2018/3/31 7:39:57',
'2018-03-31 07:39:57',
'2018-3-31 7:39',
'2018-3-31 7',
'2018-3-31',
'2018-3',
'2018',
'7:39:57',
'7:39',
'7',
'20180331073957',
'201803310739',
'2018033107',
'20180331',
'201803',
'2018',
'073957',
'0739',
'07',
'3/31',
'201404',
'199912',
'1999',
];
require_once 'DatetimeGuess.php';
$datetimeGuess = new DatetimeGuess();
foreach($data as $str){
$info = $datetimeGuess->guessDatetimeInfo($str);
echo
"<tr>
<td>{$info['orig_datetime']}</td>
<td>{$info['datetime_a']}</td>
<td>{$info['format_a']}</td>
<td>{$info['datetime_b']}</td>
<td>{$info['format_b']}</td>
<td>{$info['format_mysql_a']}</td>
<td>{$info['format_mysql_b']}</td>
</tr>";
}
?>
</tbody></table>
/**
* 部分文字列から日時情報を推測するクラス
*
* @note
* 「2018-3」,「4-1」,「10:30」などの部分的な日時文字列から、フォーマットや日時などの情報を取得する。
*
* @date 2018-3-31
* @version 1.0
* @author kenji uehara
*
*/
class DatetimeGuess{
/**
* 部分的な日時文字列から日時情報を推測する。
*
* @note
* 部分的な日時文字列とは「2018-8」,「8/31」,「10:30」などを指す。
*
* @param string $str 部分的日時文字列
* @param $option
* - time_priority 時刻優先フラグ(あいまいな数値並びである場合、日付と時刻のどちらを優先判定するか) 0:日付フォーマットを優先判定 , 1:時刻フォーマットを優先判定
* - format_b 出力の1つであるdatetime_bのフォーマット(デフォルト→ Y-m-d H:i:s)
* @return array
* - orig_datetime 元の日時文字列
* - datetime_a 部分日時
* - format_a 部分日時フォーマット
* - datetime_b 日時
* - format_b 日時フォーマット
* - format_mysql_a 部分日時フォーマット(MySQL用)
* - format_mysql_b 日時フォーマット(MySQL用)
*
*/
public function guessDatetimeInfo($str,$option=array()){
$orig_datetime = $str;
// 番号のみの文字列から日時を推測取得するする(201808など)
$datetime_a = $this->convNumStr2date($str,$option);
// 部分日付文字列のフォーマットを取得する
$format_a = $this->getDateFormatFromString($datetime_a,$option);
$format_b = 'Y-m-d H:i:s';
if(isset($option['format_b'])) $format_b = $option['format_b'];
// 部分的日時のフォーマット変換
$datetime_b = $this->convDatetimeFormat($datetime_a,$format_a,$format_b);
// 日時フォーマットをMySQL用の日時フォーマットに変換する(例:Y-m-d → %Y-%m-%d)
$format_mysql_a = $this->convDateformatForMySql($format_a);
$format_mysql_b = $this->convDateformatForMySql($format_b);
return array(
'orig_datetime' => $orig_datetime,
'datetime_a' => $datetime_a,
'format_a' => $format_a,
'datetime_b' => $datetime_b,
'format_b' => $format_b,
'format_mysql_a' => $format_mysql_a,
'format_mysql_b' => $format_mysql_b,
);
}
/**
* 文字列から適切な日時のフォーマットを取得する
*
* @param string $str 日付文字列
* @param $format = string フォーマット
* @param $option
* - time_priority 時刻優先フラグ 0:日付フォーマットを優先判定 , 1:時刻フォーマットを優先判定
* - mysql_format_flg MySQLフォーマットフラグ 0:PHP型の日時フォーマット , 1:MySQL型の日時フォーマット
*/
public function getDateFormatFromString($str,$option=array()){
$time_priority = 0;
if(!empty($option['time_priority'])) $time_priority = $option['time_priority'];
$mysql_format_flg = 0;
if(!empty($option['mysql_format_flg'])) $mysql_format_flg = $option['mysql_format_flg'];
$format = '';
if(preg_match('/^\d+$/', $str)){
$len = strlen($str);
if($len == 14){
$format = 'Y-m-d H:i:s';
}else if($len == 8){
$format = 'Y-m-d';
}else if($len == 6){
if($time_priority == 0){
$format = 'Y-m-d';
}else{
$format = 'H:i:s';
}
}else if($len == 4){
if($time_priority == 0){
if(preg_match('/^[1-9][0-9]{3}$/', $str)){
$format = 'Y';
}else{
$format = 'm-d';
}
}else{
$format = 'H:i';
}
}else if($len == 1 || $len == 2){
if($time_priority == 0){
$format = 'd';
}else{
$format = 'h';
}
}
}
else if(preg_match('/^[1-9]([0-9]{3})(\/|-)([0-9]{1,2})(\/|-)([0-9]{1,2}) ([0-9]{1,2}):([0-9]{1,2}):([0-9]{1,2})/', $str)){
$format = 'Y-m-d H:i:s';
}
else if(preg_match('/^[1-9]([0-9]{3})(\/|-)([0-9]{1,2})(\/|-)([0-9]{1,2}) ([0-9]{1,2}):([0-9]{1,2})/', $str)){
$format = 'Y-m-d H:i';
}
else if(preg_match('/^[1-9]([0-9]{3})(\/|-)([0-9]{1,2})(\/|-)([0-9]{1,2}) ([0-9]{1,2})/', $str)){
$format = 'Y-m-d H';
}
else if(preg_match('/^[1-9]([0-9]{3})(\/|-)([0-9]{1,2})(\/|-)([0-9]{1,2})/', $str)){
$format = 'Y-m-d';
}
else if(preg_match('/^[1-9]([0-9]{3})(\/|-)([0-9]{1,2})/', $str)){
$format = 'Y-m';
}
else if(preg_match('/^[1-9]([0-9]{3})$/', $str)){
$format = 'Y';
}
else if(preg_match('/([0-9]{1,2})(\/|-)([0-9]{1,2})/', $str)){
$format = 'm-d';
}
else if(preg_match('/([0-9]{1,2}):([0-9]{1,2}):([0-9]{1,2})/', $str)){
$format = 'H:i:s';
}
else if(preg_match('/([0-9]{1,2}):([0-9]{1,2})/', $str)){
$format = 'H:i';
}
// MySQLフォーマットフラグがONであるならば、日時フォーマットをMySQL用の日時フォーマットに変換する(例:Y-m-d → %Y-%m-%d)
if(!empty($mysql_format_flg)){
$format = $this->convDateformatForMySql($format);
}
return $format;
}
/**
* 日時フォーマットをMySQL用の日時フォーマットに変換する(例:Y-m-d → %Y-%m-%d)
* @param string $format 日時フォーマット
* @return string MySQL用の日時フォーマット
*/
public function convDateformatForMySql($format){
$format2='';
$ary = str_split($format);
for($i=0;$i $key){
$v = null;
if(isset($fKeys1[$key])){
$fk_i = $fKeys1[$key];
$v = $list[$fk_i];
}else{
switch ($key) {
case 'Y': $v = date('Y'); break;
case 'm': $v = '1'; break;
case 'd': $v = '1'; break;
case 'H': $v = '0'; break;
case 'i': $v = '0'; break;
case 's': $v = '0'; break;
}
}
if(!empty($digit2_flg) && strlen($v) == 1){
$v = '0' . $v;
}
$str2 = str_replace($key, $v, $str2);
}
return $str2;
}
}
検証
手入力日時の自動変換
手入力による様々な日付文字列入力を正しい日付フォーマットに自動変換する関数。
全角数値は半角数値に変換される。
日付文字列の前後に文字列があっても問題ない。
クラスメソッド型
/**
* 手入力日時の自動変換
*
* @note
* 手入力による様々な日付文字列入力を正しい日付フォーマットに自動変換する。
* 全角数値は半角数値に変換される。
* 日付文字列の前後に文字列があっても問題ない。
*
* 例)
* 「山の日8月12日公共」 → 2019-8-12 12:13:14
*
* @param string $date_str 日付文字列
* @param string $format 日付フォーマット(デフォ:Y-m-d h:i:s)
* @return array
* - string value 自動変換後の日付
* - string err 入力エラー文字列
*/
public function humanInputDateTime($date_str, $format='Y-m-d h:i:s'){
$date_str0 = $date_str;
$res = ['date'=>$date_str, 'err'=>''];
if(empty($date_str)) return $res;
$date_str = mb_convert_kana($date_str, 'n'); // 全角を半角に変換する
$date_str = mb_convert_kana($date_str, 's'); // 全角スペースを半角に変換する
$date_str = mb_convert_kana($date_str, 'a'); // 全角記号半角に変換する
$date_str = str_replace('・', '/', $date_str); // 「・」はスラッシュに置換する
$date_str = trim($date_str);
$date_str = preg_replace('/¥s(?=¥s)/', '', $date_str); // 連続スペースを一つにする
if(empty($date_str)) return $res;
$date_str = str_replace('日 ', ' ', $date_str);
$success = false; // 成功フラグ
// Y/m/d h:i:s
$date = '';
$re = '{([0-9]{4})(¥/|-|年)([0-9]{1,2})(¥/|-|月)([0-9]{1,2})(日|¥s)([0-9]{1,2})(:|時)([0-9]{1,2})(:|分)([0-9]{1,2})}';
preg_match($re, $date_str, $match);
if(!empty($match)){
$date = $match[0];
$success = true;
}
// Y/m/d h:i
if(empty($success)){
$re = '{([0-9]{4})(¥/|-|年)([0-9]{1,2})(¥/|-|月)([0-9]{1,2})(日|¥s)([0-9]{1,2})(:)([0-9]{1,2})}';
preg_match($re, $date_str, $match);
if(!empty($match)){
$date = $match[0];
$date .= ':00';
$success = true;
}
}
// Y/m/d
if(empty($success)){
$re = '{([0-9]{4})(¥/|-|年)([0-9]{1,2})(¥/|-|月)([0-9]{1,2})}';
preg_match($re, $date_str, $match);
if(!empty($match)){
$date = $match[0];
$date .= ' 00:00:00';
$success = true;
}
}
// m/d
if(empty($success)){
$re = '{([0-9]{1,2})(¥/|-|月)([0-9]{1,2})}';
preg_match($re, $date_str, $match);
if(!empty($match)){
$date = $match[0];
$date = date('Y') . '/' . $date . ' 00:00:00';
$success = true;
}
}
// y/m
if(empty($success)){
$re = '{([0-9]{4})(¥/|-|年)([0-9]{1,2})}';
preg_match($re, $date_str, $match);
if(!empty($match)){
$date = $match[0];
$date .= '/1 00:00:00';
$success = true;
}
}
// h:i:s
if(empty($success)){
$re = '{([0-9]{1,2})(:|時)([0-9]{1,2})(:|分)([0-9]{1,2})}';
preg_match($re, $date_str, $match);
if(!empty($match)){
$date = $match[0];
$date = date('Y/m/d') . ' ' . $date;
$success = true;
}
}
// h:i
if(empty($success)){
$re = '{([0-9]{1,2})(:|時)([0-9]{1,2})}';
preg_match($re, $date_str, $match);
if(!empty($match)){
$date = $match[0];
$date = date('Y/m/d') . ' ' . $date . ':00';
$success = true;
}
}
// Y
if(empty($success)){
$re = '{([0-9]{4})(年)}';
preg_match($re, $date_str, $match);
if(!empty($match)){
$date = $match[0];
$date = $date . '1/1 00:00:00';
$success = true;
}
}
// m
if(empty($success)){
$re = '{([0-9]{1,2})(月)}';
preg_match($re, $date_str, $match);
if(!empty($match)){
$date = $match[0];
$date = date('Y') . '/' . $date . '1 00:00:00';
$success = true;
}
}
// 日
if(empty($success)){
$re = '{([0-9]{1,2})(日)}';
preg_match($re, $date_str, $match);
if(!empty($match)){
$date = $match[0];
$date = date('Y/m') . '/' . $date . ' 00:00:00';
$success = true;
}
}
// 時
if(empty($success)){
$re = '{([0-9]{1,2})(時)}';
preg_match($re, $date_str, $match);
if(!empty($match)){
$date = $match[0];
$date = date('Y/m/d') . ' ' . $date . '00:00';
$success = true;
}
}
// 分
if(empty($success)){
$re = '{([0-9]{1,2})(分)}';
preg_match($re, $date_str, $match);
if(!empty($match)){
$date = $match[0];
$date = date('Y/m/d h:') . $date . '00';
$success = true;
}
}
// 秒
if(empty($success)){
$re = '{([0-9]{1,2})(秒)}';
preg_match($re, $date_str, $match);
if(!empty($match)){
$date = $match[0];
$date = date('Y/m/d h:i:') . $date ;
$success = true;
}
}
if($success == true){
$date = preg_replace('{年|月}', '/', $date);
$date = preg_replace('{時|分}', ':', $date);
$date = str_replace('日', ' ', $date);
$date = str_replace(' ', ' ', $date);
$date = str_replace('秒', '', $date);
$err = $this->isDatetime($date); // 日時チェック
if(empty($err)){
$date = date($format, strtotime($date)); // フォーマット変換
}else{
$date = $date_str0;
$err .= '→' . $date;
}
}else{
$date = $date_str0;
$err = '日時形式ではありません →' . $date;
}
$res['date'] = $date;
$res['err'] = $err;
return $res;
}
/**
* 日時入力チェックのバリデーション
* ※日付のみあるいは時刻は異常と見なす。
* @param string $str_dt 日時文字列
* @param bool $req 入力必須フラグ false:空許可(デフォ), true:入力必須
* @return string エラー文字列 正常のときはnull
* @date 2015-10-5 | 2019-8-12
*/
public function isDatetime($str_dt, $req=false){
//空値且つ、必須入力がnullであれば、trueを返す。
if(empty($str_dt) && empty($req)){
return null;
}
//日時を 年月日時分秒に分解する。
$aryA =preg_split('/[-: ¥/]/', $str_dt );
if(count($aryA)!=6){
return '日時形式ではありません。';
}
foreach ($aryA as $key => $val){
//▼正数以外が混じっているば、即座にfalseを返して処理終了
if (!preg_match("/^[0-9]+$/", $val)) {
return '文字列が混じっています。';
}
}
//▼グレゴリオ暦と整合正が取れてるかチェック。(閏年などはエラー) ※さくらサーバーではemptyでチェックするとバグになるので注意。×→if(empty(checkdate(12,11,2012))){・・・}
if(checkdate($aryA[1],$aryA[2],$aryA[0])==false){
return '存在しない日付です(グレゴリオ暦)。';
}
//▼時刻の整合性をチェック
if($aryA[3] < 0 || $aryA[3] > 23){
return '時刻に異常があります。';
}
if($aryA[4] < 0 || $aryA[4] > 59){
return '「分」に異常があります。';
}
if($aryA[5] < 0 || $aryA[5] > 59){
return '秒に異常があります。';
}
return null;
}
旧型(preg_match関連が安定していない)
/**
* 手入力日時の自動変換
*
* @note
* 手入力による様々な日付文字列入力を正しい日付フォーマットに自動変換する。
* 全角数値は半角数値に変換される。
* 日付文字列の前後に文字列があっても問題ない。
*
* 例)
* 「山の日8月12日公共」 → 2019-8-12 12:13:14
*
* @param string $date_str 日付文字列
* @param string $format 日付フォーマット(デフォ:Y-m-d h:i:s)
* @return array
* - string value 自動変換後の日付
* - string err 入力エラー文字列
*/
function humanInputDateTime($date_str, $format='Y-m-d h:i:s'){
$date_str0 = $date_str;
$res = ['date'=>$date_str, 'err'=>''];
if(empty($date_str)) return $res;
$date_str = mb_convert_kana($date_str, 'n'); // 全角を半角に変換する
$date_str = mb_convert_kana($date_str, 's'); // 全角スペースを半角に変換する
$date_str = mb_convert_kana($date_str, 'a'); // 全角記号半角に変換する
$date_str = str_replace('・', '/', $date_str); // 「・」はスラッシュに置換する
$date_str = trim($date_str);
$date_str = preg_replace('/¥s(?=¥s)/', '', $date_str); // 連続スペースを一つにする
if(empty($date_str)) return $res;
$date_str = str_replace('日 ', ' ', $date_str);
// Y/m/d h:i:s
$date = '';
$re = '/([0-9]{4})(¥/|-|年)([0-9]{1,2})(¥/|-|月)([0-9]{1,2})(日|¥s)([0-9]{1,2})(:|時)([0-9]{1,2})(:|分)([0-9]{1,2})/';
preg_match($re, $date_str, $match);
if(!empty($match)){
$date = $match[0];
}
// Y/m/d h:i
if(empty($date)){
$re = '/([0-9]{4})(¥/|-|年)([0-9]{1,2})(¥/|-|月)([0-9]{1,2})(日|¥s)([0-9]{1,2})(:)([0-9]{1,2})/';
preg_match($re, $date_str, $match);
if(!empty($match)){
$date = $match[0];
$date .= ':00';
}
}
// Y/m/d
if(empty($date)){
$re = '/([0-9]{4})(¥/|-|年)([0-9]{1,2})(¥/|-|月)([0-9]{1,2})/';
preg_match($re, $date_str, $match);
if(!empty($match)){
$date = $match[0];
$date .= ' 00:00:00';
}
}
// m/d
if(empty($date)){
$re = '/([0-9]{1,2})(¥/|-|月)([0-9]{1,2})/';
preg_match($re, $date_str, $match);
if(!empty($match)){
$date = $match[0];
$date = date('Y') . '/' . $date . ' 00:00:00';
}
}
// y/m
if(empty($date)){
$re = '/([0-9]{4})(¥/|-|年)([0-9]{1,2})/';
preg_match($re, $date_str, $match);
if(!empty($match)){
$date = $match[0];
$date .= '/1 00:00:00';
}
}
// h:i:s
if(empty($date)){
$re = '/([0-9]{1,2})(:|時)([0-9]{1,2})(:|分)([0-9]{1,2})/';
preg_match($re, $date_str, $match);
if(!empty($match)){
$date = $match[0];
$date = date('Y/m/d') . ' ' . $date;
}
}
// h:i
if(empty($date)){
$re = '/([0-9]{1,2})(:|時)([0-9]{1,2})/';
preg_match($re, $date_str, $match);
if(!empty($match)){
$date = $match[0];
$date = date('Y/m/d') . ' ' . $date . ':00';
}
}
// Y
if(empty($date)){
$re = '/([0-9]{4})(年)/';
preg_match($re, $date_str, $match);
if(!empty($match)){
$date = $match[0];
$date = $date . '1/1 00:00:00';
}
}
// m
if(empty($date)){
$re = '/([0-9]{1,2})(月)/';
preg_match($re, $date_str, $match);
if(!empty($match)){
$date = $match[0];
$date = date('Y') . '/' . $date . '1 00:00:00';
}
}
// 日
if(empty($date)){
$re = '/([0-9]{1,2})(日)/';
preg_match($re, $date_str, $match);
if(!empty($match)){
$date = $match[0];
$date = date('Y/m') . '/' . $date . ' 00:00:00';
}
}
// 時
if(empty($date)){
$re = '/([0-9]{1,2})(時)/';
preg_match($re, $date_str, $match);
if(!empty($match)){
$date = $match[0];
$date = date('Y/m/d') . ' ' . $date . '00:00';
}
}
// 分
if(empty($date)){
$re = '/([0-9]{1,2})(分)/';
preg_match($re, $date_str, $match);
if(!empty($match)){
$date = $match[0];
$date = date('Y/m/d h:') . $date . '00';
}
}
// 秒
if(empty($date)){
$re = '/([0-9]{1,2})(秒)/';
preg_match($re, $date_str, $match);
if(!empty($match)){
$date = $match[0];
$date = date('Y/m/d h:i:') . $date ;
}
}
$date = preg_replace('/年|月/', '/', $date);
$date = preg_replace('/時|分/', ':', $date);
$date = preg_replace('/日|秒/', '', $date);
$err = isDatetime($date); // 日時チェック
if(empty($err)){
$date = date($format); // フォーマット変換
}else{
$err .= '→' . $date;
$date = '';
}
$res['date'] = $date;
$res['err'] = $err;
return $res;
}
/**
* 日時入力チェックのバリデーション
* ※日付のみあるいは時刻は異常と見なす。
* @param string $str_dt 日時文字列
* @param bool $req 入力必須フラグ false:空許可(デフォ), true:入力必須
* @return string エラー文字列 正常のときはnull
* @date 2015-10-5 | 2019-8-12
*/
function isDatetime($str_dt, $req=false){
//空値且つ、必須入力がnullであれば、trueを返す。
if(empty($str_dt) && empty($req)){
return null;
}
//日時を 年月日時分秒に分解する。
//$aryA =preg_split( '|[ /:_-]|', $str_dt );
$aryA =preg_split("[¥/|-|:|¥s]", $str_dt );
if(count($aryA)!=6){
return '日時形式ではありません。';
}
foreach ($aryA as $key => $val){
//▼正数以外が混じっているば、即座にfalseを返して処理終了
if (!preg_match("/^[0-9]+$/", $val)) {
return '文字列が混じっています。';
}
}
//▼グレゴリオ暦と整合正が取れてるかチェック。(閏年などはエラー) ※さくらサーバーではemptyでチェックするとバグになるので注意。×→if(empty(checkdate(12,11,2012))){・・・}
if(checkdate($aryA[1],$aryA[2],$aryA[0])==false){
return '存在しない日付です(グレゴリオ暦)。';
}
//▼時刻の整合性をチェック
if($aryA[3] < 0 || $aryA[3] > 23){
return '時刻に異常があります。';
}
if($aryA[4] < 0 || $aryA[4] > 59){
return '「分」に異常があります。';
}
if($aryA[5] < 0 || $aryA[5] > 59){
return '秒に異常があります。';
}
return null;
}
検証
strtotimeをいろいろな日付文字列で試す
Demo
strtotime('2022-11-8'); | 1667833200 | |
strtotime('2022-11'); | 1667228400 | |
strtotime('2022'); | 1667906520 | |
strtotime('11'); | | |
strtotime('8'); | | |
strtotime(''); | | |
strtotime(0); | | |
strtotime(null); | | |
strtotime('2022-11-8 12:12:12'); | 1667877132 |
strtotime('2022-11-8 12:12'); | 1667877120 |
strtotime('2022-11-8 12'); | |
strtotime('abc'); | |
strtotime('2022/11/8 12:12:12'); | 1667877132 | スラッシュ区切り |
strtotime('8-11-2022 12:12:12'); | 1667877132 | 米国式の日付記述 |
一か月後
$date2 = date("Y-m-d",strtotime($date1 . "+1 month"));
phpで取り扱える日時や日付形式であるかチェックする
// 日時チェック→ trueなら日付形式ですが、空文字もtrueと判定されます。
private function checkDateTime($dateString) {
// 日付と時刻を解析し、DateTimeオブジェクトを作成
try {
// 日付と時刻を解析してDateTimeオブジェクトを作成
$dateTime = new ¥DateTime($dateString);
return true;
} catch (¥Exception $e) {
// 日付形式が不正な場合は例外をスロー
return false;
}
}
phpで取り扱える日時や日付形式を指定フォーマットに変換する
// 日時変換
private function convertToMySQLDateTime($dateString) {
// 日付と時刻を解析し、DateTimeオブジェクトを作成
try {
// 日付と時刻を解析してDateTimeオブジェクトを作成
$dateTime = new ¥DateTime($dateString);
} catch (¥Exception $e) {
// 日付形式が不正な場合は例外をスロー
return false;
}
// MySQLのDATETIME形式に変換
return $dateTime->format('Y-m-d H:i:s');
}
XXX
- ホーム
- プログラミングの覚書
- PHPの覚書
- PHP | 日付と時刻の覚書