我的应用程序的用户是全球性的,但大多数用户没有用户配置文件来保存他们的首选时区信息,所以我想根据他们的语言设置进行尽力猜测。
例如,如果使用他们en_US选择的语言选择按钮,那么我将在纽约 TZ 中呈现日期,如果en_GB则在伦敦 TZ,如果de_DE,则在柏林 TZ 中渲染日期,依此类推。
我正在使用条纹框架和代码,例如...
<stripes:format value="${someDateValue}" formatType="datetime" formatPattern="medium"/>
。在很多地方,并且不想通过所有这些来更新到其他内容(自定义标签或其他)。我也宁愿避免JavaScript AJAX解决方案(主要是因为我认为它们也会导致我更新很多条纹:格式标签)。
Stripes 框架将使用默认的 DateFormat 作为请求语言环境,这都是有效的(随着日期格式的变化)。但所有时区都保留在服务器 TZ (GMT) 中。
所以我想要一些方法来为DateFormat.getDateInstance()和类似的默认DateFormat-s设置时区,然后再返回它们,但我不确定该怎么做。
到目前为止,我尝试的是将其设置在返回的 DateFormat 实例上,但当然它是按值返回的,因此它不起作用:
DateFormat df = DateFormat.getDateInstance(DateFormat.SHORT, new Locale("en_US"));
System.out.println(df.getTimeZone().getDisplayName()); // prints Greenwich Mean Time
df.setTimeZone(TimeZone.getTimeZone("America/New_York"));
System.out.println(df.getTimeZone().getDisplayName()); // prints Eastern Standard Time
df = DateFormat.getDateInstance(DateFormat.SHORT, new Locale("en_US"));
System.out.println(df.getTimeZone().getDisplayName()); // prints Greenwich Mean Time again, although if this approach were successful it would print Eastern Standard Time
任何想法如何最好地解决这个问题?
我的计划 B 将是一个自定义的 Stripes 标签,然后在我格式化日期的许多地方进行更改,但在走这条路线之前,我想检查一下我没有错过一些简单的解决方案(要么是 Stripes 钩子,要么是在更基本的 Java 语言环境处理级别上更改它的方法)。
用户的时区偏移量不会在 HTTP 标头上携带。通常有两种方法:
- 使用时区设置创建用户配置文件,允许用户对其进行设置
- 使用 javascript 的 Date 对象
getTimezoneOffset()
自动检测时区,并使用 ajax 将其发布到服务器。以这个为例,在网络上搜索。
或者你可以两者的组合
以这种方式实现它,它似乎工作正常:
- 自定义条纹格式化程序
- 工厂,它添加了自定义日期格式化程序
- DateFormatter 从会话中获取时区偏移量,从 ThreadLocal 获取会话,并使用它来调整用于呈现日期的 DateFormat
- 拦截器将会话的时区偏移量存储到 ThreadLocal 中
- 页面上的 JQuery AJAX 调用,将 JavaScript 获得的时区偏移量提交到后端,并将其存储在会话中