java - 将字符串转换为 'Instant'

标签 java date timezone zoneddatetime java.time.instant

我正在尝试使用 Java 8 或实用程序包将字符串中的日期时间转换为 Instant 实例。

例如,

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

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

reqString 在 America/Toronto 中时区。

这是我尝试过的

 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;dr

  • 修复未填充的月份和日期的格式设置模式。
  • 仅使用 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) .新类(class)完全取代旧类(class)。没有必要将传统和现代混为一谈。

本地日期时间

解析为 LocalDateTime因为您的输入字符串缺少 time zone 的任何指示符或 offset-from-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

如果您确定输入旨在表示使用加拿大多伦多地区人们使用的挂钟时间的时刻,请应用 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[America/Toronto]

即时

看到与 UTC 相同的时刻, 提取一个 Instant .同一时刻,不同的挂钟时间。

Instant instant = zdt.toInstant();

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


关于java.time

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。该项目是 future 可能添加到 java.time 的试验场。您可能会在这里找到一些有用的类,例如 Interval , YearWeek , YearQuarter , 和 more .

关于java - 将字符串转换为 'Instant',我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50299639/

相关文章:

java - JTextArea实时输出

java - AssertJ 断言抛出异常或结果

c# - Windows 7时区规则是否存在缺陷

iOS 10 时区格式问题,日期创建为 timeIntervalSince1970

Android:有没有办法获取国家名称的时区?

java - 对于多级进程内缓存来说,更好的选择是什么?

JAVA 返回对象或按引用传递

mysql - 如何将 CONTAINS 与 CURDATE 一起使用?

iphone - 如何从 UILocalNotification 对象获取下一个触发日期

Java 将日期格式从自定义日期更改为 MM dd yyyy