<?php
/**
 * DateUtil
 * 日付に関するユーティリティー
 * $Id: DateUtil.inc,v 1.1 2015/10/08 11:18:56 wanggb Exp $
 * @author iimuro
 * @access public
 * @package jp.aimslib.util
 */

define("JAPANESE_ERA_HEISEI", "HEISEI");
define("JAPANESE_ERA_SHOWA", "SHOWA");
define("JAPANESE_ERA_TAISHO", "TAISHO");
define("JAPANESE_ERA_UNKNOWN", "SEIREKI");

class DateUtil {


	/**
	 * 1910年まで対応したmktimeです。
	 * 60年ずらして計算を行います。
	 * TODO 2000年問題ができてる?
	 * @param int $hour 時
	 * @param int $minute 分
	 * @param int $second 秒
	 * @param int $month 月
	 * @param int $day 日
	 * @param int $year 年
	 * @return int unixtimestamp
	 */
	public static function modMkTime($hour, $minute, $second, $month, $day, $year) {
		if (($year < 1970) && ($year > 1910)) {

			// 両方に60たして差分を取得。2000年があるので、日にち-1
			$tmp1 = mktime(0, 0, 0, $month, $day, $year + 60);
			$tmp2 = mktime(0, 0, 0, 1, 1, 1970 + 60);
			$diff_sec = $tmp2 - $tmp1;

			// 1日の秒数
			//$day_sec = 60 * 60 * 24;
			//$diff_sec -= $day_sec;
			$timestamp = mktime($hour, $minute, $second, 1, 1, 1970) - $diff_sec;
		} else {
			$timestamp = mktime($hour, $minute, $second, $month, $day, $year);
		}
		return $timestamp;

	}


	/**
	 * 和暦の年号を返します。
	 * @param int $timestamp unixtimestamp
	 * @return String 対応する定義名
	 */
	public static function getJapaneseEra($year, $month, $date) {
		$data = DateUtil::_getJapaneseYear($year, $month, $date);
		return $data[0];
	}

	/**
	 * 和暦の年を返します。
	 * @param int $timestamp unixtimestamp
	 * @return int 和暦の年
	 */
	public static function getJapaneseYear($year, $month, $date) {
		$data = DateUtil::_getJapaneseYear($year, $month, $date);
		return $data[1];
	}


	/**
	 * 和暦の年号と年を配列で返します。
	 * @return array 0:年号 1:年
	 */
	public static function _getJapaneseYear($year, $month, $date) {
//		$year = date("Y", $timestamp);
//		$month = date("m", $timestamp);
//		$date = date("d", $timestamp);

		$jp_year = 0;
		$era = "";
		if ($year >= 1989) {
			// 平成
			if (($month <= 1) && ($date <= 7)) {
				// まだ昭和
				$era = JAPANESE_ERA_SHOWA;

				$jp_year = $year - 1925;
			} else {
				$era = JAPANESE_ERA_HEISEI;

				$jp_year = $year - 1988;
			}
		} else if ($year >= 1926) {
			// 平成
			if (($month <= 12) && ($date <= 24)) {
				// まだ昭和
				$era = JAPANESE_ERA_TAISHO;

				$jp_year = $year - 1911;
			} else {
				$era = JAPANESE_ERA_SHOWA;

				$jp_year = $year - 1925;
			}
		} else {
			// あとは西暦
				$era = JAPANESE_ERA_UNKNOWN;

				$jp_year = $year;


		}

		return array($era, $jp_year);

	}

	public static function getDays($fromdate,$todate) {

		$days = 0;

		$tmp_date = $fromdate;

		while ($tmp_date <= $todate) {
			$tmp_date = date("Ymd",mktime(0,0,0,substr($tmp_date,4,2),substr($tmp_date,6,2)+1,substr($tmp_date,0,4)));
			$days++;
		}

		return $days;

	}

	public static function checkDateByYYYYMMDD($date) {

		$str_date = null;

		if ($date == null) {
			return false;
		}

		if (!is_numeric($date)) {
			return false;
		} else {
			$str_date = (string)$date;
			if (strlen($str_date) <> 8) {
				return false;
			} else {
				if (checkdate(substr($str_date,4,2),substr($str_date,6,2),substr($str_date,0,4))) {
					return true;
				} else {
					return false;
				}
			}
		}

	}


	/**
	 * @param string $date_str
	 * @param string $date_len
	 * 				$date_len = 8 例:20060101
	 * 				$date_len = 10 例:2006-01-01 or 2006/01/01
	 * 				$date_len = 19 例:2006-01-01 01:01:01 or 2006/01/01 01:01:01
	 * 				$date_len = 23 例:2006-01-01 01:01:01.001 or 2006/01/01 01:01:01.001
	 * @param string $format '-' or '/' or 'HAN' or 'NONE'
	 * @param string $re_format 'YYYYMMDD' or 'YYYYMM' or 'MMDD' or 'YYYYMMDD HH' or 'YYYYMMDD HHGG' or 'YYYYMMDD HHGGSS'
	 * @return String
	 */
	public static function getFormatDate($date_str, $format, $re_format=null) {

		if ($date_str == null ) return null;

		if ($format == null ) return null;

		$date_len = strlen($date_str);
		if ($date_len < 24) {
			if ($date_len != 8 && $date_len != 10 &&
				$date_len != 19 && $date_len != 23) return $date_str;
		} else {
			$date_str = substr($date_str, 0, 23);
			$date_len = 23;
		}

		$re_date = $date_str;
		$year = "";
		$month = "";
		$day = "";
		$hour = "";
		$min = "";
		$sec = "";
		$usec = "";

		switch ($date_len) {
			case 8:
				$year = substr($date_str, 0, 4);
				$month = substr($date_str, 4, 2);
				$day = substr($date_str, 6, 2);
				break;
			case 10:
				$year = substr($date_str, 0, 4);
				$month = substr($date_str, 5, 2);
				$day = substr($date_str, 8, 2);
				break;
			case 19:
				$year = substr($date_str, 0, 4);
				$month = substr($date_str, 5, 2);
				$day = substr($date_str, 8, 2);

				$hour = substr($date_str, 11, 2);
				$min = substr($date_str, 14, 2);
				$sec = substr($date_str, 17, 2);
				break;
			case 23:
				$year = substr($date_str, 0, 4);
				$month = substr($date_str, 5, 2);
				$day = substr($date_str, 8, 2);

				$hour = substr($date_str, 11, 2);
				$min = substr($date_str, 14, 2);
				$sec = substr($date_str, 17, 2);
				$usec = substr($date_str, 19);
				break;
		}

		switch ($re_format) {
			case "YYYYMMDD":
				switch ($format) {
					case "-":
					case "/":
						$re_date = $year . $format . $month . $format . $day;
						break;
					case "HAN":
//						$month = (substr($month, 0, 1) == "0")?substr($month, 1, 1):$month;
//						$day = (substr($day, 0, 1) == "0")?substr($day, 1, 1):$day;
						$re_date = $year . "年" . $month . "月" . $day . "日";
						break;
					case "NONE":
						$re_date = $year . $month . $day;
						break;
				}
				break;
			case "YYYYMM":
				switch ($format) {
					case "-":
					case "/":
						$re_date = $year . $format . $month;
						break;
					case "HAN":
						$month = (substr($month, 0, 1) == "0")?substr($month, 1, 1):$month;
						$day = (substr($day, 0, 1) == "0")?substr($day, 1, 1):$day;
						$re_date = $year . "年" . $month . "月";
						break;
					case "NONE":
						$re_date = $year . $month;
						break;
				}
				break;
			case "MMDD":
				switch ($format) {
					case "-":
					case "/":
						$re_date = $month . $format . $day;
						break;
					case "HAN":
						$month = (substr($month, 0, 1) == "0")?substr($month, 1, 1):$month;
						$day = (substr($day, 0, 1) == "0")?substr($day, 1, 1):$day;
						$re_date = $month . "月" . $day . "日";
						break;
					case "NONE":
						$re_date = $month . $day;
						break;
				}
				break;
			case "YYYYMMDD HH":
				switch ($date_len) {
					case 8:
					case 10:
						switch ($format) {
							case "-":
							case "/":
								$re_date = $year . $format . $month . $format . $day . " 00";
								break;
							case "HAN":
								$month = (substr($month, 0, 1) == "0")?substr($month, 1, 1):$month;
								$day = (substr($day, 0, 1) == "0")?substr($day, 1, 1):$day;
								$re_date = $year . "年" . $month . "月" . $day . "日" . " 00時";
								break;
							case "NONE":
								$re_date = $year . $month . $day . " 00";
								break;
						}
						break;
					case 19:
					case 23:
						switch ($format) {
							case "-":
							case "/":
								$re_date = $year . $format . $month . $format . $day . " " . $hour;
								break;
							case "HAN":
								$month = (substr($month, 0, 1) == "0")?substr($month, 1, 1):$month;
								$day = (substr($day, 0, 1) == "0")?substr($day, 1, 1):$day;
								$re_date = $year . "年" . $month . "月" . $day . "日" . $hour . "時";
								break;
							case "NONE":
								$re_date = $year . $month . $day . $hour;
								break;
						}
						break;
				}
				break;
			case "YYYYMMDD HHGG":
				switch ($date_len) {
					case 8:
					case 10:
						switch ($format) {
							case "-":
							case "/":
								$re_date = $year . $format . $month . $format . $day . " 00:00";
								break;
							case "HAN":
								$month = (substr($month, 0, 1) == "0")?substr($month, 1, 1):$month;
								$day = (substr($day, 0, 1) == "0")?substr($day, 1, 1):$day;
								$re_date = $year . "年" . $month . "月" . $day . "日" . " 00時00分";
								break;
							case "NONE":
								$re_date = $year . $month . $day . " 00:00";
								break;
						}
						break;
					case 19:
					case 23:
						switch ($format) {
							case "-":
							case "/":
								$re_date = $year . $format . $month . $format . $day . " " . $hour . ":" . $min;
								break;
							case "HAN":
								$month = (substr($month, 0, 1) == "0")?substr($month, 1, 1):$month;
								$day = (substr($day, 0, 1) == "0")?substr($day, 1, 1):$day;
								$re_date = $year . "年" . $month . "月" . $day . "日" . $hour . "時" . $min . "分";
								break;
							case "NONE":
								$re_date = $year . $month . $day . $hour . $min;
								break;
						}
						break;
				}
				break;
			case "YYYYMMDD HHGGSS":
				switch ($date_len) {
					case 8:
					case 10:
						switch ($format) {
							case "-":
							case "/":
								$re_date = $year . $format . $month . $format . $day . " 00:00:00";
								break;
							case "HAN":
								$month = (substr($month, 0, 1) == "0")?substr($month, 1, 1):$month;
								$day = (substr($day, 0, 1) == "0")?substr($day, 1, 1):$day;
								$re_date = $year . "年" . $month . "月" . $day . "日" . " 00時00分00秒";
								break;
							case "NONE":
								$re_date = $year . $month . $day . " 00:00:00";
								break;
						}
						break;
					case 19:
					case 23:
						switch ($format) {
							case "-":
							case "/":
								$re_date = $year . $format . $month . $format . $day . " " . $hour . ":" . $min . ":" . $sec;
								break;
							case "HAN":
								$month = (substr($month, 0, 1) == "0")?substr($month, 1, 1):$month;
								$day = (substr($day, 0, 1) == "0")?substr($day, 1, 1):$day;
								$re_date = $year . "年" . $month . "月" . $day . "日" . $hour . "時" . $min . "分" . $sec . "秒";
								break;
							case "NONE":
								$re_date = $year . $month . $day . $hour . $min . $sec;
								break;
						}
						break;
				}
				break;
		}
		return $re_date;
	}

	/**
	 * 誕生日から年齢を取得
	 *
	 * @param int $birthday YYYYMMDD形式の誕生日。
	 * @param int $today YYYYMMDD形式の日付。指定しない場合、今日。
	 * @return int 年齢
	 */
	public static function getAgeFromBirthday($birthday, $today = null) {

		if (empty($today)) {
			$today = date('Ymd');
		}
		// (今日の日付-誕生日)/10000の小数点以下切捨て。
		$year = (int) (($today - $birthday) / 10000);

		return $year;
	}
	
	/**
	 * 日付の形式が正しいか確認し、正しい場合に指定された形式でデータを返します。
	 * @param $year
	 * @param $mon
	 * @param $day
	 * @param $format
	 * @return String 日付文字列。間違っていた場合名null。
	 */
	public static function getValidDateFormat($year, $mon, $day, $format = "Y-m-d") {
		if (!empty($year) && !empty($mon) && !empty($day) && checkdate($mon, $day, $year)) {
			return date($format, mktime(0, 0, 0, $mon, $day, $year));
		} else {
			return null;
		}
	}

	public static function checkDate($year, $month, $day){


		if ((!is_numeric($year)) || (!is_numeric($month)) || (!is_numeric($day))) {
			return null;
		}

//		if (strlen($year) != 4  || strlen($month) == 0 || strlen($day) == 0) {
//			return null;
//		}
//		 $year = 0+$year;
//		 $month = 0+$month;
//		 $day = 0+ $day;
		 //if (date("Y") < $year || $year > date(Y)) $year = $year-100;
		if ($year < 1900) {
			return null;
		}
		if (checkdate($month, $day, $year)){
			return date("Y-m-d", mktime (0,0,0,$month,$day,$year));
		}
		return null;
	}
	
	
	/**
	 * 日付の形式が正しいか
	 * @param $target_date
	 * @return boolean
	 */
	public static function checkValidDate($target_date) {
		if (preg_match("/^(\d{4}).?(\d{1,2}).?(\d{1,2})$/", $target_date, $tmp)) {
			if ($tmp[1] . "-" . $tmp[2] . "-" . $tmp[3] == date("Y-m-d", strtotime($target_date))) {
				return true;
			}
		}
		return false;
	}
	

}

?>