用户在Java中定义的日期时间输入

时间:2018-11-27 03:22:31

标签: java datetime calendar date-difference

我想以以下格式输入日期和时间,并需要计算两者之间的时差,有人可以建议如何以字符串以下作为输入并计算时差。

java中用户定义的日期时间输入

String startTime= "11/27/2018+09:00:00";
String endTime= "11/28/2018+13:00:00";

+是分隔符(不是加号或减号的符号)。

2 个答案:

答案 0 :(得分:1)

无意义的输入

String startTime= "11/27/2018+09:00";
String endTime= "11/28/2018+13:00";

这些输入没有意义。将+09:00之类的offset-from-UTC应用于11/27/2018之类的日期没有意义。

要使偏移具有含义,您需要一个日期和一个日期

我们可以猜测一下,并且假设发送数据的人意味着一天的第一时刻。如果是这样的话,他们应该这样说,将其包括在数据中。

此处的窍门是,某些时区中的某些日期并非总是在一天中的00:00:00开始。诸如Daylight Saving Time (DST)之类的异常表示一天可能在诸如01:00:00之类的时间开始。不幸的是,您的输入仅包含offset(时分秒数),而不是时区(Continent/Region名称)。 time zone是特定地区人民过去,现在和将来对偏移量的更改历史。没有时区,我们将无法查找规则以了解异常。

您能做的最好的事情就是假设这一天从00:00:00开始,而忽略任何异常情况。但这是猜测,是不可取的。真正的解决方案是在交换日期时间值时就数据发布者进行两件事的教育:(a)使用UTC而不是偏移量或区域,并且(b)以标准ISO 8601格式编写字符串。

猜测工作

如果纠正此数据的来源不可行,那么我们可以进行猜测。

提取日期,与偏移量分开。

String input = "11/27/2018+09:00";
DateTimeFormatter f = DateTimeFormatter.ofPattern( "MM/dd/uuuu" );
LocalDate localDate = LocalDate.parse( input.substring( 0 , 10 ) , f );
ZoneOffset zoneOffset = ZoneOffset.of( input.substring( 11 ) );
  

localDate.toString():2018-11-27

     

zoneOffset.toString():+09:00

OffsetDateTime odt = OffsetDateTime.of( localDate , LocalTime.MIN , zoneOffset );
  

2018-11-27T00:00 + 09:00

我们可以将经过时间计算为Duration。但是要提防,如果没有时区的上下文,我们就无法考虑该时间段内可能发生的任何异常,如上所述。仅使用偏移量而不是区域,使用通用的24小时制进行计算。因此,再次,这只是草率的猜测,而不是可靠的解决方案。

Duration d = Duration.between( odt , odtLater ) ; 

关于 java.time

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

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

要了解更多信息,请参见Oracle Tutorial。并在Stack Overflow中搜索许多示例和说明。规格为JSR 310

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

在哪里获取java.time类?

ThreeTen-Extra项目使用其他类扩展了java.time。该项目为将来可能在java.time中添加内容提供了一个试验场。您可能会在这里找到一些有用的类,例如IntervalYearWeekYearQuartermore

答案 1 :(得分:0)

在Java 8中有:
LocalDateTime:如果需要处理日期和时间,请使用此选项。
LocalDate:如果您只需要处理日期,请使用它。
ZonedDateTime:如果您需要处理带时区的日期时间,请使用此选项。
OffsetDateTime:如果您需要处理带偏移的日期时间,请使用此选项。 (最适合您的情况)

您的案例仅使用日期和偏移量,这有点棘手,因为时区和偏移量只能应用于LocalDateTime(不仅是日期)。

但是,我认为您可以这样解决:

创建一个将日期字符串转换为OffsetDateTime的方法,如下所示:

private static OffsetDateTime createZonedDateTime (String dateWithTimeOffset)
{
    //TODO: assert that dateWithTimeOffset is valid
    String date = dateWithTimeOffset.substring (0, 10);
    String timeOffset = dateWithTimeOffset.substring (10, 13);

    //define your date pattern
    DateTimeFormatter formatter = DateTimeFormatter.ofPattern ("MM/dd/yyyy");

    return LocalDate.parse (date, formatter) // create LocalDate
                .atStartOfDay () // convert it to LocalDateTime with time 00:00:00
                .atOffset (ZoneOffset.of(timeOffset)); // apply the offset
}

然后,您可以像这样简单地创建OffsetDateTime

OffsetDateTime startTime = stringToZonedDateTime ("11/27/2018+09:00");  
OffsetDateTime endTime = stringToZonedDateTime ("11/28/2018+13:00");

您可以使用OffsetDateTime创建持续时间,如下所示:

Duration duration = Duration.between (startTime, endTime);

持续时间具有与持续时间相关的一切,例如:

duration.toHours () // will give you the hour duration