将 UTC 日期转换为 Android 中的本地时间?
Convert UTC date to Local Time in Android?
我有一个日期 String
,类似于 2017-09-16T05:06:18.157
,我想将其转换为当地时间 (IST)。在印度标准时间大约是 2017-09-16 10:36:18
.
使用 Joda-Time,我尝试将其转换为本地,但我无法做到。
下面是我的代码:
private String getConvertDate(String date_server) {
DateTimeFormatter inputFormatter = DateTimeFormat
.forPattern("yyyy-MM-dd'T'HH:mm:ss.SSS")
.withLocale(Locale.US);
DateTime parsed = inputFormatter.parseDateTime(date_server);
DateTimeFormatter outputFormatter = DateTimeFormat
.forPattern("yyyy-MM-dd HH:mm:ss")
.withLocale(Locale.US)
.withZone(DateTimeZone.getDefault());
return outputFormatter.print(parsed);
}
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
TimeZone utcZone = TimeZone.getTimeZone("UTC");
simpleDateFormat.setTimeZone(utcZone);
Date myDate =simpleDateFormat.parse(rawQuestion.getString("Asia/Kolkata"));
simpleDateFormat.setTimeZone(TimeZone.getDefault());
String formattedDate = simpleDateFormat.format(myDate);
试试这个代码:
String serverdateFormat = "yyyy-MM-dd'T'HH:mm:ss'Z'";
public String convertServerDateToUserTimeZone(String serverDate) {
String ourdate;
try {
SimpleDateFormat formatter = new SimpleDateFormat(serverdateFormat, Locale.UK);
formatter.setTimeZone(TimeZone.getTimeZone("UTC"));
Date value = formatter.parse(serverDate);
TimeZone timeZone = TimeZone.getTimeZone("Asia/Kolkata");
SimpleDateFormat dateFormatter = new SimpleDateFormat(serverdateFormat, Locale.UK); //this format changeable
dateFormatter.setTimeZone(timeZone);
ourdate = dateFormatter.format(value);
//Log.d("OurDate", OurDate);
} catch (Exception e) {
ourdate = "0000-00-00 00:00:00";
}
return ourdate;
}
很好,您找到了 SimpleDateFormat
的解决方案。我只想添加更多关于它的见解(主要是因为旧的 classes(Date
、Calendar
和 SimpleDateFormat
)有 lots of problems and design issues,他们正在被新的 APIs 取代)。
输入String
(2017-09-16T05:06:18.157
)仅包含日期(year/month/day)和时间(hour/minute/second/millisecond),但没有时区信息。因此,当调用 parseDateTime
时,Joda-Time 只是假定它处于 JVM 默认时区。
如果你知道输入是UTC,但输入本身没有关于它的信息,你必须告诉它。一种方法是在格式化程序中设置:
// set the formatter to UTC
DateTimeFormatter inputFormatter = DateTimeFormat.forPattern("yyyy-MM-dd'T'HH:mm:ss.SSS")
.withZone(DateTimeZone.UTC);
// DateTime will be in UTC
DateTime parsed = inputFormatter.parseDateTime("2017-09-16T05:06:18.157");
另一种方法是首先将输入解析为 org.joda.time.LocalDateTime
(表示没有时区的日期和时间的 class),然后将其转换为 DateTime
协调世界时:
// parse to LocalDateTime
DateTime = parsed = LocalDateTime.parse("2017-09-16T05:06:18.157")
// convert to a DateTime in UTC
.toDateTime(DateTimeZone.UTC);
两者产生相同的 DateTime
,对应于 UTC 2017-09-16T05:06:18.157Z
。
要将其格式化为 "IST timezone"(这实际上不是时区 - 更多内容见下文),您还可以在格式化程序中设置时区:
// convert to Asia/Kolkata
DateTimeFormatter outputFormatter = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss")
.withZone(DateTimeZone.forID("Asia/Kolkata"));
System.out.println(outputFormatter.print(parsed));
或者您可以将 DateTime
转换为另一个时区,使用 withZone()
method:
DateTimeFormatter outputFormatter = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss");
// convert to Asia/Kolkata
System.out.println(outputFormatter.print(parsed.withZone(DateTimeZone.forID("Asia/Kolkata"))));
两者都将打印:
2017-09-16 10:36:18
在您的代码中,您使用的是 DateTimeZone.getDefault()
,它获取 JVM 默认时区(有一些 ). But the default timezone ,因此最好指定您要使用的时区。
此外,请记住像 IST 这样的短名称不是真正的时区。始终喜欢使用 IANA timezones names(始终采用 Region/City
格式,如 Asia/Kolkata
或 Europe/Berlin
)。
避免使用 3 个字母的缩写(如 IST
或 PST
),因为它们 ambiguous and not standard. Just check in this list IST 可以是 "India Standard Time"、"Israel Standard Time" 和"Irish Standard Time".
您可以通过调用 DateTimeZone.getAvailableIDs()
.
获取可用时区列表(并选择最适合您的系统的时区)
Java 新 Date/Time API
Joda-Time 处于维护模式,正在被新的 APIs 取代,所以我不建议用它开始一个新项目。即使在 joda's website 它说:"Note that Joda-Time is considered to be a largely “finished” project. No major enhancements are planned. If using Java SE 8, please migrate to java.time (JSR-310).".
如果您不能(或不想)从 Joda-Time 迁移到新的 API,您可以忽略此部分。
在 Android 中你可以使用 ThreeTen Backport, a great backport for Java 8's new date/time classes. To make it work, you'll also need the ThreeTenABP (more on how to use it ).
这个新的 API 每个情况都有 lots of different date/time types。
首先,您可以将输入解析为 org.threeten.bp.LocalDateTime
,然后我使用 org.threeten.bp.ZoneOffset
将其转换为 UTC,结果为 org.threeten.bp.OffsetDateTime
.
然后,我使用 org.threeten.bp.ZoneId
将其转换为另一个时区,并使用 org.threeten.bp.format.DateTimeFormatter
对其进行格式化(这基本上是 的建议 - 只是为了展示如何很简单,因为没有什么不同可做):
// parse to LocalDateTime
OffsetDateTime parsed = LocalDateTime.parse("2017-09-16T05:06:18.157")
// convert to UTC
.atOffset(ZoneOffset.UTC);
// convert to Asia/Kolkata
ZoneId zone = ZoneId.of("Asia/Kolkata");
DateTimeFormatter outputFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
System.out.println(outputFormatter.format(parsed.atZoneSameInstant(zone)));
输出为:
2017-09-16 10:36:18
我有一个日期 String
,类似于 2017-09-16T05:06:18.157
,我想将其转换为当地时间 (IST)。在印度标准时间大约是 2017-09-16 10:36:18
.
使用 Joda-Time,我尝试将其转换为本地,但我无法做到。
下面是我的代码:
private String getConvertDate(String date_server) {
DateTimeFormatter inputFormatter = DateTimeFormat
.forPattern("yyyy-MM-dd'T'HH:mm:ss.SSS")
.withLocale(Locale.US);
DateTime parsed = inputFormatter.parseDateTime(date_server);
DateTimeFormatter outputFormatter = DateTimeFormat
.forPattern("yyyy-MM-dd HH:mm:ss")
.withLocale(Locale.US)
.withZone(DateTimeZone.getDefault());
return outputFormatter.print(parsed);
}
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
TimeZone utcZone = TimeZone.getTimeZone("UTC");
simpleDateFormat.setTimeZone(utcZone);
Date myDate =simpleDateFormat.parse(rawQuestion.getString("Asia/Kolkata"));
simpleDateFormat.setTimeZone(TimeZone.getDefault());
String formattedDate = simpleDateFormat.format(myDate);
试试这个代码:
String serverdateFormat = "yyyy-MM-dd'T'HH:mm:ss'Z'";
public String convertServerDateToUserTimeZone(String serverDate) {
String ourdate;
try {
SimpleDateFormat formatter = new SimpleDateFormat(serverdateFormat, Locale.UK);
formatter.setTimeZone(TimeZone.getTimeZone("UTC"));
Date value = formatter.parse(serverDate);
TimeZone timeZone = TimeZone.getTimeZone("Asia/Kolkata");
SimpleDateFormat dateFormatter = new SimpleDateFormat(serverdateFormat, Locale.UK); //this format changeable
dateFormatter.setTimeZone(timeZone);
ourdate = dateFormatter.format(value);
//Log.d("OurDate", OurDate);
} catch (Exception e) {
ourdate = "0000-00-00 00:00:00";
}
return ourdate;
}
很好,您找到了 SimpleDateFormat
的解决方案。我只想添加更多关于它的见解(主要是因为旧的 classes(Date
、Calendar
和 SimpleDateFormat
)有 lots of problems and design issues,他们正在被新的 APIs 取代)。
输入String
(2017-09-16T05:06:18.157
)仅包含日期(year/month/day)和时间(hour/minute/second/millisecond),但没有时区信息。因此,当调用 parseDateTime
时,Joda-Time 只是假定它处于 JVM 默认时区。
如果你知道输入是UTC,但输入本身没有关于它的信息,你必须告诉它。一种方法是在格式化程序中设置:
// set the formatter to UTC
DateTimeFormatter inputFormatter = DateTimeFormat.forPattern("yyyy-MM-dd'T'HH:mm:ss.SSS")
.withZone(DateTimeZone.UTC);
// DateTime will be in UTC
DateTime parsed = inputFormatter.parseDateTime("2017-09-16T05:06:18.157");
另一种方法是首先将输入解析为 org.joda.time.LocalDateTime
(表示没有时区的日期和时间的 class),然后将其转换为 DateTime
协调世界时:
// parse to LocalDateTime
DateTime = parsed = LocalDateTime.parse("2017-09-16T05:06:18.157")
// convert to a DateTime in UTC
.toDateTime(DateTimeZone.UTC);
两者产生相同的 DateTime
,对应于 UTC 2017-09-16T05:06:18.157Z
。
要将其格式化为 "IST timezone"(这实际上不是时区 - 更多内容见下文),您还可以在格式化程序中设置时区:
// convert to Asia/Kolkata
DateTimeFormatter outputFormatter = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss")
.withZone(DateTimeZone.forID("Asia/Kolkata"));
System.out.println(outputFormatter.print(parsed));
或者您可以将 DateTime
转换为另一个时区,使用 withZone()
method:
DateTimeFormatter outputFormatter = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss");
// convert to Asia/Kolkata
System.out.println(outputFormatter.print(parsed.withZone(DateTimeZone.forID("Asia/Kolkata"))));
两者都将打印:
2017-09-16 10:36:18
在您的代码中,您使用的是 DateTimeZone.getDefault()
,它获取 JVM 默认时区(有一些
此外,请记住像 IST 这样的短名称不是真正的时区。始终喜欢使用 IANA timezones names(始终采用 Region/City
格式,如 Asia/Kolkata
或 Europe/Berlin
)。
避免使用 3 个字母的缩写(如 IST
或 PST
),因为它们 ambiguous and not standard. Just check in this list IST 可以是 "India Standard Time"、"Israel Standard Time" 和"Irish Standard Time".
您可以通过调用 DateTimeZone.getAvailableIDs()
.
Java 新 Date/Time API
Joda-Time 处于维护模式,正在被新的 APIs 取代,所以我不建议用它开始一个新项目。即使在 joda's website 它说:"Note that Joda-Time is considered to be a largely “finished” project. No major enhancements are planned. If using Java SE 8, please migrate to java.time (JSR-310).".
如果您不能(或不想)从 Joda-Time 迁移到新的 API,您可以忽略此部分。
在 Android 中你可以使用 ThreeTen Backport, a great backport for Java 8's new date/time classes. To make it work, you'll also need the ThreeTenABP (more on how to use it
这个新的 API 每个情况都有 lots of different date/time types。
首先,您可以将输入解析为 org.threeten.bp.LocalDateTime
,然后我使用 org.threeten.bp.ZoneOffset
将其转换为 UTC,结果为 org.threeten.bp.OffsetDateTime
.
然后,我使用 org.threeten.bp.ZoneId
将其转换为另一个时区,并使用 org.threeten.bp.format.DateTimeFormatter
对其进行格式化(这基本上是
// parse to LocalDateTime
OffsetDateTime parsed = LocalDateTime.parse("2017-09-16T05:06:18.157")
// convert to UTC
.atOffset(ZoneOffset.UTC);
// convert to Asia/Kolkata
ZoneId zone = ZoneId.of("Asia/Kolkata");
DateTimeFormatter outputFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
System.out.println(outputFormatter.format(parsed.atZoneSameInstant(zone)));
输出为:
2017-09-16 10:36:18