在Java中将日期从UTC转换为PST

5

我需要将Google App Engine本地服务器时区的日期转换为Java中的太平洋时间。

我尝试使用以下代码:

Calendar calstart =
Calendar.getInstance();

calstart.setTimeZone(TimeZone.getTimeZone("PST"));
//calstart.setTimeZone(TimeZone.getTimeZone("America/Los_Angeles"));

Date startTime = calstart.getTime();

但是这给我提供了错误的时间(一些下午4点,而实际上PST是晚上10点)。我还尝试了注释掉的行America/Los_Angeles,但在GAE服务器上提供了错误的时间。
有什么想法/建议吗?

请查看我对这个问题的回答 - Vik David
3个回答

6
使用Joda Time,你只需要使用DateTime.withZone方法。示例如下:
public static Date convertJodaTimezone(LocalDateTime date, String srcTz, String destTz) {
    DateTime srcDateTime = date.toDateTime(DateTimeZone.forID(srcTz));
    DateTime dstDateTime = srcDateTime.withZone(DateTimeZone.forID(destTz));
    return dstDateTime.toLocalDateTime().toDateTime().toDate();
}

作为建议,永远不要使用默认的时间相关 API 进行计算。它非常糟糕。Joda 看起来是最好的替代 API。


2
除非你需要进行一些计算,因此需要将日期格式化以便向终端用户显示,否则您可以直接使用DateFormat:
Date startTime = new Date(); // current date time
TimeZone pstTimeZone = TimeZone.getTimeZone("America/Los_Angeles");
DateFormat formatter = DateFormat.getDateInstance(); // just date, you might want something else
formatter.setTimeZone(pstTimeZone);
String formattedDate = formatter.format(startTime);

然而,如果您真的需要转换日期(这非常罕见),您可能希望使用以下代码片段:
TimeZone pacificTimeZone = TimeZone.getTimeZone("America/Los_Angeles");
long currentTime = new Date().getTime();
long convertedTime = currentTime +
    pacificTimeZone.getOffset(currentTime);

这将给你从1970年1月1日起在PST时区经过的毫秒数。你可以使用这个信息轻松地创建Date对象。
如果你需要频繁进行日期计算,你可能想使用Apache Commons Lang的DateUtils。或者像mdrg建议的那样切换到JodaTime。


2

不要依赖服务器的时区

永远不要依赖服务器或主机JVM当前默认的时区。

始终明确指定您期望的时区,并将其作为可选参数传递。

java.time

java.util.Calendar类现在已经过时,被java.time类所取代。
获取当前的UTC时间。Instant类表示时间线上的一个时刻,在UTC时间标准下,精度为纳秒(最多九位小数)。
Instant instant = Instant.now();

instant.toString(): 2017-01-19T22:01:21.321Z

当您想通过特定区域的挂钟时间观看那一时刻时,请应用ZoneId以获得ZonedDateTime

指定格式为continent/region正确时区名称,例如America/MontrealAfrica/CasablancaPacific/Auckland。永远不要使用3-4个字母的缩写,如ESTPSTIST,因为它们不是真正的时区,没有标准化,甚至不是唯一的(!)。

ZoneId z = ZoneId.of( "America/Los_Angeles" );
ZonedDateTime zdt = instant.atZone( z );

zdt.toString(): 2017年1月19日14点01分21秒.321,美国洛杉矶时区


Table of all date-time types in Java, both modern and legacy


关于 java.time

java.time 框架内置于 Java 8 及更高版本。这些类取代了麻烦的旧版日期时间类,例如 遗留java.util.DateCalendarSimpleDateFormat

想要了解更多,请查看Oracle教程。并在Stack Overflow上搜索许多示例和解释。规范是JSR 310

Joda-Time项目现在处于维护模式,建议迁移到java.time类。

您可以直接使用与您的数据库兼容的JDBC驱动程序(符合JDBC 4.2或更高版本)与java.time对象进行交换。无需字符串,无需java.sql.*类。Hibernate 5和JPA 2.2支持java.time

在哪里获取java.time类?


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接