使用 GWT 创建 ISO 8601 日期字符串

Create ISO 8601 date String with GWT

这是我的代码:

public static String getStringFormat(Date inputDate, String timeZone){
        String strFormat = null;
        try{
            final TimeZone computedTimeZone = TimeZone.createTimeZone(TimeZoneInfo.buildTimeZoneData(timeZone));
            DateTimeFormat dateTimeFormat = DateTimeFormat.getFormat(DateTimeFormat.PredefinedFormat.ISO_8601);
            strFormat = dateTimeFormat.format(inputDate, computedTimeZone);
            Date d = new Date(strFormat);
            strFormat = dateTimeFormat.format(d, TimeZone.createTimeZone(0));
            String[] s = strFormat.split("\+");
            strFormat = s[0];
        }catch(Exception e){
            Console.log(e.getMessage());
        }
        return strFormat;
    }

对于输入,new Date()Etc/GMT+3此函数returns为空。有什么问题吗?

错误

Error: NullPointerException: undefined
    at NBF_g$.QBF_g$ [as createError_0_g$] (NullPointerException.java:40)
    at NBF_g$.ub_g$ [as initializeBackingError_0_g$] (Throwable.java:113)
    at NBF_g$.bb_g$ (Throwable.java:61)
    at NBF_g$.Ib_g$ (Exception.java:25)
    at NBF_g$.avq_g$ (RuntimeException.java:25)
    at NBF_g$.gfs_g$ (JsException.java:34)
    at new NBF_g$ (NullPointerException.java:27)
    at new wou_g$ (JSONString.java:43)

方法 TimeZoneInfo.buildTimeZoneData(String tzJSON) 不接受区域的名称,但需要 JSON 包含该区域如何工作的详细信息的字符串。事实证明,浏览器不会向您提供所有时区如何工作的所有细节,因此您的应用程序必须已经准备好处理它们。

GWT 附带了所有时区(虽然它们目前有点过时,应该在下一个版本中更新),但是你必须告诉编译器你想要哪个时区,否则它会编译它们出去。所有可能的时区及其偏移量等的完整列表并不小,因此我鼓励您限制列表。

这些存储在常量接口中TimeZoneConstants。以下是您可能如何使用它:

TimeZoneConstants constants = GWT.create(TimeZoneConstants.class);

// This is the shorthand for TimeZone.createTimeZone(TimeZoneInfo.buildTimeZoneData(...))
TimeZone computedTimeZone = TimeZone.createTimeZone(constants.americaAdak());
//...

如果您想改用时区字符串,例如从服务器传递的时区字符串,您可以构建支持的可能时区的地图。请注意,尽管完整地图非常大(200KB 仅用于 "America/..." 组中的时区)。

computedTimeZone = TimeZone.createTimeZone(constants.americaAdak());
zones.put(computedTimeZone.getID(), computedTimeZone);
computedTimeZone = TimeZone.createTimeZone(constants.americaAnchorage());
zones.put(computedTimeZone.getID(), computedTimeZone);
computedTimeZone = TimeZone.createTimeZone(constants.americaAnguilla());
zones.put(computedTimeZone.getID(), computedTimeZone);
//...

然后您可以根据需要从地图上读出特定项目:

String tzName = Window.prompt("Enter a timezone name", "America/Chicago");

DateTimeFormat dateTimeFormat = DateTimeFormat.getFormat(DateTimeFormat.PredefinedFormat.ISO_8601);
String strFormat = dateTimeFormat.format(inputDate, zones.get(tzName));
//...

在你的评论中,你澄清了这个问题,你只需要处理偏移量,而不是完整的 TimeZone 字符串格式,即 Etc/GMT+3,意思是 "Offset of +3 hours from GMT"。这更容易处理 - 只需将 +3 解析为一个数字,然后使用 TimeZone.createTimeZone(int timeZoneOffsetInMinutes) 方法。这将 理解夏令时,但如果没有时区的全名或偏移量列表等,这是不可能的(这就是为什么 JSON好大)。

//TODO, implement parse(), don't forget about negative numbers
int offsetInHours = parse(timeZone);
TimeZone computedTimeZone = TimeZone.createTimeZone(60 * offsetInHours);
//...