[英]Best way to handle user specific date/timezone conversion with Spring MVC + Freemarker
我想显示使用用户时区格式化的存储日期(时区为UTC) (可能因用户而异,并存储在配置文件中)。
我提出的解决方案是以下一个, 我想知道这是否是最好的方法 ,或者是否有另一个,可能更简单的解决方案。
时区设置为UTC:
-Duser.timezone=UTC
控制器,Freemarker-Template,HandlerInterceptor:
控制器:
@Controller
@RequestMapping("/test")
public class TestController {
@RequestMapping
public String dateTest(Model model){
final Date date = new Date();
model.addAttribute("formattedDate", new SimpleDateFormat("hh:mm:ss").format(date));
model.addAttribute("date", date);
return "test";
}
}
Freemarker的,模板:
<#setting time_zone="${currentTimeZone}">
UTC Time: ${formattedDate}<br/>
Localized time for timezone <i>${currentTimeZone}</i>: ${date?time}
HandlerInterceptor接口:
public class TimezoneHandlerInterceptor extends HandlerInterceptorAdapter{
@Override
public void postHandle(HttpServletRequest request,
HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
//Only for testing, in production something like:
//final String currentUserTimezone = userService.getCurrentUser().getTimezoneId();
final String currentUserTimezone = "Europe/Berlin";
modelAndView.addObject("currentTimeZone", currentUserTimezone);
}
}
输出:
UTC Time: 08:03:53
Localized time for timezone Europe/Berlin: 09:03:53
那么是否有更标准或甚至开箱即用的方法来实现相同的结果? 谢谢你的帮助。
由于您打印两次相同的日期,只是以不同的方式呈现(不同的时区),它可能只是一个演示文稿(MVC View)问题,因此它不应该在模型中解决。 相反,你可以做这样的事情是模板:
<#import "/lib/utils.ftl" as u>
...
UTC Time: ${u.utcTime(date)}<br/>
Localized time for timezone <i>${currentTimeZone}</i>: ${date?time}
utcTime
应该在utils.ftl
中定义,如<#assign u = "com.something.freemarker.UtcTimeMethod"?new()>
,其中com.something.freemarker.UtcTimeMethod
是TemplateMethodModelEx
实现。 还有其他方法可以做到这一点,比如u
可能是FreeMarker配置中定义的共享变量等等。重点是,你需要打印UTC时间不会影响模型。
从<#setting time_zone=currentTimeZone>
部分开始(注意那里不需要${...}
),当然它取决于Web应用程序框架,但是如果你设置时区(如在调用模板之前,基于访问者的语言环境)。 FreeMarker通过Template.createProcessingEnvironment
(参见JavaDoc)支持,但Spring MVC可能不支持。
此外, Date
对象始终以UTC格式存储日期时间。 您无需使用-D
为其设置时区。
不,那看起来不错。 我建议您不要依赖user.timezone进行字符串格式化,因为最终有人会使用错误的时区启动您的webapp; 相反,你可以使用
DateFormat formatter = new SimpleDateFormat("hh:mm:ss");
formatter.setTimeZone(TimeZone.getTimeZone("UTC"));
顺便说一下,你见过CodeReview吗? 这个问题同样适用于这两个网站,因为这样你就可以用它来表达。
您可以像这样覆盖FreeMarkerView
public static class YourFreemarkerView extends FreeMarkerView {
@Override
protected void processTemplate(Template template, SimpleHash model, HttpServletResponse response)
throws IOException, TemplateException {
HttpRequestHashModel httpRequestHashModel = (HttpRequestHashModel)model.get(FreemarkerServlet.KEY_REQUEST);
Environment env = template.createProcessingEnvironment(model, response.getWriter(), null);
env.setLocale(RequestContextUtils.getLocale(httpRequestHashModel.getRequest()));
env.setTimeZone(RequestContextUtils.getTimeZone(httpRequestHashModel.getRequest()));
env.process();
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.