我的应用程序从服务器获取有关过去事件的日期和时间的响应。但是,我的服务器在另一个时区,因此这里有些棘手。服务器时区为UTC +01:00
,而我的时区为UTC +03:00
。当我从服务器收到响应时,它们带有UTC +01:00
中的时间戳。首先,我尝试将日期作为String
接收,对其进行子字符串设置,设置其时区,然后以正确的时间格式和时区返回它。 (我删减了毫秒数的后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
->子字符串响应:2018-04-30T07:26:55.152+01:00
->最终格式:30-04-2018 09:26:55
但是,毫秒数并不总是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();
但这并没有改变任何东西。在第二种方法中我到底在做错什么?如果需要,我准备共享更多代码。
最佳答案
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
注意事项:
单个参数
OffsetDateTime.parse
在秒上接受1到9个小数,因此在解析之前,您无需以任何方式操作字符串。不要将您的UTC偏移量
UTC +03:00
用作时区。使用非洲/内罗毕,欧洲/莫斯科,亚洲/卡塔尔等时区或适当的时区。它更好地记录了您为什么做自己的工作,并且在偏移量发生更改的情况下,它可以面向未来。发生的次数比您想的要多。问题:我可以在Android上使用java.time吗?
是的,
java.time
在较新的Android设备上都能很好地工作。它至少需要Java 6。在Java 8和更高版本以及更新的Android设备(我知道API级别为26)上,内置了现代API。
在Java 6和7中,获取ThreeTen Backport,即新类的Backport(JSR 310的ThreeTen;请参见底部的链接)。
在较旧的Android上,请使用Android版本的ThreeTen Backport。叫做ThreeTenABP。并确保使用子包从
org.threeten.bp
导入日期和时间类。链接
Oracle tutorial: Date Time解释如何使用
java.time
。Java Specification Request (JSR) 310,其中首先描述
java.time
。ThreeTen Backport project,
java.time
到Java 6和7的反向端口(JSR-310的ThreeTen)。ThreeTenABP,ThreeTen Backport的Android版
Question: How to use ThreeTenABP in Android Project,具有非常详尽的说明。
关于android - Date()未捕获时区更改,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/50100721/