Smarty 设置时区实现方法

作者:袖梨 2022-06-25

Smarty自带的时间格式化(date_format[格式化日期])是比较强大的,其参数甚至可以是MySQL或者Unix的时间戳。不过刚才在使用的时候发现格式化有点小问题:

代码如下 复制代码

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

相关文章

精彩推荐