ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Twig date 过滤器详解:格式、时区与默认值配置实战(基于 twig/twig 源码)

Twig date 过滤器详解:格式、时区与默认值配置实战(基于 twig/twig 源码) 后端【免费下载链接】TwigTwig, the flexible, fast, and secure template language for PHP项目地址https://gitcode.com/gh_mirrors/tw/Twig点击查看免费下载本篇指南以 Twig 官方文档 date 过滤器参考 为主体系统讲解date过滤器的格式化用法、可接受输入类型、默认格式与默认时区的配置方式并结合 CoreExtension 源码与 集成测试用例 还原其底层调用链。读完后你将能够正确在模板中格式化日期、按需求切换时区并通过setDateFormat()/setTimezone()在全局层面定制输出。基本用法把日期格式化成目标格式date过滤器将日期值渲染为指定格式格式符遵循 PHP 内置date函数的格式字符约定{{ post.published_at|date(m/d/Y) }}一个重要的例外当被过滤的值是DateInterval类型时格式符必须遵循DateInterval::format的格式字符如%d days而不是date()的格式字符因为DateInterval只有时长含义没有绝对时间点。date过滤器接受的输入包括字符串必须能被 PHP 的strtotime函数解析的日期字符串例如now、2010-10-04 13:45DateTime/DateTimeImmutable实例DateInterval实例数字从 convertDate 的源码 可以看到纯数字含负数会被当作 Unix 时间戳处理通过new \DateTime(.$date)构造。例如显示当前日期直接对字符串now应用过滤器{{ now|date(m/d/Y) }}如果想在输出中显示格式字符串里的普通英文单词比如 at需要用反斜杠转义每一个字符避免被 PHP 当作格式符解析{{ post.published_at|date(F jS \\a\\t g:ia) }}null 与空值的行为文档明确了一个容易踩坑的细节当传入date过滤器的值是null时默认返回当前日期。从 convertDate 源码 可以确认这一点null会被替换为字符串now再构造DateTime。如果你希望空值渲染为空字符串而不是当前日期文档给出的做法是配合三元运算符{{ post.published_at is empty ? : post.published_at|date(m/d/Y) }}参数说明参数说明默认值format目标日期格式串。作用于DateInterval时须用DateInterval::format格式符不传时使用默认格式F j, Y H:i渲染效果类似January 11, 2024 15:17timezone目标时区。支持 PHP 支持的时区名字符串或\DateTimeZone对象传false表示保持对象自身时区不变不传时使用默认时区Twig 过滤器支持命名参数date 集成测试 中就有命名用法的实证{{ date7|date(timezoneEurope/Paris) }}修改默认格式setDateFormat()不指定format时Twig 使用内置默认格式。从 CoreExtension 的类属性定义 可以看到这一组默认值private $dateFormats [F j, Y H:i, %d days];第一个元素是日期的默认格式第二个元素是DateInterval的默认格式对应源码中formatDate()的选取逻辑 L523-L526$date instanceof \DateInterval时取$formats[1]否则取$formats[0]。默认格式可以在运行时通过core扩展实例上的setDateFormat()覆盖第一个参数是日期默认格式第二个是时长默认格式$twig new \Twig\Environment($loader); $twig-getExtension(\Twig\Extension\CoreExtension::class)-setDateFormat(d/m/Y, %d days);setDateFormat 的实现 采用“按位置非空覆盖”策略传入null的槽位保持原值不变因此可以只改日期格式而保留时长格式public function setDateFormat($format null, $dateIntervalFormat null): void { if (null ! $format) { $this-dateFormats[0] $format; } if (null ! $dateIntervalFormat) { $this-dateFormats[1] $dateIntervalFormat; } }日期默认格式测试 和 时长默认格式测试 验证了这套行为在设置setDateFormat(Y-m-d, %d days %h hours)后{{ date1|date }}输出2010-10-04而{{ date2|date }}P2D时长输出2 days 0 hours显式传入格式串时则始终优先于默认值。时区处理三种取值语义date过滤器默认按“默认时区”渲染——即 php.ini 中声明的时区或在 Twig 中显式设置的时区。文档给出了三层控制手段恰好对应 convertDate 源码 中$timezone参数的三种取值语义传时区名字符串或\DateTimeZone对象强制把日期转换到该时区显示{{ post.published_at|date(m/d/Y, Europe/Paris) }}传false当输入本身是DateTime对象且希望保留其当前时区时传false即可跳过时区转换{{ post.published_at|date(m/d/Y, false) }}源码中该分支体现为DateTimeImmutable走false ! $timezone ? $date-setTimezone($timezone) : $date普通DateTime则先clone再按需setTimezone避免污染传入的原始对象L596-L607。全局设置默认时区通过setTimezone()一次性指定接受时区字符串或\DateTimeZone实例$twig new \Twig\Environment($loader); $twig-getExtension(\Twig\Extension\CoreExtension::class)-setTimezone(Europe/Paris);setTimezone / getTimezone 的实现 显示字符串会被立即包装为\DateTimeZone若从未调用过setTimezone()getTimezone()会惰性回退到 PHP 的date_default_timezone_get()。注意时区参数对DateInterval没有意义。时长格式化测试 特意传入America/New_York时区并验证输出不变2 days 0 hours注释明确写着 This should have no effect on \DateInterval formatting——这与源码一致formatDate()对DateInterval直接返回$date-format($format)根本不走convertDate()。源码视角formatDate 的完整调用链date过滤器在 CoreExtension::getFilters() 中注册指向实例方法new TwigFilter(date, [$this, formatDate]),核心实现在 formatDate()public function formatDate($date, $format null, $timezone null): string { if (null $format) { $formats $this-getDateFormat(); $format $date instanceof \DateInterval ? $formats[1] : $formats[0]; } if ($date instanceof \DateInterval) { return $date-format($format); } return $this-convertDate($date, $timezone)-format($format); }执行逻辑可以归纳为四步format为空 → 按输入类型从$dateFormats数组选取默认格式输入是DateInterval→ 直接调用DateInterval::format()返回其余输入统一交给convertDate()归一化为DateTime/DateTimeImmutable最终调用format()输出字符串。convertDate()L584-L629还负责了类型归一化的其余细节数字按 Unix 时间戳前缀构造负数时间戳同样支持测试数据date5 -189291360输出 1964 年的日期即为佐证对DateTime会先clone再做时区设置保证模板中同一变量反复格式化时互不干扰。此外src/Resources/core.php 中还保留了历史遗留的全局函数twig_date_format_filter()它只是转发到CoreExtension::formatDate()并自 Twig 3.9 起被标记为deprecated——在新代码与自定义模板中应直接使用date过滤器而不是这些内部函数。与 date 函数、date_modify 过滤器的配合date过滤器只负责“格式化输出”。如果需要日期比较应使用同名的date函数返回日期对象而非字符串用法参考 doc/functions/date.rst{% if date(user.created_at) date(-2days, Europe/Paris) %} {# do something #} {% endif %}如果需要偏移计算可以链式调用date_modify过滤器后再格式化这一组合在 CoreExtension::modifyDate 的注释 和 date_immutable 测试 中都有示例{{ date1|date_modify(1 hour)|date(d/m/Y H:i:s) }}关键参考路径文档主体doc/filters/date.rst过滤器实现与默认值src/Extension/CoreExtension.php$dateFormats默认值 L137、setDateFormatL147、setTimezoneL173、formatDateL521、convertDateL584遗留全局函数已废弃src/Resources/core.php行为验证测试tests/Fixtures/filters/date.test、date_interval.test、date_default_format.test、date_time_zone_conversion.test、date_immutable.test环境前提当前仓库 composer.json 要求 PHP 8.1以上date过滤器行为基于该版本线验证。赞分享后端【免费下载链接】TwigTwig, the flexible, fast, and secure template language for PHP项目地址https://gitcode.com/gh_mirrors/tw/Twig点击查看免费下载相关推荐Twig convert_encoding 过滤器基于 iconv 的模板层字符编码转换详解Twig convert_encoding 过滤器基于 iconv 的模板层字符编码转换详解 在涉及多语言数据源如日文、俄文、中文内容混排的 PHP 项目后端Twig data_uri 过滤器详解基于 RFC 2397 在模板中内联生成 Data URITwig data_uri 过滤器详解基于 RFC 2397 在模板中内联生成 Data URI 本文围绕 Twig 的 data_uri 过滤器展开它能把后端Twig IntlExtension 深度解析currency_symbol 过滤器从用法到源码实现Twig IntlExtension 深度解析currency_symbol 过滤器从用法到源码实现 currency_symbol 是 Twig 官方 In后端上一篇sebastian/diff的技术文档API参考与使用指南下一篇GrapesJS MJML开发环境搭建5分钟上手的完整步骤创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表