在GWT中显示本地时间

时间:2013-11-25 16:14:06

标签: java date datetime gwt

我有一个应用,我需要在当地时间显示事件,在用户的时区,但是在事件发生的时区。我正在以ISO-8601格式获得时间,包括时区偏移。时区不是恒定的,我正在显示的每个事件可以有不同的时间(它们代表航班起飞和到达时间)。

例如,我有“2014-02-05T09:00-08:00”,我想将其显示为“上午9:00”。

我的第一个天真的代码看起来像这样:

private static final DateTimeFormat ISO_TIME_FORMAT =
    DateTimeFormat.getFormat("yyyy-MM-dd'T'HH:mmZZZ");
private static final DateTimeFormat TIME_OF_DAY_FORMAT =
    DateTimeFormat.getFormat(PredefinedFormat.HOUR_MINUTE);

public static String formatTimeOfDay(String iso8601Time) {
  return TIME_OF_DAY_FORMAT.format(QPX_TIME_FORMAT.parse(iso8601Time));
}

但是这会显示用户的时区中的时间,在我的情况下是“早上6点”,因为我在美国ET。

看看GWT参考,看起来我需要根据ISO-8601日期获得正确的TimeZone,但我不清楚如何做到这一点。我试过了

public static String formatTimeOfDay(String isoTime) {
  Date date = QPX_TIME_FORMAT.parse(isoTime);
  String tzoneStr = qpxTime.substring(16);
  TimeZone tzone = TimeZone.createTimeZone(tzoneStr);
  return TIME_OF_DAY_FORMAT.format(date, tzone);
}

但是我收到“解析JSON时出错:SyntaxError:意外的数字-05:00”异常。看起来我应该能够从输入字符串中解析Date和TimeZone,因为它具有编码在其中的所有信息。

此时,通过isoTime.substring(11,16)直接从输入时间提取时间似乎是最容易的事情。这意味着我必须编写一个自定义解析器,将24小时转换为上午/下午格式,但这可能是最简单的。

任何其他建议?

1 个答案:

答案 0 :(得分:0)

在GWT 2.5.1中,TimeZone.createTimeZone获得TimeZoneInfo的JSON版本(可在TimeZoneConstants.properties中找到此JSON版本)。为了从“-08:00”区域偏移创建JSON版本,您必须自己解析它。但即使使用合适的TimeZone,它仍然不适合我:

DateTimeFormat ISO_TIME_FORMAT = DateTimeFormat.getFormat ("yyyy-MM-dd'T'HH:mmZZZ");
DateTimeFormat TIME_OF_DAY_FORMAT = DateTimeFormat.getFormat (PredefinedFormat.HOUR_MINUTE);
String qpxTime = "2014-02-05T09:00-08:00";
RootPanel.get().add (new Label ("dts: " + qpxTime));
Date dt = ISO_TIME_FORMAT.parse (qpxTime);
RootPanel.get().add (new Label ("dt: " + dt.toString()));
String tzs = qpxTime.substring (16);
RootPanel.get().add (new Label ("tzs: " + tzs));
int tzh = Integer.parseInt (qpxTime.substring (16, qpxTime.indexOf (':', 16)));
RootPanel.get().add (new Label ("tzh: " + tzh));
// cf. http://www.docjar.com/html/api/com/google/gwt/i18n/client/TimeZoneInfo.java.html
// cf. http://code.google.com/p/google-web-toolkit/source/browse/trunk/user/src/com/google/gwt/i18n/client/constants/TimeZoneConstants.properties
TimeZone tz = TimeZone.createTimeZone ("{\"id\": \"fromOffset\", \"std_offset\": " + (tzh * 60) + ", \"transitions\": [], \"names\": \"\"}");
RootPanel.get().add (new Label ("tz: " + tz));
RootPanel.get().add (new Label ("format plain: " + TIME_OF_DAY_FORMAT.format (dt)));  // 9:00 AM
// cf. http://code.google.com/p/google-web-toolkit/source/browse/trunk/user/src/com/google/gwt/i18n/shared/DateTimeFormat.java
RootPanel.get().add (new Label ("format tz: " + TIME_OF_DAY_FORMAT.format (dt, tz)));  // 9:00 AM
RootPanel.get().add (new Label ("tz offset: " + tz.getStandardOffset()));  // 480
RootPanel.get().add (new Label ("format custom: " + TIME_OF_DAY_FORMAT.format (new Date (dt.getTime() + 60L * 60L * 1000L * tzh))));  // 1:00 PM

如果所有时间都包含区域偏移,则可以手动将其应用于时间。但是,如果您想要解析标准区域名称,那么在我看来,您要么解析客户端上的TimeZoneConstants.properties,要么将时间转换卸载到服务器。