[英]Java Convert UTC Date to local Date with Joda
这段代码有效,但是我想使用Joda-Time
public static Date dateFromUTC(Date date){
return new Date(date.getTime() + Calendar.getInstance().getTimeZone().getOffset(date.getTime()));
}
我试过了,但是没有用-这是什么问题?
public static Date dateFromUTC(Date date){
return new DateTime(date).withZone(DateTimeZone.getDefault()).toDate();
}
尝试这个:
new DateTime(date, DateTimeZone.UTC)
.toLocalDateTime() // value without timezone
.toDateTime() // convert to default timezone
.toDate();
您的代码实际上对日期不执行任何操作,因为new DateTime(date)
创建具有默认时区的DateTime对象。 然后将其转换回java.util.Date
。
首先,请阅读注释中链接的文章: https : //codeblog.jonskeet.uk/2017/04/23/all-about-java-util-date/
java.util.Date
没有时区。 它实际上代表一个时间点:自unix纪元以来的毫秒数(1970年1月1日,UTC午夜)。
但是,当您打印Date
时,它使用 JVM默认时区将Date
转换为日期/时间值,但是Date
本身没有时区。
这就是为什么将Date
对象转换为另一个时区没有意义的原因。
如果您想知道与特定时区中的“ Date
相对应的日期(日,月,年)和时间(时,分,秒,毫秒),则可以使用Joda-Time:
// java.util.Date
Date date = new Date();
// the Date converted to UTC
DateTime utc = new DateTime(date, DateTimeZone.UTC);
// the Date converted to JVM default timezone
DateTime convertedToDefaultTz= new DateTime(date, DateTimeZone.getDefault());
也可以使用另一个DateTime
进行转换:
DateTime convertedToDefaultTz = utc.withZone(DateTimeZone.getDefault());
Joda的DateTime
附加了一个时区,因此现在可以转换为另一个时区了。 但是它返回的Date
对象将始终是相同的,因为它们都表示同一时刻(时间轴上的同一点):
Date d1 = utc.toDate();
Date d2 = convertedToDefaultTz.toDate();
System.out.println(d1.equals(d2)); // true
都是因为-再次- Date
没有时区。
请改用java.time类。
Instant.now() // Capture current moment in UTC. Always in UTC, by definition.
…和…
ZonedDateTime.now() // Capture current moment as seen through the wall-clock time of the people in the region of the time zone used by default in this JVM.
正如其他人所说,您误解了这些课程中涉及的概念。 java.util.Date
以UTC表示时刻 ,始终以UTC †表示 ,从未在其他时区中表示。 因此,在Question中看到的代码是荒谬的。 你太辛苦了!
Joda-Time项目现在处于维护模式 ,团队建议迁移到java.time类。 Joda-Time和java.time之间的许多概念相似,因为两个项目都是由同一个人Stephen Colebourne领导的。
准备迁移时,请使用Instant
代替java.util.Date
。
Instant instant = Instant.now() ; // Capture the current moment in UTC.
Instant.toString():2018-01-23T12:34:56.123456789Z
代替java.util.Calendar
,使用ZonedDateTime
表示通过特定区域(时区)的挂钟时间看到的时刻。
以continent/region
的格式指定正确的时区名称 ,例如America/Montreal
, Africa/Casablanca
或Pacific/Auckland
。 切勿使用EST
或IST
等3-4个字母的缩写,因为它们不是真实的时区,不是标准化的,甚至不是唯一的(!)。
ZoneId z = ZoneId.of( "Pacific/Auckland" ) ;
ZonedDateTime zdt = instant.atZone( z ) ; // Same moment, same point on the timeline, different wall-clock time.
作为快捷方式,如果只需要分区时间,则可以跳过“ Instant
。
ZoneId z = ZoneId.of( "Africa/Tunis" ) ;
ZonedDateTime zdt = ZonedDateTime.now( z ) ; // Capture the current moment as seen by people in a certain time zone.
您可以通过提取Instant
对象从那里到达UTC。
Instant instant = zdt.toInstant() ; // Same moment, same point on the timeline, but viewed with the wall-clock time of UTC.
†其实, 有一个深处分配一个时区java.util.Date
但无关这里我们的讨论。 混乱? 是。 其中的原因是多方面的 ,以避免烂摊子是旧的Date
/ Calendar
及相关遗留日期时间类。
java.time框架内置于Java 8及更高版本中。 这些类取代了麻烦的旧的旧式日期时间类,例如java.util.Date
, Calendar
和SimpleDateFormat
。
现在处于维护模式的Joda-Time项目建议迁移到java.time类。
要了解更多信息,请参见Oracle教程 。 并在Stack Overflow中搜索许多示例和说明。 规格为JSR 310 。
您可以直接与数据库交换java.time对象。 使用与JDBC 4.2或更高版本兼容的JDBC驱动程序 。 不需要字符串,不需要java.sql.*
类。
在哪里获取java.time类?
ThreeTen-Extra项目使用其他类扩展了java.time。 该项目为将来可能在java.time中添加内容提供了一个试验场。 您可以在这里找到一些有用的类,比如Interval
, YearWeek
, YearQuarter
,和更多 。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.