gpt4 book ai didi

java - 以毫秒为单位解析 CIM_DateTime 到 Java Date

转载 作者:塔克拉玛干 更新时间:2023-11-02 19:53:47 25 4
gpt4 key购买 nike

我正在尝试将从 Windows 管理界面检索到的日期时间值转换为 Java (1.7) 日期;最终到纪元以来的毫秒数。 format is specified here .

我尝试解析的一个示例是 20160513072950.782000-420,即 2016 年 5 月 13 日 07:29:50 加上 782 毫秒,在我的本地时区(-420 分钟 = UTC- 7 小时)。小数点后的数字是小数秒;理论上最多 6 位微秒,但实际上只有前 4 位非零。

我最初尝试使用 SimpleDateFormat 进行解析指定我要解析的三位毫秒数:

SimpleDateFormat cimDateFormat = new SimpleDateFormat("yyyyMMddHHmmss.SSS");
Date date = cimDateFormat.parse(s, new ParsePosition(0));

我的理由是用 SSS 指定毫秒的三位数会停止解析。不幸的是,这没有用;在上面的示例中添加了超过 782 毫秒。

我最终通过将字符串修剪为所需字符使其按预期工作:

SimpleDateFormat cimDateFormat = new SimpleDateFormat("yyyyMMddHHmmss.S");
Date date = cimDateFormat.parse(s.substring(0, 18), new ParsePosition(0));

在这种情况下,我只包含一个 S 毫秒,但它解析了所有三个。

我在 SimpleDateFormat javadoc 中找不到任何内容可以清楚地解释此解析结束时发生的情况。具体问题:

  1. 为什么在 SSS 情况下它一直解析超过指定的位数?
  2. 为什么单个 S 会解析所有 3 毫秒数字?
  3. 除了像我那样截断字符串之外,是否有任何其他方式告诉 SimpleDateFormat 在指示的位置停止解析字符串?

最佳答案

修改输入

据我所知,Java 的三个常见日期时间框架(旧的捆绑 java.util.Date/.Calendar/java.text.SimpleDateFormat 类、Joda-Time 框架或 java.lang. Java 8 及更高版本中内置的时间框架)允许将 UTC 偏移量作为总分钟数。

根据 Sotirios Delimanolis 的建议,您必须修改 offset-from-UTC将总分钟数转换为标准的小时数和分钟数(和秒数——这种可能性被奇怪的 Microsoft 格式忽略了)。所以 -420 应该变成 -07:00-07:00:00

java.time

您正在使用与最早版本的 Java 捆绑在一起的麻烦的旧日期时间类。旧类(class)现在已成为遗留类(class),并已被 java.time 取代框架内置于 Java 8 及更高版本,主要是 back-ported to Java 6 & 7 by the ThreeTen-Backport项目及进一步adapted to Android .

java.time 类的分辨率为 nanoseconds , 最多九位小数秒。因此,处理您输入的 4-6 位小数秒没有问题。

我们的策略分为两部分:(a) 修改输入以转换与 UTC 的偏移量,以及 (b) 将修改后的输入字符串解析为日期时间对象。

修改输入

首先,我们将输入从 20160513072950.782000-420 更改为 20160513072950.782000-07:00:00。我们通过提取 +- 之后的字符来完成此操作,在本例中为 420

// Modify the input to replace offset as a number of minutes to the standard format, a number of hours, minutes, and seconds.
String input = "20160513072950.782000-420";
String offsetInMinutesAsString = input.substring ( 22 );

将其转换为long,并创建一个LocalTime 对象,以便我们可以生成HH:mm:ss 格式的字符串>。

long offsetInMinutes = Long.parseLong ( offsetInMinutesAsString );
LocalTime offsetAsLocalTime = LocalTime.MIN.plusMinutes ( offsetInMinutes );
String offsetAsString = offsetAsLocalTime.format ( DateTimeFormatter.ISO_LOCAL_TIME );

用我们生成的字符串替换那些尾随字符。

String inputModified = ( input.substring ( 0 , 22 ) + offsetAsString );

将字符串解析为日期时间对象

定义一个 custom formatting pattern通过它将该字符串解析为 OffsetDateTime对象。

// Parse the modified input as an OffsetDateTime.
DateTimeFormatter formatter = DateTimeFormatter.ofPattern ( "yyyyMMddHHmmss.SSSSSSZZZZZ" , Locale.US );
OffsetDateTime odt = OffsetDateTime.parse ( inputModified , formatter );

转储到控制台。

System.out.println ( "input: " + input + " | inputModified: " + inputModified + " | odt: " + odt );

input: 20160513072950.782000-420 | inputModified: 20160513072950.782000-07:00:00 | odt: 2016-05-13T07:29:50.782-07:00

转换

我强烈建议避免使用旧的日期时间类。但是,如果您必须使用 java.util.Date 对象与旧日期时间代码进行互操作,则可以进行转换。

寻找添加到旧类以进行转换的新方法。对于此转换,我们使用 java.util.Date.from .我们需要将该转换方法提供给 Instant对象,UTC 时间轴上的一个时刻,分辨率为 nanoseconds .我们可以从 OffsetDateTime 中提取一个。

Instant instant = odt.toInstant();
java.util.Date utilDate = java.util.Date.from( instant );

有关转换的更多信息,包括漂亮的图表,请参阅 my Answer到另一个问题。请记住,我们仅使用 offset-from-UTC在我们的输入字符串和我们的 OffsetDateTime 中,不是完整的时区。 time zone是用于处理夏令时 (DST) 等异常情况的偏移量规则。 Instantjava.util.Date 均采用 UTC(偏移量为零)。

关于java - 以毫秒为单位解析 CIM_DateTime 到 Java Date,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37308672/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com