Joda-Time 库指定 mili 秒精度
Posted
技术标签:
【中文标题】Joda-Time 库指定 mili 秒精度【英文标题】:Joda-Time Library Specifying mili second precision 【发布时间】:2021-11-11 10:56:36 【问题描述】:我正在使用这段代码片段将日期和时间字符串转换为 Joda DateTime 对象 -
String time = "124204";
String date = "05/09/25";
DateTimeFormatter formatter = DateTimeFormat.forPattern("dd/mm/yyhhmmss").withZone(DateTimeZone.UTC);
String dateInString = date.concat(time);
DateTime dateTime = DateTime.parse(dateInString, formatter);
System.out.println(dateTime);
我得到的输出是 - 2025-01-05T00:42:04.000Z
但我希望它为 - 2025-01-05T00:42:04.000000Z
我希望 mili 秒精度为 6 位。
我该怎么做?感谢您的帮助。
【问题讨论】:
您使用 Joda Time 有什么原因吗?尽管它比使用Date
、Calendar
或 SimpleDateFormat
更好,但您确实应该使用 java.time
中提供的更新的 Java 日期和时间 API。
毫秒精度不能是六位数,毫秒按定义是三位数。您似乎想要的是微秒精度。但是,您似乎将toString()
的输出与某些所需的渲染混淆了。如果您想要 dateTime
的不同呈现方式,则需要使用适当的格式化程序。
请注意,格式模式字母区分大小写。请再次检查您是否需要mm
或MM
、hh
或HH
。
【参考方案1】:
你很困惑。
你似乎认为你有一个字符串。你没有;你有一个DateTime
类型的对象。您所看到的是在其中一个对象上调用 toString()
的结果,并且与 all toString()
方法一样,这只是一个调试辅助工具。它是为了你的开发者的眼球,绝对没有其他用途(如果你将它用于其他用途,请停止这样做)。
如果您希望以某种特定格式输出,则创建第二个 DateTimeFormat
对象并使用它。您正在使用第一个将字符串转换为日期时间对象(parse
方法)。这些格式化程序对象是双向的;他们还可以使用format
方法将日期时间对象转换回字符串。去做。制作你想要的图案,在上面调用.format
并将你拥有的dateTime
对象交给它。
注意:您为什么使用 jodatime?它已被 java.time
包淘汰,该包由与 jodatime 相同的作者编写。
【讨论】:
【参考方案2】:只要您至少使用 Java 8,请使用 java.time:
String time = "124204";
String date = "05/09/25";
DateTimeFormatter parser = DateTimeFormatter.ofPattern("dd/MM/yyHHmmss").withZone(ZoneId.of("UTC"));
String dateInString = date.concat(time);
ZonedDateTime dateTime = ZonedDateTime.parse(dateInString, parser);
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSSSSX");
System.out.println(dateTime.format(formatter));
这将打印 2025-09-05T12:42:04.000000Z。不确定您是否真的打算在输入中使用 12 小时格式,而且我没有这方面的经验,所以我忽略了这一点。
【讨论】:
【参考方案3】:Joda-Time 解决方案(过时)
您的结果中的秒数可能不需要这 6 位小数。你可能想再次考虑这个问题。您要求的格式是 ISO 8601。ISO 8601 格式不规定小数位数,而是让交换数据的各方商定。大多数实现都接受不同数量的小数(有一定的限制,但在我遇到的情况下提供少于限制的小数是没有问题的)。
其他是正确的,您可以考虑升级到 java.time,它是 Joda-Time 的继任者。如果你现在不能这样做,这里有一种使用 Joda-Time 获取你想要的字符串的方法。
String time = "124204";
String date = "05/09/25";
DateTimeFormatter timeFormatter = DateTimeFormat.forPattern("HHmmss");
DateTimeFormatter dateFormatter = DateTimeFormat.forPattern("dd/MM/yy");
LocalTime lt = LocalTime.parse(time, timeFormatter);
LocalDate ld = LocalDate.parse(date, dateFormatter);
DateTime dateTime = ld.toLocalDateTime(lt).toDateTime(DateTimeZone.UTC);
DateTimeFormatter resultFormatter
= DateTimeFormat.forPattern("yyyy-MM-dd'T'HH:mm:ss.SSSSSSZZ");
String dateTimeString = dateTime.toString(resultFormatter);
System.out.println(dateTimeString);
输出:
2025-09-05T12:42:04.000000+00:00
我注意到您要求2025-01-05T00:42:04.000000Z
。也许您没有注意到时间字符串中的小时是12
(不是00
),而日期字符串中的月份是09
(不是01
)。在您自己的代码中,您的小时和月份不正确,因为您在格式模式中始终使用小写模式字母。我们需要大写 HH
代表一天中的小时和大写 MM
代表月份。
编辑:您还希望 Z
而不是 +00:00
来表示 UTC(与 UTC 的偏移量为零),就像您从无参数 DateTime.toString()
得到的一样。 ISO 8601 再次允许两者,所以这可能无关紧要。不过,我很惊讶,没有找到简单的方法来获取Z
。以下格式化程序给出了它,但我可能会遗漏一些更简单的东西。
DateTimeFormatter resultFormatter = new DateTimeFormatterBuilder()
.append(ISODateTimeFormat.dateHourMinuteSecond())
.appendPattern(".SSSSSS")
.appendTimeZoneOffset("Z", true, 2, 2)
.toFormatter();
2025-09-05T12:42:04.000000Z
我还使用了不同的解析方法。虽然连接两个字符串并解析结果有效,但我发现单独解析每个字符串更清晰。
正如其他人所说,当您要求特定格式时,例如秒的特定小数位数,您只能在字符串中使用该格式。因此,解决方案是将您的DateTime
格式化为字符串。
用法:一毫秒是千分之一秒。所以要求 6 位毫秒是没有意义的,也不会给你更高的精度。我把你的问题理解为秒的小数点后 6 位——也称为微秒(百万分之一秒)。
链接
Wikipedia article: ISO 8601 可能类似的问题:Scala / Joda - Joda DateTimeFormat not applying【讨论】:
以上是关于Joda-Time 库指定 mili 秒精度的主要内容,如果未能解决你的问题,请参考以下文章
MySQL DATETIME 精度(joda-time、Hibernate、org.jadira.usertype、hbm2ddl)
使用joda-time工具类 计算时间相差多少 天,小时,分钟,秒
使用joda-time工具类 计算时间相差多少 天,小时,分钟,秒