解析和检索与日期时间的时区偏移量 [英] Parse and retrieve timezone offset from date-time

查看:118
本文介绍了解析和检索与日期时间的时区偏移量的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

日期格式: yyyy-MM-dd'T'HH:mm:ss.SSSZ

输入日期: 2017-09-18T03:08:20.888 + 0200

问题:我需要从输入的String中检索时区偏移量并在其中打印解析的日期这个时区。换句话说,我需要输出与输入相同。

Problem: I need retrieve timezone offset from the input String and print the parsed date in this timezone. In other words, I need output to be the same as the input.

SimpleDateFormat 成功解析输入日期并返回 java.util.Date 对象。 我们知道,日期没有时区字段。 SimpleDateFormat 将解析的日期转换为其时区,默认情况下为系统时区。当我打印此日期时,它将在系统时区中打印。

SimpleDateFormat parses input date successfully and returns java.util.Date object. As we know, Date does not have timezone field. SimpleDateFormat converts parsed date to its timezone, which is, by default, system timezone. When I print this date, it is printed in System timezone.

简单演示

private static void runDemoTask() throws ParseException {
    final String dateTimeTimezoneFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZ";
    final SimpleDateFormat inputSdf = new SimpleDateFormat(dateTimeTimezoneFormat);
    final String inputDate = "2017-09-18T01:08:20.888+0200";

    Date parsedDate = inputSdf.parse(inputDate);

    final SimpleDateFormat outputSdf = new SimpleDateFormat(dateTimeTimezoneFormat);
    //outputSdf.setTimeZone("X_TIMEZONE_WHICH_I_NEED");
    String output = outputSdf.format(parsedDate);
    System.out.println(output);
}

输出

Mon Sep 18 00:08:20 GMT+01:00 2017

注意,输出日期具有系统时区,与输入字符串不同。

Note, output date has system timezone, which is different from input string.

注意,我不会使用 java.time Joda Time 和其他库,因为我需要支持现有代码。

Note, I will not use java.time, Joda Time and other libraries because I need to support existing code.

可能令人不快的解决方案

Possible unpleasant solution

我尝试使用正则表达式来检索符号和偏移量。

I tried to use regular expression to retrieve sign and offset.

private static  String parseTimeZone(String input) {
    final int singGroup = 1;
    final int offsetGroup = 2;
    final String timezonePatternStr = "([+-])(\\d{4})$";
    final Pattern timezonePattern = Pattern.compile(timezonePatternStr);

    Matcher matcher = timezonePattern.matcher(input);
    if (matcher.find()) {
        String sign = matcher.group(singGroup);
        String offset = matcher.group(offsetGroup);
        System.out.println(sign + " " + offset);
    }

    return "";
} 

它会打印

+ 0200


推荐答案

SimpleDateFormat 扩展了 DateFormat ,因此在内部使用 Calendar 。解析日历更新的日期时,可以在解析后 从中获取时区:

SimpleDateFormat extends DateFormat and thus internally uses a Calendar. When parsing the date that calendar is being updated so you can get the timezone from it after parsing:

//use the timezone of the internally stored calendar
outputSdf.setTimeZone( inputSdf.getTimezone() );

显示为什么 DateFormat 不是线程安全的。

That also shows why DateFormat is not threadsafe.

编辑:

内部日历的时区似乎没有未更新,但ZONE_OFFSET字段已更新。因此,您可以执行以下操作:

It seems the internal calendar's timezone isn't updated but the ZONE_OFFSET field is. Hence you could do something like this:

int zoneOffset = inputSdf.getCalendar().get( Calendar.ZONE_OFFSET );
//length check etc. left for you
String matchingZoneId = TimeZone.getAvailableIDs( zoneOffset )[0];
outputSdf.setTimeZone( TimeZone.getTimeZone( matchingZoneId ) );

请注意,您不能只设置输出格式的区域偏移量,因为它不会更新

Note that you can't just set the zone offset of the output format since that won't update the timezone reference which is used when formatting.

如您所见,这种方式看起来有点 hacky,因此您应该认真考虑是否确实需要时区。在大多数情况下,无论如何,您都可以通过其他方式定义输出时区,例如通过获取用户的位置,输入信息等等。

As you can see doing it this way looks a little "hacky" and thus you should think hard on whether you really need the timezone. In most cases you'd define the output timezone in a different way anyways, e.g. by getting the user's location, input, etc.

这篇关于解析和检索与日期时间的时区偏移量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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