Java:Convert UTC 日期到本地时区
Java:Convert date in UTC to local time zone
我有日期存储在 UTC 时区的数据库中。必须将此日期转换为系统本地时区。我已经研究了 Whosebug 中的所有其他问题,但没有一个对我有用。请任何人帮我解决这个问题。
我只需要 java.utils.Date 中的输出,因为石英调度程序的 startAt() 方法只接受日期。
你可以使用下面的代码
DateFormat localFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS");
localFormat.setTimeZone(TimeZone.getTimeZone("PST"));
Date locaTime = new Date(localFormat.format(date));
我正在使用 java 中的 LocalDateTime 8. 我使用下面的代码从 unix 时间戳中获取本地日期时间。可能还有其他方法可以从您想要的格式中获取它。
Date.from(LocalDateTime.ofEpochSecond(unixTimestamp, 0, ZoneOffset.UTC).toLocalDate());
tl;博士
您不需要应用时区。
详情
A Date
已经有一个时区:UTC。它代表一个特定的时刻,时间轴上的一个点。您只会在用户的首选 wall-clock time 中应用时区以显示给用户。设置为早上 6 点 UTC 的闹钟在 Europe/Paris
的早上 7 点和 Asia/Kolkata
的 11:30 AM 触发——同一时刻。
Date
是 UTC
java.util.Date
class 已经使用 UTC。您不能将该对象调整到另一个时区。 class 只是自 UTC 1970 年第一刻以来的毫秒数的包装器。不要被其 toString
方法的混淆行为分散注意力,该方法在呈现字符串时应用 JVM 当前的默认时区;内部值采用 UTC†.
所以你问的(从 Date
开始,调整到本地时区,并呈现 Date
)是不可能的,没有意义。
我建议您在 Whosebug 上搜索和研究其他日期时间问题以了解这些概念。专门搜索这些 Java classes: Instant
, ZoneId
, ZonedDateTime
.
转化
当需要与尚未更新为 java.time 类型的旧代码交互时,您可以转换为 java.time。调用添加到旧 classes 的新转换方法。
Instant instant = myJavaUtilDate.toInstant(); // UTC.
ZonedDateTime zdt = instant.atZone( ZoneId.of( "America/Montreal" ) ); // Same moment, but different wall-clock time.
并且您可以从 java.time classes 转换。
LocalDate ld = LocalDate.of( 2016 , 1 , 23 ); // 2016-01-23. No time zone at all.
LocalTime lt = LocalTime.of( 6 , 0 , 0 ); // 06:00:00. No time zone at all.
ZoneId z = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = ZonedDateTime( ld , lt , z );
Instant instant = zdt.toInstant(); // UTC.
// Convert from modern classes to legacy class.
java.util.Date d = java.util.Date.from( instant );
† java.util.Date
实际上 确实 在其内部设置了时区。但是那个区域没有 setter 也没有 getter 方法。为了我们的目的,我们可以忽略它。令人困惑?是的。在早期 Java 日期时间 classes 中做出的许多糟糕的设计选择之一。也是避免这些 classes 的众多原因之一。仅使用 java.time classes。
通过查看 Whosebugs 问题找到一个 class 石英 DateBuilder,它有助于转换时区
Date startDate = DateBuilder.translateTime(job.getStartDate(), TimeZone.getTimeZone("UTC"), TimeZone.getDefault());
我有日期存储在 UTC 时区的数据库中。必须将此日期转换为系统本地时区。我已经研究了 Whosebug 中的所有其他问题,但没有一个对我有用。请任何人帮我解决这个问题。 我只需要 java.utils.Date 中的输出,因为石英调度程序的 startAt() 方法只接受日期。
你可以使用下面的代码
DateFormat localFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS");
localFormat.setTimeZone(TimeZone.getTimeZone("PST"));
Date locaTime = new Date(localFormat.format(date));
我正在使用 java 中的 LocalDateTime 8. 我使用下面的代码从 unix 时间戳中获取本地日期时间。可能还有其他方法可以从您想要的格式中获取它。
Date.from(LocalDateTime.ofEpochSecond(unixTimestamp, 0, ZoneOffset.UTC).toLocalDate());
tl;博士
您不需要应用时区。
详情
A Date
已经有一个时区:UTC。它代表一个特定的时刻,时间轴上的一个点。您只会在用户的首选 wall-clock time 中应用时区以显示给用户。设置为早上 6 点 UTC 的闹钟在 Europe/Paris
的早上 7 点和 Asia/Kolkata
的 11:30 AM 触发——同一时刻。
Date
是 UTC
java.util.Date
class 已经使用 UTC。您不能将该对象调整到另一个时区。 class 只是自 UTC 1970 年第一刻以来的毫秒数的包装器。不要被其 toString
方法的混淆行为分散注意力,该方法在呈现字符串时应用 JVM 当前的默认时区;内部值采用 UTC†.
所以你问的(从 Date
开始,调整到本地时区,并呈现 Date
)是不可能的,没有意义。
我建议您在 Whosebug 上搜索和研究其他日期时间问题以了解这些概念。专门搜索这些 Java classes: Instant
, ZoneId
, ZonedDateTime
.
转化
当需要与尚未更新为 java.time 类型的旧代码交互时,您可以转换为 java.time。调用添加到旧 classes 的新转换方法。
Instant instant = myJavaUtilDate.toInstant(); // UTC.
ZonedDateTime zdt = instant.atZone( ZoneId.of( "America/Montreal" ) ); // Same moment, but different wall-clock time.
并且您可以从 java.time classes 转换。
LocalDate ld = LocalDate.of( 2016 , 1 , 23 ); // 2016-01-23. No time zone at all.
LocalTime lt = LocalTime.of( 6 , 0 , 0 ); // 06:00:00. No time zone at all.
ZoneId z = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = ZonedDateTime( ld , lt , z );
Instant instant = zdt.toInstant(); // UTC.
// Convert from modern classes to legacy class.
java.util.Date d = java.util.Date.from( instant );
† java.util.Date
实际上 确实 在其内部设置了时区。但是那个区域没有 setter 也没有 getter 方法。为了我们的目的,我们可以忽略它。令人困惑?是的。在早期 Java 日期时间 classes 中做出的许多糟糕的设计选择之一。也是避免这些 classes 的众多原因之一。仅使用 java.time classes。
通过查看 Whosebugs 问题找到一个 class 石英 DateBuilder,它有助于转换时区
Date startDate = DateBuilder.translateTime(job.getStartDate(), TimeZone.getTimeZone("UTC"), TimeZone.getDefault());