将字符串转换为Instant

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (2769)

我试图使用java 8或utils包将string中的datetime转换为即时。

例如。

String requestTime = "04:30 PM, Sat 5/12/2018";

Instant reqInstant should result in 2018-05-12T20:30:00.000Z

reqString位于美国/多伦多时区。

这是我试过的

 String strReqDelTime = "04:30 PM, Sat 5/12/2018";
 Date date = new SimpleDateFormat("hh:mm a, EEE MM/dd/yyyy").parse(requestTime);
 Instant reqInstant = date.toInstant();

上面的代码导致了"2018-05-12T23:30:00Z"

任何帮助表示赞赏。

提问于
用户回答回答于

tl;博士

  • 修复未填充月份和日期的格式模式。
  • 仅使用java.time类,从不使用旧类。

举例:

LocalDateTime.parse(                   // Parse as an indeterminate `LocalDate`, devoid of time zone or offset-from-UTC. NOT a moment, NOT a point on the timeline.
    "04:30 PM, Sat 5/12/2018" ,        // This input uses a poor choice of format. Whenever possible, use standard ISO 8601 formats when exchanging date-time values as text. Conveniently, the java.time classes use the standard formats by default when parsing/generating strings.
    DateTimeFormatter.ofPattern( "hh:mm a, EEE M/d/uuuu" , Locale.US )  // Use single-character `M` & `d` when the number lacks a leading padded zero for single-digit values.
)                                      // Returns a `LocalDateTime` object.
.atZone(                               // Apply a zone to that unzoned `LocalDateTime`, giving it meaning, determining a point on the timeline.
    ZoneId.of( "America/Toronto" )     // Always specify a proper time zone with `Contintent/Region` format, never a 3-4 letter pseudo-zone such as `PST`, `CST`, or `IST`. 
)                                      // Returns a `ZonedDateTime`. `toString` → 2018-05-12T16:30-04:00[America/Toronto].
.toInstant()                           // Extract a `Instant` object, always in UTC by definition.
.toString()                            // Generate a String in standard ISO 8601 format representing the value within this `Instant` object. Note that this string is *generated*, not *contained*.

2018-05-12T20:30:00Z

使用单位数格式化模式

MM在格式化模式中使用的意思是任何单位数值(1月至9月)将显示填充前导零。

但是你的输入缺少填充的前导零。所以使用单一M

同样的,我预计的一天,d而不是dd

仅使用java.time

您正在使用java.time类几年前取代的麻烦的旧日期时间类(DateSimpleDateFormat)。新课程完全取代旧课程。无需混合传统和现代。

LocalDateTime

解析为LocalDateTime因为您的输入字符串缺少任何时区指示符或从UTC偏移量。这样的价值不是时刻,也不是时间轴上的一点。它只是大约26-27小时范围内的一组潜在时刻。

String input = "04:30 PM, Sat 5/12/2018";
DateTimeFormatter f = DateTimeFormatter.ofPattern( "hh:mm a, EEE M/d/uuuu" , Locale.US );  // Specify locale to determine human language and cultural norms used in translating that input string.
LocalDateTime ldt = LocalDateTime.parse( input , f );

ldt.toString():2018-05-12T16:30

ZonedDateTime

如果您确定输入旨在表示使用多伦多加拿大地区人员使用的挂钟时间的时刻,请应用a ZoneId来获取ZonedDateTime对象。

分配时区为您的未分区提供了意义LocalDateTime。现在我们有一个时刻,时间轴上的一点。

ZoneId z = ZoneId.of( "America/Toronto" ) ;
ZonedDateTime zdt = ldt.atZone( z ) ;  // Give meaning to that `LocalDateTime` by assigning the context of a particular time zone. Now we have a moment, a point on the timeline.

zdt.toString():2018-05-12T16:30-04:00 [美国/多伦多]

Instant

要查看与UTC相同的时刻,请提取Instant。同一时刻,不同的挂钟时间。

Instant instant = zdt.toInstant() ;

instant.toString():2018-05-12T20:30:00Z

关于java.time

java.time框架是建立在Java 8和更高版本。这些类取代麻烦的老传统日期时间类,如java.util.DateCalendar,和SimpleDateFormat

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

要了解更多信息,请参阅Oracle教程。并搜索Stack Overflow以获取许多示例和解释。规范是JSR 310

您可以直接与数据库交换java.time对象。使用符合JDBC 4.2或更高版本的JDBC驱动程序。不需要字符串,不需要课程。java.sql.*

从哪里获取java.time类?

ThreeTen-额外项目与其他类扩展java.time。该项目是未来可能添加到java.time的试验场。您可以在此比如找到一些有用的类IntervalYearWeekYearQuarter,和更多

用户回答回答于

您的计算机(服务器)中的时区似乎是美国太平洋夏令时(GMT-7),但您预计会有美国东部夏令时(GMT-4)的结果。

Instant.toString()以ISO-8601格式返回UTC(GMT + 0)DateTime。(末尾的'Z'表示UTC)。

SimpleDateFormat威胁DateTime字符串在未指定的计算机的默认时区中。并且您的输入未指定时区。

所以,你需要在输入的时区做些什么。

PS。在DST东部的矿山机器上,您的代码完全按照您的预期给出了结果。

扫码关注云+社区

领取腾讯云代金券