如何调整Rails的set_time_zone方法,显示带时区名称的友好时间?
Rails时区格式化:显示友好时区名称而非偏移量
首先来说说你遇到的报错原因:你修改后的set_time_zone写法不对哦。Time.use_zone如果不带块调用的话,会返回对应的时区对象,你后面接了.strftime('%Z')之后,就相当于把原本要传递给use_zone的块给弄丢了,所以执行到yield的时候就会报错“no block given”。其实你最初的set_time_zone方法是完全正确的,问题根本不在这个控制器方法里,而是在时间的格式化环节。
正确的解决思路
around_action :set_time_zone的作用是让整个请求周期内的时间计算都切换到用户的时区,而要显示友好的时区名称,应该在视图层处理格式化,而不是修改控制器的时区设置方法。
具体可以这么做:
方法1:用Rails的本地化格式化(推荐)
在config/locales/en.yml(或者对应语言的本地化文件)里定义一个带时区名称的时间格式:
en: time: formats: friendly_with_zone: "%Y-%m-%d %H:%M %Z" friendly_with_zone_label: "%Y-%m-%d %H:%M %Z time"
然后在视图里调用Rails的本地化时间方法l(也就是localize的简写):
<!-- 显示成 2020-09-21 00:00 Melbourne --> <%= l(@your_model.your_time_field, format: :friendly_with_zone) %> <!-- 显示成 2020-09-21 00:00 Melbourne time --> <%= l(@your_model.your_time_field, format: :friendly_with_zone_label) %>
方法2:直接在视图里用strftime格式化
如果不想配置本地化文件,也可以直接在视图里写:
<%= @your_model.your_time_field.strftime("%Y-%m-%d %H:%M %Z") %> <!-- 或者带time后缀 --> <%= @your_model.your_time_field.strftime("%Y-%m-%d %H:%M %Z time") %>
为什么这样能生效?
因为你已经通过around_action :set_time_zone把当前请求的时区切换成了用户的时区(比如Melbourne),所以当你调用strftime('%Z')或者本地化格式化时,会自动使用这个时区的名称,而不是数字偏移量。只要你的current_user.time_zone存储的是ActiveSupport::TimeZone里的标准名称(比如"Melbourne"),%Z就会准确显示对应的时区名称。
内容的提问来源于stack exchange,提问作者stevec
相关产品推荐
相关产品推荐

