Ben*_*Ben 12 javascript jsf localization jsf-2
我正在JSF 2.0中编写一个webapp,它将Timestamps作为信息的一部分显示给用户.我希望用户看到本地化到其位置的时间戳(浏览器的语言环境).
到目前为止,无论我做什么,时间戳总是会显示为服务器的时区本地化.
我尝试使用以下方法获取语言环境:
Locale browserLocale = FacesContext.getCurrentInstance().getViewRoot().getLocale();
Run Code Online (Sandbox Code Playgroud)
要么
Locale browserLocale = FacesContext.getCurrentInstance().getExternalContext().getRequestLocale();
Run Code Online (Sandbox Code Playgroud)
两者都返回了服务器的语言环境.
然后我使用locale对象SimpleDateFormat来打印时间戳.
我使用正确的API吗?
我在某处读过你必须使用客户端代码(Javascript)来获取浏览器的时区.那是对的吗?你会怎么做?
谢谢'''提前.
UPDATE发现了这个(jsTimezoneDetect)JavaScript代码.但我仍然不确定如何将时区转换为Java Locale对象
Paw*_*yda 27
您可能应该使用内置格式标记而不是SimpleDateFormat.你的问题意味着你想向国际用户显示日期和时间,在这种情况下你应该真正使用用户的本地格式(他们往往会有所不同,你知道).
在时区的情况下,它与国际化和本地化无关,即在美国有几个不同的时区.您可以在此处使用两种方法:
将时区信息存储在用户配置文件中(如果有).这是最简单的方法,允许您使用内置<f:convertDateTime>标记.
从Web浏览器获取时区信息.您可以通过Ajax请求获取它,就像在Ben的示例中一样.从技术上讲,你也可以<f:convertDateTime>在这里使用标签.
您可以以一些常见的,与语言环境无关的(或者如果您愿意,也可以是不变的)格式发送UTC时间戳,在客户端解析它以使用Globalize创建JavaScript的日期对象和语言环境格式.
会有一些例子,但我先解释一下.
Locale browserLocale = FacesContext.getCurrentInstance().getViewRoot().getLocale();
Run Code Online (Sandbox Code Playgroud)
这将为您提供Web浏览器的区域设置(但不是时区,因为这不是与区域设置相关的).它实际上将读取HTTP Accept-Language标头的内容并选择最佳的区域设置.如果它不适合您,请确保您已正确设置支持的区域设置faces-config.xml.通过最好的Locale,我知道它将尝试使用用户最喜欢的Locale(如果你的应用程序支持),那么第二好等等.如果支持没有语言环境的,它会回退给你的应用程序的默认语言环境(同样,faces-config.xml如果此设置丢失必须有此设置)或服务器的默认语言环境(或至少我是这么认为的,它种很有意义).
Locale browserLocale = FacesContext.getCurrentInstance().getExternalContext().getRequestLocale();
Run Code Online (Sandbox Code Playgroud)
这个将为您提供Accept-Language标题中的顶级Locale.请检查您的Web浏览器的设置 - 它几乎没有办法为您提供服务器Locale,除非它们与您的Web浏览器完全相同.当且仅当JVM不支持Web浏览器的Locale时(这似乎不太可能),它可以为您提供服务器的默认值.
BTW.FacesContext.getCurrentInstance().getExternalContext().getRequestLocales()将为您提供迭代器,以便您可以手动遍历Accept-Language标头中的Locales列表.它只是让你知道,你可能不应该使用它(UIViewRoot真的够了).
现在,假设您有一些带有用户配置文件的bean以及为您提供时区的方法.此方法优于Ajax调用,因为可能会发生两个不同时区具有相同的UTC偏移但在不同日期切换夏令时(换句话说,某些时间戳将被错误打印).无论如何,在这种情况下,您可以像这样格式化时间戳(日期也来自某些bean):
<h:outputText value="#{someBean.timestamp}">
<f:convertDateTime type="both" dateStyle="default" timeStyle="default" timeZone="#{userProfile.timeZone}" />
</h:outputtext>
Run Code Online (Sandbox Code Playgroud)
现在让我解释一下这些属性:
默认情况下,标记将使用当前视图Locale,因此您不必担心此部分,尤其是在正确设置Locale支持的情况下.
将它与Ajax结合起来(参见Ben的回答)很容易(我认为).
我还提到你可以写出不变的日期,在客户端解析它们然后用Globalize格式化它们.假设你已经解析了日期(这取决于你想要使用的表示,所以我将跳过这部分),它可以这样做:
// you also have to assign the culture based on UIViewRoot locale and send it out with JavaScript
Globalize.culture(theLocale);
var formattedDateTime = Globalize.format(parsedDateTime, "f"); // this will use short date time format
Run Code Online (Sandbox Code Playgroud)
与Java不同,Globalize只有短("f")和长("F")日期和时间格式.所以我决定使用短的.
还请记住,Globalize文化是通过连字符而不是下划线分开的,因此您需要"fr-CA",而不是"fr_CA".
如果您想使用该方法并需要更具体的示例,请告诉我.
成功了.这是我做的:
向JSF添加了一个隐藏的输入字段,以便我可以将JavaScript值发送到服务器:
<h:form prependId="false">
<h:inputText id="timezone_holder" value="#{bean.timezone}" styleClass="hide">
<f:ajax listener="#{bean.timezoneChangedListener}"></f:ajax>
</h:inputText>
</h:form>
Run Code Online (Sandbox Code Playgroud)
使用上面的插件,我运行JavaScript了检索浏览器偏移量的代码.
$(document).ready(function() {
var timezone = jstz.determine_timezone();
$("#timezone_holder").val(timezone.offset());
$("#timezone_holder").change();
});
Run Code Online (Sandbox Code Playgroud)
当更改时区输入(从上面的javascript代码启动)时,我在eventListener中运行此代码:
String strFromJavaScript = getTimezone();
HttpServletRequest request = (HttpServletRequest) FacesContext.getCurrentInstance().getExternalContext()
.getRequest();
Locale browserLocale = request.getLocale();
TimeZone tz = TimeZone.getTimeZone("GMT" + strFromJavaScript);
// set time zone
SimpleDateFormat formatter = new SimpleDateFormat("MMM d, yyyy, HH:mm", browserLocale);
formatter.setTimeZone(tz);
Run Code Online (Sandbox Code Playgroud)
然后,每当我需要格式化日期时,我都使用上面创建的日期格式化程序.
| 归档时间: |
|
| 查看次数: |
29333 次 |
| 最近记录: |