此代码正常运行,但我想使用Joda-Time
public static Date dateFromUTC(Date date){
return new DateTime(date).withZone(DateTimeZone.getDefault()).toDate();
}
我尝试了这个,但它没有用 - 这有什么问题?
{{1}}
答案 0 :(得分:1)
试试这个:
new DateTime(date, DateTimeZone.UTC)
.toLocalDateTime() // value without timezone
.toDateTime() // convert to default timezone
.toDate();
您的代码实际上对日期没有任何作用,因为new DateTime(date)
使用默认时区创建DateTime对象。然后你只需将它转换回java.util.Date
。
答案 1 :(得分:1)
首先,请阅读评论中链接的文章: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
没有时区。
答案 2 :(得分:1)
改为使用 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 †,从不在其他时区。因此,问题中看到的代码是非感性的。你工作太辛苦了!
Joda-Time项目现在位于maintenance mode,团队建议迁移到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
的格式指定proper time zone name,例如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及更高版本中。这些类取代了麻烦的旧legacy日期时间类,例如java.util.Date
,Calendar
和& SimpleDateFormat
现在位于Joda-Time的maintenance mode项目建议迁移到java.time类。
要了解详情,请参阅Oracle Tutorial。并搜索Stack Overflow以获取许多示例和解释。规范是JSR 310。
您可以直接与数据库交换 java.time 对象。使用符合JDBC driver或更高版本的JDBC 4.2。不需要字符串,不需要java.sql.*
类。
从哪里获取java.time类?
ThreeTen-Extra项目使用其他类扩展java.time。该项目是未来可能添加到java.time的试验场。您可以在此处找到一些有用的课程,例如Interval
,YearWeek
,YearQuarter
和more。