Smarty 设置时区实现方法

作者:袖梨 2022-06-25

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编译生成的源文件,在对应的地方找到了这一句:

 代码如下 复制代码

   $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()函数,这个函数根据区域设置格式化本地时间/日期,这里的区域也正是我们之前设置的时区。整个过程应该是这样的了

相关文章

精彩推荐