使用Joda Time将简单的民用时间解析为完整的日期和时间

时间:2019-06-11 23:47:47

标签: java android time jodatime

我的时间间隔字符串为:

"04:00 PM - 04:30 PM"

我的目标是使用Joda Time将字符串解析为如下所示的开始时间和结束时间变量:

String startTime = "2019-06-11T04:00:00"

String endTime = "2019-06-11T04:30:00"

毫秒始终为00,我可以使用joda时间库轻松获取当前日期,但是从间隔字符串到最后两个字符串的完整实现方面,我遇到很多困难

感谢您的帮助!

我当前的尝试是:

String[] selectedTime = interval.split(" - ");
DateTimeFormatter parser = ISODateTimeFormat.dateTime();
DateTime dtStart = parser.parseDateTime(selectedTime[0]);
DateTimeFormatter formatter = DateTimeFormat.forPattern("yyyy-MM-dd'T'HH:mm:ss");
String startTime = formatter.print(dtStart);

我理解为什么这行不通,因为我没有传递所有必需的信息,例如年,月,日和毫秒。

2 个答案:

答案 0 :(得分:3)

仅供参考,Joda-Time项目现在位于maintenance mode中,建议迁移到java.time类。参见Tutorial by Oracle

java.time

您的输入缺少时区或UTC偏移量的指示符。因此,解析为LocalDateTime个对象。

您的输入文本为标准ISO 8601格式。在 java.time 类中,默认情况下使用这些标准格式来生成/解析字符串。因此,无需指定格式设置模式。

LocalDateTime ldt = LocalDateTime.parse( "2019-06-11T04:00:00" ) ;

您只需要时间,因此提取一个LocalTime对象。

LocalTime lt = ldt.toLocalTime() ;

通常最好让DateTimeFormatter类自动为您本地化。

Locale locale = Locale.CANADA_FRENCH ;  // Or Locale.US, Locale.ITALY, etc.
DateTimeFormatter f = DateTimeFormatter.ofLocalizedTime( FormatStyle.MEDIUM ).withLocale( locale ) ;
String output = lt.format( f ) + " — " + otherLt.format( f ) ;

否则,请根据需要指定特定的格式设置模式。

DateTimeFormatter f = DateTimeFormatter.ofPattern( "HH:mm a" , Locale.US ) ;
String output = lt.format( f ) + " to " + otherLt.format( f ) ;

早期的Android

大多数 java.time 功能都已在ThreeTen-Backport项目中反向移植到Java 6和Java 7。在ThreeTenABP中进一步适用于较早的Android(<26)。参见How to use ThreeTenABP…

对于Android 26及更高版本,内置了 java.time 的实现。

答案 1 :(得分:2)

Basil Bourque是正确的,与Joda-Time相比,您应该更喜欢Java.time(现代Java日期和时间API)。如果您已经大量使用Joda-Time,并且现在不想升级到java.time,那么这里是您问题的Joda-Time解决方案。 编辑:我已重写代码,以考虑到您的以下评论:

  

...您能否提供一些有关如何确定的帮助   结束时间-时区?在这种情况下,间隔将   来自“ 11:30 PM-12:00 AM”。现在,当前时间是11:30,所以   DateTimeZone将返回今天的日期。当我尝试生成   结束时间的字符串,它的日期将设置为今天的日期,但是   最后一个字符串应具有第二天的日期,因为它是   参考上午12:00。...

    String interval = "04:00 PM - 04:30 PM";
    String[] selectedTime = interval.split(" - ");
    DateTimeFormatter parser = DateTimeFormat.forPattern("hh:mm a");
    LocalDate today = new LocalDate(DateTimeZone.getDefault());
    LocalTime tStart = parser.parseLocalTime(selectedTime[0]);

    String startTime = today.toLocalDateTime(tStart).toString();
    System.out.println("Start time: " + startTime);

今天运行时输出为:

  

开始时间:2019-06-12T16:00:00.000

由于24小时制的下午4点是16点,因此我认为这是您想要的结果。如果要格式化的时间不以毫秒为单位,则只需格式化LocalDateTime即可获得与格式化问题中的dtStart相同的方式。

结束时间稍微复杂一点:

    LocalTime tEnd = parser.parseLocalTime(selectedTime[1]);
    String endTime;
    if (tEnd.isBefore(tStart)) {
        // Assume that end time is after midnight, that is, tomorrow
        endTime = today.plusDays(1).toLocalDateTime(tEnd).toString();
    } else {
        // The normal case: both start and end times are today
        endTime = today.toLocalDateTime(tEnd).toString();
    }
    System.out.println("End time: " + endTime);
  

结束时间:2019-06-12T16:30:00.000

如果相反,我们曾经有过

    String interval = "11:30 PM - 12:00 AM";
  

结束时间:2019-06-13T00:00:00.000

Joda-Time处于维护模式

Joda-Time主页上的报价:

  

请注意,Joda-Time被认为是很大程度上“完成”的项目。   没有计划进行重大增强。如果使用Java SE 8,请迁移   到java.time(JSR-310)。

https://www.joda.org/joda-time/

即使您是针对较旧的Android(API级别26以下)进行编码的,至少对于新代码,我还是希望对ThreeTenABP的依赖比对Joda-Time的依赖。