在JSF中 - 获取客户端的区域设置(在浏览器的时区中显示时间) [英] In JSF - Getting the Client's Locale (To Display time in browser's timezone)

查看:92
本文介绍了在JSF中 - 获取客户端的区域设置(在浏览器的时区中显示时间)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在JSF 2.0中编写一个webapp,它将Timestamps作为信息的一部分显示给用户。
我希望用户看到本地化到他们位置的时间戳(浏览器的语言环境)。

I'm writing a webapp in JSF 2.0 that displays Timestamps as part of the information to the user. I would like the user to see the timestamps localized to their location (browser's locale).

到目前为止,无论我做了什么,时间戳总是会出现本地化到服务器的时区。

So far, whatever I did, the timestamps would always appear localized to the timezone of the server.

我尝试使用这些方法获取语言环境:

I tried getting the locale with these methods:

Locale browserLocale = FacesContext.getCurrentInstance().getViewRoot().getLocale();

Locale browserLocale = FacesContext.getCurrentInstance().getExternalContext().getRequestLocale();

两者都返回了服务器的区域设置。

Both returned the server's locale.

然后我使用带有 SimpleDateFormat 的语言环境对象来打印时间戳。

I then use the locale object with SimpleDateFormat to print timestamps.

我使用的是正确的API吗?

我在某处读过你必须使用客户端代码(Javascript)来获取浏览器的时区。那是对的吗?你会怎么做?

Am I using the correct API?
I've read somewhere that you have to use client side code (Javascript) to get the browser's timezone. Is that correct? How would you do that?

感谢'''提前。

更新找到这个(jsTimezoneDetect)JavaScript代码。但我仍然不确定如何将时区转换为Java 区域设置对象

UPDATE found this (jsTimezoneDetect) JavaScript code. But I'm still not sure how to translate the timezone to a Java Locale Object

推荐答案

您可能应该使用内置格式标记而不是SimpleDateFormat。你的问题意味着你想向国际用户显示日期和时间,在这种情况下你应该真正使用用户的本地格式(它们往往不同,你知道)。

You probably should use built-in formatting tag instead of SimpleDateFormat. Your question implies that you want to show date and time to International user, and in this case you should really use user's local format (they tend to differ, you know).

在时区的情况下,它与国际化和本地化无关,即在美国有几个不同的时区。您可以在此处使用两种方法:

In case of time zone, it has nothing to do with Internationalization and Localization, i.e. there are several different time zones in USA. There are two approaches you can use here:


  1. 将时区信息存储在用户配置文件中(如果有的话)。这是最简单的方法,允许您使用内置的< f:convertDateTime> 标记。

从Web浏览器获取时区信息。您可以通过Ajax请求获取它,就像在Ben的示例中一样。从技术上讲,你也可以在这里使用< f:convertDateTime> 标记。

Get time zone information from web browser. You can get it via Ajax request just like in Ben's example. Technically you can also use <f:convertDateTime> tag here.

你可以发送时间戳在UTC中的一些常见的,与语言环境无关的(或者如果你愿意的话不变)格式,在客户端解析它以使用全球化

You can send the timestamps in UTC in some common, locale-independent (or invariant if you prefer) format, parse it on the client side to create JavaScript's date object and format for locale with Globalize.

接下来会有一些例子,但我先解释一下。

Some examples will follow but let me explain something first.

Locale browserLocale = FacesContext.getCurrentInstance().getViewRoot().getLocale();

为您提供网络浏览器的区域设置(但不是时区,因为这是 区域设置相关的)。它实际上将读取HTTP Accept-Language标头的内容并选择最佳的区域设置。如果它不适合您,请确保您在 faces-config.xml 中正确设置了支持的语言环境。通过最好的Locale,我知道它会尝试使用用户最喜欢的Locale(如果你的应用程序支持),那么第二好等等。如果不支持任何语言环境,它将回退到应用程序的默认语言环境(再次, faces-config.xml 必须具有此设置)或服务器的默认语言环境如果缺少此设置(或者至少我认为这样,那就有意义了。)

This will give you web browser's locale (but not time zone, since this is not locale related). It will actually read the contents of HTTP Accept-Language header and choose the best possible locale. If it is not working for you, please make sure that you have correctly set supported locales in your faces-config.xml. By best possible Locale, I understand that it will try to use user's most preferred Locale (if that's supported by your application), then second best and so on. If none of the Locales is supported, it will fall-back to your application's default Locales (again, faces-config.xml has to have this setting) or to server's default Locale if this setting is missing (or at least I think so, it kind of makes sense).

Locale browserLocale = FacesContext.getCurrentInstance().getExternalContext().getRequestLocale();

这个将为您提供Accept-Language标题中的顶级语言环境。请检查您的网络浏览器的设置 - 它几乎无法为您提供服务器区域设置,除非它们与您的网络浏览器完全相同。当且仅当JVM不支持Web浏览器的Locale时(这似乎不太可能),它可以为您提供服务器的默认值。

This one will give you the top Locale from Accept-Language header. Please check your web browser's settings - there is almost no way for it to give you the server Locale, unless they are exactly the same as your web browser's. It can give you server's defaults if and only if, none of the web browser's Locale is supported by JVM (which seems a bit unlikely).

BTW。 FacesContext.getCurrentInstance()。getExternalContext()。getRequestLocales()将为您提供迭代器,以便您可以手动迭代Accept-Language标头中的Locales列表。它只是让你知道,你可能不应该使用它(UIViewRoot真的够了)。

BTW. FacesContext.getCurrentInstance().getExternalContext().getRequestLocales() will give you the Iterator so you can manually iterate through the list of Locales in Accept-Language header. It is just to let you know, you probably should not use it (UIViewRoot is really enough).

现在,假设你有一些带有用户配置文件和方法的bean这会给你时区。此方法优于Ajax调用,因为可能会发生两个不同时区具有相同的UTC偏移但在不同日期切换夏令时(换句话说,某些时间戳将被错误打印)。无论如何,在这种情况下,您可以格式化您的时间戳(日期也来自某个bean):

Now, suppose you have some bean with the user profile and the method which will give you the time zone. This method is better than Ajax call, in the sense that it might happen that two different time zones have the same UTC offset but switch Daylight Saving Time on different date (in other words some timestamps would be printed incorrectly). Anyway, in case like this, you can format your time-stamp like this (date also come from some bean):

<h:outputText value="#{someBean.timestamp}">
  <f:convertDateTime type="both" dateStyle="default" timeStyle="default" timeZone="#{userProfile.timeZone}" />
</h:outputtext>

现在让我解释一下这些属性:

Now let me explain the attributes:


  • 类型 - 要显示的内容,均表示日期和时间

  • dateStyle - 日期样式(短,中,长,完整,默认)。你应该在这里使用默认值,因为这将为每个Locale使用最合适的格式

  • timeStyle - 类似于日期样式但是时间部分

  • timeZone - 采用UTC偏移(因此您不需要转换任何东西)或时区名称(即America / Los_Angeles)。

  • type - what to show, both means date and time
  • dateStyle - style of date (out of short, medium, long, full, default). You should really use default here as this will use the most proper format for each Locale
  • timeStyle - similar to date style but for time part
  • timeZone - takes either an UTC offset (so you don't need to convert anything) or time zone name (i.e. America/Los_Angeles).

默认情况下,标记将使用当前视图Locale,因此您不必担心此部分,尤其是在正确设置Locale支持的情况下。

The tag will use current view Locale by default, so you do not have to worry about this part, especially if you set up Locale support correctly.

将其与Ajax结合使用(参见Ben的回答)很容易(我认为)。

Combining it with Ajax (see Ben's answer) would be easy enough (I think).

我还提到你可以写出不变的日期,在客户端解析它们然后格式化他们与Globalize。假设你已经解析了日期(这取决于你想要使用的表示,所以我将跳过这部分),它可以这样做:

I also mentioned that you can write out invariant dates, parse them on the client-side and then format them with Globalize. Assuming that you have parsed date already (it depends on the representation you want to use, so I will skip this part), it could be done like that:

// 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

与Java不同,Globalize只有短(f)和长(F)日期和时间格式。所以我决定使用短的。

请记住,Globalize文化是通过连字符而不是下划线分开的,所以你需要fr-CA,而不是fr_CA。 >
如果您想使用该方法并需要更具体的示例,请告诉我。

Unlike Java, Globalize have only short ("f") and long ("F") date and time formats. So I decided on using short one.
Please also keep in mind, that Globalize cultures are separated via hyphen, not underscore, so you need "fr-CA", not "fr_CA" for example.
Please let me know if you want to use that method and need more concrete example.

这篇关于在JSF中 - 获取客户端的区域设置(在浏览器的时区中显示时间)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆