Date()不会捕获时区更改

时间:2018-04-30 12:37:59

标签: android date datetime timezone

我的应用程序从我的服务器获得过去事件的日期和时间的响应。但是,我的服务器位于另一个时区,这里的事情有点棘手。服务器时区为UTC +01:00,而我的时区为UTC +03:00。当我收到来自服务器的回复时,它们的时间戳为UTC +01:00。首先,我尝试将日期作为String接收,子串,设置其时区,然后以适当的时间格式和区域返回。 (我剪掉了milisec的最后4位数,因为DateFormat无效。)

private String getFormattedDate(String date) {
    DateFormat serverDateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSXXX");
    DateFormat finalDateFormat = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss");
    Calendar calendar = Calendar.getInstance();
    TimeZone timeZone = calendar.getTimeZone();
    serverDateFormat.setTimeZone(timeZone);
    String cutoutDate = date.substring(0,23);
    String cutoutZone = date.substring(27, date.length());
    String dateInProperFormat = cutoutDate + cutoutZone;
    Date finalDate = serverDateFormat.parse(dateInProperFormat);
    return finalDateFormat.format(finalDate);
}

这会正确读取并转换所有内容:

  

服务器响应:2018-04-30T07:26:55.1524511+01:00 - > Substringed响应:2018-04-30T07:26:55.152+01:00 - >最终格式:30-04-2018 09:26:55

然而,milisec并不总是7,所以当发生这种情况时,我得到Unparsable date错误。这使我的日期不是String,而是Date。这将代码仅缩减为5行:

private String getFormattedDate(Date date) {
    SimpleDateFormat finalDateFormat = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss");
    Calendar calendar = Calendar.getInstance();
    TimeZone timeZone = calendar.getTimeZone();
    finalDateFormat.setTimeZone(timeZone);
    return finalDateFormat.format(date);
}

但现在,时间总是在UTC +01:00。我试着像这样得到时区:

TimeZone timeZone = TimeZone.getDefault();

但这并没有改变任何事情。在我的第二种方法中,我究竟做错了什么?如果需要,我准备分享更多我的代码。

2 个答案:

答案 0 :(得分:2)

java.time

private static DateTimeFormatter finalDateTimeFormatter
        = DateTimeFormatter.ofPattern("dd-MM-uuuu HH:mm:ss");
private static ZoneId zone = ZoneId.of("Europe/Istanbul");

private static String getFormattedDate(String dateTime) {
    return OffsetDateTime.parse(dateTime)
            .atZoneSameInstant(zone)
            .format(finalDateTimeFormatter);
}

让我们用您问题中的示例服务器响应进行尝试:

    System.out.println(getFormattedDate("2018-04-30T07:26:55.1524511+01:00"));

输出所需的:

  

30-04-2018 09:26:55

注意事项:

  • one-arg OffsetDateTime.parse在秒数上接受1到9位小数,因此在解析之前不需要以任何方式操纵字符串。
  • 请勿将UTC +03:00的UTC偏移量用作时区。使用非洲/内罗毕,欧洲/莫斯科,亚洲/卡塔尔等时区或适当的时区。它更好地记录了你正在做你正在做的事情的原因,并且在偏移被改变的情况下它是面向未来的。这种情况比你想象的更频繁。

问题:我可以在Android上使用java.time吗?

是的,java.time适用于较旧和较新的Android设备。它只需要至少Java 6

  • 在Java 8及更高版本和更新的Android设备上(来自API级别26,我被告知)现代API内置。
  • 在Java 6和7中获取ThreeTen Backport,新类的后端端口(适用于JSR 310的ThreeTen;请参阅底部的链接)。
  • On(较旧)Android使用Android版的ThreeTen Backport。它被称为ThreeTenABP。并确保使用子包从org.threeten.bp导入日期和时间类。

链接

答案 1 :(得分:1)

尝试以下代码。这是一种解决方案

   public String getFormattedDate(String date) {
    DateFormat serverDateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSXXX");
    DateFormat finalDateFormat = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss");
    Calendar calendar = Calendar.getInstance();
    TimeZone timeZone = calendar.getTimeZone();
    serverDateFormat.setTimeZone(timeZone);
    String[] splitTime=date.split("\\+");
    String cutoutDate="";
    if (splitTime[0].length()>23)cutoutDate = date.substring(0,23);
    else cutoutDate=splitTime[0];
    String cutoutZone = "+"+splitTime[1];
    String dateInProperFormat = cutoutDate + cutoutZone;
    Date finalDate = null;
    try {
        finalDate = serverDateFormat.parse(dateInProperFormat);
    } catch (ParseException e) {
        e.printStackTrace();
    }
    return finalDateFormat.format(finalDate);
}