我有一个Date对象,它从数据库中获取已经是UTC的日期,但是时区偏移量是根据应用程序运行的位置转换的。
因此,如果数据库的日期为uniq 1.txt > 1.txt
,并且应用程序在LA中运行,则Date对象的偏移量将为7,并且输出将类似于此1.txt
。由于日期已经是UTC,所以无论它在哪里运行,我都希望它看起来像2019-09-06 00:00:00.000
。
Date类没有2019-09-06T07:00Z
方法,想到的第一件事是将其转换为String并在最后加上硬编码2019-09-06T00:00Z
,这是不干净的。有什么想法吗?
更多信息:列的类型为DATETIME。 DB:SQL Server。
答案 0 :(得分:2)
我有一个Date对象,它从已经存在UTC的数据库中获取日期,
不要。
可怕的Date
类在几年前被现代的 java.time 类所取代。
您应该使用OffsetDateTime
从类型为TIMESTAMP WITH TIME ZONE
的数据库列中检索一下。
OffsetDateTime odt = myResultSet.getObject( … , OffsetDateTime.class ) ;
该值可能以UTC为单位。如果要查看调整到时区的时刻,请应用ZoneId
以获得ZonedDateTime
。
ZoneId z = ZoneId.of( "America/Montreal" ) ;
ZonedDateTime zdt = odt.atZoneSameInstant( z ) ;
但是时区偏移量会根据应用程序的运行位置进行转换。
请注意,虽然java.util.Date
实际上是UTC的时刻,但其toString
方法却是说谎。该方法在生成其文本时动态地应用JVM的当前默认时区。尽管出于良好目的,但此反功能造成了Date
内部存在时区的错觉。
如果仅使用 java.time 类,则不会出现此类问题。无需再次使用java.util.Date
,java.sql.Date
,Calendar
,GregorianCalendar
,SimpleDateFormat
,DateFormat
或其他此类旧类。
因此,如果数据库的日期为:2019-09-06 00:00:00.000并且应用程序在LA中运行,则Date对象的偏移量将为7,并且输出将类似于以下2019-09-06T07: 00Z
这部分对我来说毫无意义。
您的数据库中是否有正确的数据类型? TIMESTAMP WITHOUT TIME ZONE
可能是错误类型,用于跟踪时刻。此类型只有日期和时间,但是缺少与UTC偏移或时区的上下文。此类型不能代表时间轴上的特定点。
编辑您的问题以精确地指定 您的列是什么数据库和什么数据类型。
至少尝试使用 java.time 来消除Date::toString
注入不适当时区的困惑。
Date类没有setTimeZone()方法
java.util.Date
始终处于UTC,距离1970年1月1日UTC 1970-01-01T00:00:00Z开始仅几毫秒。而已。 (实际上,还有更多的时区被埋在深处,没有任何吸气剂方法,会影响equals
的行为,但与我们在这里的讨论无关。此类是糟糕的设计烂摊子。)>
,首先想到的是将其转换为String并在末尾硬编码00:00Z,这并不干净。有什么想法吗?
不,您绝对不应该玩此类游戏。您只会陷入更大的麻烦。直接在数据库中获取数据类型,仅使用Java中的 java.time 类,即可解决您的问题。
由于您没有提供足够的详细信息,因此我无法提供进一步的帮助。搜索堆栈溢出以了解更多信息。这个主题已经被讨论了很多次了。
答案 1 :(得分:1)
Date
是固定的时间点。可以使用不同的时区显示,但是它本身没有时区。
可以将DateFormat
与SimpleDateFormat
一样设置为使用特定时区。将日期格式设置为使用TimeZone.getTimeZone("GMT")
,您将获得所需的输出。
从Java 8开始,有一个更新的,改进的日期/时间API:https://docs.oracle.com/javase/8/docs/api/java/time/package-summary.html