将时间戳字符串“HH:mm:ss”转换为持续时间

时间:2016-03-29 18:43:25

标签: java string time timestamp duration

就像标题所说,我已经能够从文本文件中隔离一个字符串,其中包含格式为“HH:mm:ss”的持续时间。我如何将其转换为持续时间?我需要将它转换为以1小时表示此时间戳的双精度,所以如果它是“08:30:00”,我需要双精度值为8.5。不确定如何转换它,似乎时间在Java中是一个棘手的主题。任何帮助将不胜感激,即使只是你说“使用这个类”,所以我可以查找并弄明白。

谢谢!

3 个答案:

答案 0 :(得分:2)

您可以将表达式拆分为多个部分,然后解析并计算持续时间:

    String[] a = "08:30:00".split(":");
    double d = Integer.parseInt(a[0]) + Integer.parseInt(a[1]) / 60.0;

答案 1 :(得分:2)

TL;博士

Duration.between ( 
    LocalTime.MIN , 
    LocalTime.parse ( "08:30:00" ) 
).toString()
  

PT8H30M

持续时间与时间戳

如果字符串08:30:00表示“8个半小时”的时间跨度,则不要使用术语“时间戳”。 “持续时间”这个词是正确的并且是常用的。并避免使用HH:MM:SS的格式,因为它太模糊,看起来像是一个时间。而是使用下面讨论的标准格式。

如果字符串08:30:00表示“早上八点半”,则使用“时间戳”一词,并避免使用“持续时间”一词。

这是两个非常不同的概念。你必须明白它们,每一个都应该在你的脑海中清晰。使用HH:MM:SS的模糊格式使得这种区别变得更加困难(因此避免使用这种格式!)。

java.time

现代的方法是使用java.time类。

LocalTime

正如Sharma的评论中所提到的,首先将您的字符串解析为LocalTime。此类表示没有日期且没有时区的时间。没有时区意味着这些对象基于通用的24小时制,而不考虑Daylight Saving Time (DST)等异常情况。

我们并不真正想要LocalTime,因为您的输入字符串代表的是时间跨度而不是时间。但这只是第一步。

LocalTime lt = LocalTime.parse ( "08:30:00" );

Duration

为了表示所需的时间跨度,我们需要Duration类。此课程适用于未附加到时间轴的时间跨度。我们可以通过将时间LocalTimeLocalTime.MIN以及00:00:00.0的{​​{1}}和lt的{​​{1}}转换为Duration d = Duration.between ( LocalTime.MIN , lt ); 来创建一个。刚刚实例化。

PnYnMnDTnHnMnS

ISO 8601

我们可以通过简单地调用ISO 8601 format for durations在标准Duration::toString中生成字符串来查看结果。解析/生成字符串时,java.time类在默认情况下使用ISO 8601。对于持续时间,标准格式为P,其中T标记开头,PT8H30M将年 - 月 - 日部分与小时 - 分 - 秒部分分开。因此,我们的八个半小时将显示为Duration

System.out.println(“d.toString():”+ d);

  

d.toString():PT8H30M

避免使用日期时间值的十进制数

为了处理这样的持续时间值,我强烈建议在序列化为文本时使用Java代码中的08:30:00对象和ISO 8601格式。

  • 在代码中使用对象可提供类型安全性,使您的代码更加自我记录,并确保有效值。
  • 使用ISO 8601格式的文本可以轻松解析值,是一种易于被人阅读的格式,并且其含义明确不像8.5,它可能被误读为一个时间。

您想要的十进制数字格式如float不明确(很容易忽略其含义)。使用floating-point类型(FloatdoubleDoubleBigDecimal)时,十进制数字也很笨拙且经常不正确,因为这些类型会产生多余的错误数字在小数部分的远端。浮点技术故意以准确性为代价来提高执行速度。

toMinutes

如果您必须使用小数,并且想要准确,请使用BigDecimal类。

在这个例子中,我假设您在截断任何小数分钟时需要小时和分钟。所以我在Duration上致电BigDecimal minutesPerHour = new BigDecimal ( 60L ); // Use var/constant for clarity of your intent. BigDecimal minutes = new BigDecimal ( d.toMinutes () ); BigDecimal fractionalHours = minutes.divide ( minutesPerHour );

BigDecimal
  

frationalHours.toString():8.5

请参阅此示例code live in IdeOne.com

如果您坚持使用这些小数而不是Duration个对象和ISO 8601文本,您可能希望使用{{1}}工具进行四舍五入。

关于java.time

java.time框架内置于Java 8及更高版本中。这些类取代了麻烦的旧legacy日期时间类,例如java.util.DateCalendar和& SimpleDateFormat

现在位于Joda-Timemaintenance mode项目建议迁移到java.time类。

要了解详情,请参阅Oracle Tutorial。并搜索Stack Overflow以获取许多示例和解释。规范是JSR 310

从哪里获取java.time类?

ThreeTen-Extra项目使用其他类扩展java.time。该项目是未来可能添加到java.time的试验场。您可以在此处找到一些有用的课程,例如IntervalYearWeekYearQuartermore

答案 2 :(得分:0)

我会用FXMLLoader fxml = new FXMLLoader(getClass().getResource("FXMLDocument.fxml")); Parent root = fxml.load(); 来完成此任务。这将基于您在参数中指定的正则表达式/分隔符将其拆分为数组。像这样的东西,

String.split()

然后您可以将这些值相加。你知道一小时有60分钟,一分钟有60秒。您可以将这些转换为小时,分别除以60和3600。然后,这只是一个简单的补充问题。