Smarty自带的时间格式化(date_format[格式化日期])是比较强大的,其参数甚至可以是MySQL或者Unix的时间戳。不过刚才在使用的时候发现格式化有点小问题:
代码如下 | 复制代码 |
<{$smarty.now|date_format:"%Y-%m-%d %H:%M"}> |
获取到的时间却是:2011-06-24 15:58。而我系统的时间是2011年6月24日 23:58,想必大家都明白了,这是时区设置不正确的原因!
从Smarty手册中没有找到相关设置时区的方法,date_format中给出的全部是格式化时间的东西,没有设置时区的选项。百度了一下才知道可以在实例化Smarty这个类的时候设置时区。其实仔细一想也很简单,毕竟Smarty是PHP写的,而且看过模板相关知识的人应该都知道:模板实际上最后还是include到源PHP文件中,只不过多了一个解析、替换的过程。所以就跟写普通PHP文件设置时区一样,最后会在模板中生效。
代码如下 | 复制代码 |
include ROOT."smarty/Smarty.class.php"; date_default_timezone_set('Asia/Shanghai'); //设置时区 $tpl=new Smarty; |
------------------------------------------
想看看Smarty中的时间到底是怎么一回事?那就继续吧...
看看Smarty编译生成的源文件,在对应的地方找到了这一句:
代码如下 | 复制代码 |
<?php echo ((is_array($_tmp=time())) ? $this->_run_mod_handler('date_format', true, $_tmp, "%Y-%m-%d %H:%M") : smarty_modifier_date_format($_tmp, "%Y-%m-%d %H:%M")); ?>
|
首先用time()将当前的Unix时间戳赋给$_tmp变量,赋值运算返回的应该是布尔类型的数据,这里却判断是否是数组类型,有点搞不懂。看看这个三目运算符,当返回是数组的时候执行$this->_run_mod_handler(),跟进这个方法看到跟插件(plugins)有关,貌似暂时用不上,而且也不知道何时能执行。后面这个smarty_modifier_date_format()才是要看的重点。
代码如下 | 复制代码 |
function smarty_modifier_date_format($string, $format = '%b %e, %Y', $default_date = '') { if ($string != '') { //如果时间戳字符串不空,将其格式化 $timestamp = smarty_make_timestamp($string); } elseif ($default_date != '') { //如果字符串为空,并且默认时间不空,将默认时间格式化 $timestamp = smarty_make_timestamp($default_date); } else { return; } if (DIRECTORY_SEPARATOR == '\') { $_win_from = array('%D', '%h', '%n', '%r', '%R', '%t', '%T'); $_win_to = array('%m/%d/%y', '%b', "n", '%I:%M:%S %p', '%H:%M', "t", '%H:%M:%S'); if (strpos($format, '%e') !== false) { $_win_from[] = '%e'; $_win_to[] = sprintf('%' 2d', date('j', $timestamp)); } if (strpos($format, '%l') !== false) { $_win_from[] = '%l'; $_win_to[] = sprintf('%' 2d', date('h', $timestamp)); } $format = str_replace($_win_from, $_win_to, $format); } return strftime($format, $timestamp); //这个是最后一步了,将最终的时间戳根据当前的时区再格式化一下 } |
这个函数前部分主要是为了保证通用性的,它根据不同的字符串格式或者是默认的时间来转换成统一的时间戳。用到的就是smarty_make_timestamp()这个函数:
代码如下 | 复制代码 |
function smarty_make_timestamp($string) { //这里就是为了保证通用性的,对时间字符串进行转化,使其格式统一。下面有注释,这个就不多说了 if(emptyempty($string)) { // use "now": $time = time(); } elseif (preg_match('/^d{14}$/', $string)) { // it is mysql timestamp format of YYYYMMDDHHMMSS? $time = mktime(substr($string, 8, 2),substr($string, 10, 2),substr($string, 12, 2), substr($string, 4, 2),substr($string, 6, 2),substr($string, 0, 4)); } elseif (is_numeric($string)) { // it is a numeric string, we handle it as timestamp $time = (int)$string; } else { // strtotime should handle it $time = strtotime($string); if ($time == -1 || $time === false) { // strtotime() was not able to parse $string, use "now": $time = time(); } } return $time; } |
格式整理好了之后就调用PHP内置的strftime()函数,这个函数根据区域设置格式化本地时间/日期,这里的区域也正是我们之前设置的时区。整个过程应该是这样的了