如何将 UTC 格式的字符串转换为特定时区的日历?
Posted
技术标签:
【中文标题】如何将 UTC 格式的字符串转换为特定时区的日历?【英文标题】:How to convert UTC formatted string to calendar in specific timezone? 【发布时间】:2012-12-05 01:47:19 【问题描述】:我正在尝试将一些 UTC 时间的字符串转换为应设置为 GMT-5 的 java Calendar 对象。
我当前的 UTC 字符串输入是这样的:
UTC 日期:20050329174411
我使用这段代码(我检测到如下所示的“模式”):
DateFormat dateFormat = new SimpleDateFormat(pattern);
Date date = dateFormat.parse(utcDate);
calendar = Calendar.getInstance(TimeZone.getTimeZone("GMT-5"));
calendar.setTime(date);
然后我这样打印时间:
日历.getTime()
我得到了这个结果:
格林威治标准时间:2005 年 3 月 29 日星期二 17:44:11 EST
我需要支持这些日期/时间字符串模式:
FORMAT_UTC4 = "yyyy";
FORMAT_UTC6 = "yyyyMM";
FORMAT_UTC8 = "yyyyMMdd";
FORMAT_UTC10 = "yyyyMMddHH";
FORMAT_UTC12 = "yyyyMMddHHmm";
FORMAT_UTC14 = "yyyyMMddHHmmss";
我希望将时间设置为“12:44:11”。我已经阅读了几个示例,发现日期时间处理非常混乱。对我来说,它总是一样的,我得到某种格式的 UTC 字符串,然后将其转换为 GMT-5。我真的觉得应该很容易!
参考 1:How can I get the current date and time in UTC or GMT in Java?
参考 2:How to handle calendar TimeZones using Java?
【问题讨论】:
【参考方案1】:在解析日期之前,您必须将 SimpleDateFormat 的时区设置为 UTC。否则,它使用您的默认时区。
并且要在“GMT-5”时区显示日期,您应该使用另一个 DateFormat,将时区设置为 GMT-5,并使用此 DateFormat 格式化日期。 Date 的toString()
方法使用您的默认时区将日期转换为可读的内容。
【讨论】:
我试过这个 dateFormat.setTimeZone(TimeZone.getTimeZone("GMT-5"));,需要改为 UTC 吗? 输入日期为UTC。因此必须使用 UTC 中的日期格式对其进行解析。输出日期为 GMT-5。因此必须使用 GMT-5 中的日期格式对其进行格式化。您不会使用法语翻译来阅读德语文本,对吗?而且您也不会使用德语翻译器来编写法语文本。 我认为从日历 (getTime) 中获取日期对象会给我 GMT-5 中的日期。 日期没有时区。这是一个普遍的瞬间。您可以选择使用时区对其进行格式化,其 toString() 方法使用您的默认时区对其进行格式化,但它没有任何时区。【参考方案2】:java.time
请注意GMT-5
或-05:00
小时的时区偏移量是固定偏移量,即独立于DST 和类型来表示具有时区偏移量的日期时间为OffsetDateTime
。
演示:
import java.time.Instant;
import java.time.OffsetDateTime;
import java.time.ZoneOffset;
public class Main
public static void main(String[] args)
Instant instant = Instant.ofEpochMilli(20050329174411L);
OffsetDateTime odt = instant.atOffset(ZoneOffset.of("-05:00"));
// Alternatively
// OffsetDateTime.ofInstant(instant, ZoneOffset.of("-05:00"));
System.out.println(odt);
输出:
2605-05-15T18:52:54.411-05:00
如果您希望根据 DST 自动调整时区偏移,请使用 ZonedDateTime
。
演示:
import java.time.Instant;
import java.time.ZoneId;
import java.time.ZonedDateTime;
public class Main
public static void main(String[] args)
Instant instant = Instant.ofEpochMilli(20050329174411L);
ZonedDateTime zdt = instant.atZone(ZoneId.of("America/Chicago"));
// Alternatively
// ZonedDateTime.ofInstant(instant, ZoneId.of("America/Chicago"));
System.out.println(zdt);
输出:
2605-05-15T18:52:54.411-05:00[America/Chicago]
从Trail: Date Time了解更多关于java.time
的modern date-time API*。
如果您需要从ZonedDateTime
的对象中获得java.util.Calendar
的对象,您可以按如下方式进行:
Calendar calendar = Calendar.getInstance();
calendar.setTime(Date.from(zdt.toInstant()));
* 出于任何原因,如果您必须坚持使用 Java 6 或 Java 7,您可以使用 ThreeTen-Backport,它将大部分 java.time 功能向后移植到 Java 6 和 7 . 如果您正在为一个 android 项目工作并且您的 Android API 级别仍然不符合 Java-8,请检查 Java 8+ APIs available through desugaring 和 How to use ThreeTenABP in Android Project。
【讨论】:
以上是关于如何将 UTC 格式的字符串转换为特定时区的日历?的主要内容,如果未能解决你的问题,请参考以下文章
将 UTC 中的 SQL Server 日期时间转换为特定时区