本篇主要分析下SuagrCRM中的日期时间处理。
./include/entryPoint.php // 获取时间日期处理示例,并放入全局变量中 $timedate = TimeDate::getInstance(); $GLOBALS['timedate'] = $timedate; ./include/TimeDate.php // 单例实现 public static function getInstance() { // 设置时区 if(empty(self::$timedate)) { // 如果没有设置时区,那么判断到此后,都会在项目根目录写条日志 // 日志的配置在config.php里查看logger数组信息 if(ini_get('date.timezone') == '') { // Remove warning about default timezone date_default_timezone_set(@date('e')); try { $tz = self::guessTimezone(); } catch(Exception $e) { $tz = "UTC"; // guess failed, switch to UTC } if(isset($GLOBALS['log'])) { $GLOBALS['log']->fatal("Configuration variable date.timezone is not set, guessed timezone $tz. Please set date.timezone=\"$tz\" in php.ini!"); } date_default_timezone_set($tz); } self::$timedate = new self; } return self::$timedate; } function guessTimezone($userOffset = 0) { if (!is_numeric($userOffset)) { return ''; } $defaultZones = array( 'America/Anchorage', 'America/Los_Angeles', 'America/Phoenix', 'America/Chicago', 'America/New_York', 'America/Argentina/Buenos_Aires', 'America/Montevideo', 'Europe/London', 'Europe/Amsterdam', 'Europe/Athens', 'Europe/Moscow', 'Asia/Tbilisi', 'Asia/Omsk', 'Asia/Jakarta', 'Asia/Hong_Kong', 'Asia/Tokyo', 'Pacific/Guam', 'Australia/Sydney', 'Australia/Perth', ); /* object(DateTime)#1 (3) { ["date"]=> string(19) "2016-01-13 15:17:45" ["timezone_type"]=> int(3) ["timezone"]=> string(13) "Asia/Shanghai" } */ $now = new DateTime(); // 获取时区列表 $tzlist = timezone_identifiers_list(); if ($userOffset == 0) { // 时差偏移量的秒数。UTC 西边的时区偏移量总是负的,UTC 东边的时区偏移量总是正的。 -43200 到 43200 $gmtOffset = date('Z'); // 时区标识(PHP 5.1.0 新加) 例如:UTC,GMT,Atlantic/Azores $nowtz = date('e'); // 把本地所在的时区加入到$tzlist数组中 if (in_array($nowtz, $tzlist)) { array_unshift($defaultZones, $nowtz); } else { // date('T') 本机所在的时区 // date('l') 星期几,完整的文本格式 Sunday 到 Saturday // timezone_name_from_abbr 返回时区名称的缩写 Asia/Chongqing $nowtz = timezone_name_from_abbr(date('T'), $gmtOffset, date('I')); if (in_array($nowtz, $tzlist)) { array_unshift($defaultZones, $nowtz); } } } else { $gmtOffset = $userOffset * 60; } // 下面两个循环是从小到大的范围查找时区 foreach ($defaultZones as $zoneName) { $tz = new DateTimeZone($zoneName); if ($tz->getOffset($now) == $gmtOffset) { return $tz->getName(); } } // try all zones foreach ($tzlist as $zoneName) { $tz = new DateTimeZone($zoneName); if ($tz->getOffset($now) == $gmtOffset) { return $tz->getName(); } } return null; }