![](/img/trans.png)
[英]Drools Fusion Conversion to long not supported from java.time.ZonedDateTime
[英]Java Time conversion from string to ZonedDateTime
您好,我正在嘗試將日期和時間從以 UTC 時間存儲的 SQL 數據庫轉換為我的系統本地時區,該時區將顯示在 JAVAFX 應用程序的表格中。
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
String appointmentStart = rs.getString("Start");
LocalDateTime ldtStart = LocalDateTime.parse(appointmentStart, formatter);
ZonedDateTime zdtStart = ZonedDateTime.of(ldtStart, ZoneId.systemDefault());
appointmentStart = zdtStart.format(formatter);
String appointmentEnd = rs.getString("End");
LocalDateTime ldtEnd = LocalDateTime.parse(appointmentEnd, formatter);
ZonedDateTime zdtEnd = ZonedDateTime.of(ldtEnd, ZoneId.systemDefault());
appointmentEnd = zdtEnd.format(formatter);
這是我寫的。 該表正在以 UTC 時間填充,並且未進行轉換。 我沒有收到任何錯誤,但是這個邏輯錯了嗎? 如果是這樣,我該怎么做?
歡迎來到堆棧溢出!
您的代碼有幾個問題:
appointmentStart
字符串不包含時區,因此您需要在DateTimeFormatter
中指定它。DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")
.withZone(ZoneOffset.UTC);
String appointmentStart = rs.getString("Start");
// UTC
ZonedDateTime ldtStart = ZonedDateTime.parse(appointmentStart, formatter);
// Local.
ZonedDateTime start = ldtStart.withZoneSameInstant(ZoneId.systemDefault());
DateTimeFormatter // Class for generating text that represents the value of a date-time object.
.ofLocalizedDateTime( FormatStyle.FULL ) // Automatically localize the generated text.
.withLocale( Locale.FRANCE ) // Whatever human language and cultural norms are best for presentation to this particular user. Or call `Locale.getDefault`.
.format( // Generate text.
LocalDateTime // Represent a date with a time-of-day. Does *not* represent a moment as it lacks the context of a time zone or offset from UTC.
.parse( // Interpret text as a date-time value.
"2023-01-23 15:30:55"
.replace( " " , "T" ) // Comply with ISO 8601 format. Then we can proceed with parsing without bothering to specify a formatting pattern.
) // Returns a `LocalDateTime` object.
.atOffset( ZoneOffset.UTC ) // Returns a `OffsetDateTime` object.
.atZoneSameInstant(
ZoneId.systemDefault()
) // Returns a `ZonedDateTime` object.
) // Return a `String` object.
lundi 2023 年 1 月 23 日 07:30:55 太平洋北美洲正常時間
CryptoFool的答案和 Oliver的答案都朝着正確的方向前進。 但我不喜歡他們在單獨解析日期時間之前直接注入一個偏移量。 我也不喜歡他們在OffsetDateTime
更合適的地方使用ZonedDateTime
。
顯然,您有一個包含日期和時間的輸入字符串,但缺少時區上下文或與 UTC 的偏移量。 例如: "2023-01-23 15:30:55"
。
String input = "2023-01-23 15:30:55" ;
該輸入幾乎符合日期時間值的ISO 8601標准格式。 要完全遵守,請將中間的 SPACE 換成T
。
String modified = input.replace( " " , "T" ) ;
java.time類在解析/生成文本時默認使用 ISO 8601 格式。 因此無需指定格式化模式。
解析為時間日期 object, LocalDateTime
object。
LocalDateTime ldt = LocalDateTime.parse( modified );
你說你想假設日期和時間是用來表示一個時刻,與 UTC 的偏移量為零小時-分鍾-秒。 Java 為該偏移量提供了一個常量ZoneOffset.UTC
。 應用該ZoneOffset
以生成OffsetDateTime
object。
OffsetDateTime odt = ldt.atOffset( ZoneOffset.UTC );
接下來,您要求從零偏移量進行調整,以查看 JVM 當前默認時區中的同一時刻。 同一時刻,時間軸上的同一點,但掛鍾時間不同。
獲取該默認區域。
ZoneId z = ZoneId.systemDefault() ;
將該ZoneId
應用於OffsetDateTime
以獲得ZonedDateTime
。
ZonedDateTime zdt = odt.atZoneSameInstant( z ) ;
以本地化格式生成文本。 指定Locale
以用於本地化人類語言和文化規范。
Locale locale = Locale.US;
DateTimeFormatter f = DateTimeFormatter.ofLocalizedDateTime( FormatStyle.FULL ).withLocale( locale );
String output = zdt.format( f );
將所有代碼放在一起。
String input = "2023-01-23 15:30:55";
String modified = input.replace( " " , "T" );
LocalDateTime ldt = LocalDateTime.parse( modified );
OffsetDateTime odt = ldt.atOffset( ZoneOffset.UTC );
ZoneId z = ZoneId.systemDefault();
ZonedDateTime zdt = odt.atZoneSameInstant( z );
Locale locale = Locale.US;
DateTimeFormatter f = DateTimeFormatter.ofLocalizedDateTime( FormatStyle.FULL ).withLocale( locale );
String output = zdt.format( f );
轉儲到控制台。
input = 2023-01-23 15:30:55
modified = 2023-01-23T15:30:55
ldt = 2023-01-23T15:30:55
odt.toString() = 2023-01-23T15:30:55Z
z.toString() = America/Los_Angeles
zdt.toString() = 2023-01-23T07:30:55-08:00[America/Los_Angeles]
output = Monday, January 23, 2023 at 7:30:55 AM Pacific Standard Time
可能有一種更巧妙的方法可以做到這一點,但我會這樣做:
// We have an unzoned datetime String that we assume is in UTC
String appointmentStart = "2022-12-24 11:00:00";
// Add a UTC time (+0) offset to the end of our String, and parse it to get a UTC-zoned ZonedDateTime
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ssZ");
ZonedDateTime utcStart = ZonedDateTime.parse(appointmentStart + "+0000", formatter);
// Convert to the local timezone
ZonedDateTime localZonedStart = utcStart.withZoneSameInstant(ZoneId.systemDefault());
// Define a formatter that doesn't include the time zone
DateTimeFormatter formatter2 = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
// Convert the local time to a String
String localZonedStartString = localZonedStart.format(formatter2);
// Print the resulting String
System.out.println(localZonedStartString);
結果:
2022-12-24 03:00:00
我在太平洋時區,與 UTC 相差 -8 小時,我們看到生成的字符串對於我的本地時區是正確的。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.