乔达时间总和各种时间

Joda Time sum various times

我正在使用 joda time 2.7,我需要以 LocalTime 格式添加几次,忽略 TimeZone 和 toDateTimeToday ;

示例:

输入(字符串 ... 次)

01:10 , 01:10 , 01:10 ,

01:10 , 01:10 , 01:10 , 01:10 , 01:10 , 01:10

预期输出(以 Millis 为单位)

03:30

或 预期输出 ( Millis )

07:00

我的想法

import org.joda.time.DateTimeZone;
import org.joda.time.Duration;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;

static long sumAccumulatedTimes( long... listTimes ){

    Duration duration = Duration.ZERO;
    DateTimeZone zone = DateTimeZone.getDefault();
    DateTimeFormatter fmt = DateTimeFormat.forPattern("HH:mm");
    for (int i = 0; i < listTimes.length; i++) { 
       duration = duration.plus( listTimes[i] ); // in iteration three, ocurred problems!
    } 
    long convertZone = zone.convertUTCToLocal( duration.getMillis() ); // Adjust TimeZone
    System.out.println("Output: " + fmt.print( convertZone  ) );
    return 0; // ignore !
 }




// Call method

  DateTimeFormatter fmt = DateTimeFormat.forPattern("HH:mm"); 
  sumAccumulatedTimes(  
       fmt.parseMillis("01:10"),
       fmt.parseMillis("01:10")//, up to here Ok (02:20 ouput), next inconsitent values 
      // fmt.parseMillis("01:10") // add three parameters, is ocurred problems
    );

编辑:更新

解决者 @Meno Hochschild

String[] input = { "12:00", "12:10" };
PeriodFormatter parser =
new PeriodFormatterBuilder()
.appendHours().appendLiteral(":")
.appendMinutes().toFormatter();
Period period = Period.ZERO;

for (String s : input) {
  period = period.plus(parser.parsePeriod(s));
 }

 PeriodFormatter printer =
  new PeriodFormatterBuilder()
  .printZeroAlways().minimumPrintedDigits(2)
 //.appendDays().appendLiteral(":") // remove original code
 .appendHours().appendLiteral(":")
 .appendMinutes().toFormatter();
 //System.out.println("duration=" +  // remove original code    //printer.print(period.normalizedStandard()));
// output: duration=01:00:10

 System.out.println("duration="                                        
  printer.print(period.normalizedStandard( PeriodType.time() )));
// output: duration= 24:10

其他解决方案,@Dexter :)

private static String sumAccumulatedTimes( String... times ){

    DateTimeFormatter fmt = DateTimeFormat.forPattern("HH:mm");
    DateTimeZone zone = DateTimeZone.getDefault();
    PeriodFormatter pformat = new PeriodFormatterBuilder()
                                    .minimumPrintedDigits(2)
                                    .printZeroAlways()
                                    .appendHours()
                                    .appendLiteral(":")
                                    .appendMinutes()
                                    .toFormatter();

    long sum = 0;  
    for ( String time : times ) { 
        long parseLong = fmt.parseMillis( time );
        sum += zone.convertUTCToLocal( parseLong ); 
    } 
    Period period = new Period( sum );  
    return period.toString(pformat);
}

乘以两个解决方案的总和,忽略时区不限制24小时

谢谢。

不要使用 DateTimeFormatter 来解析持续时间。该格式化程序专为格式化和解析时间点而设计,无法处理任何时间溢出,并且还会尝试破坏任何计算的持续时间 与时区问题 (问题的根本原因)。在我的时区 "Europe/Berlin",表达式 fmt.parseMillis("01:10") 只产生 10 分钟 - 而不是一小时十分钟。

改用持续时间格式化程序。在 Joda-Time 中,这称为 PeriodFormatter:

String[] input = { "01:10", "01:10", "01:10", "01:10", "01:10", "01:10" };
PeriodFormatter pf =
  new PeriodFormatterBuilder()
  .minimumPrintedDigits(2).printZeroAlways()
  .appendHours().appendLiteral(":").appendMinutes().toFormatter();
Period period = Period.ZERO;

for (String s : input) {
  period = period.plus(pf.parsePeriod(s));
}

System.out.println("duration=" + pf.print(period.normalizedStandard()));
// output: duration=07:00

在 OP 评论后更新(修复错误处理日溢出):

String[] input = { "12:00", "12:10" };
PeriodFormatter parser =
  new PeriodFormatterBuilder()
  .appendHours().appendLiteral(":")
  .appendMinutes().toFormatter();
Period period = Period.ZERO;

for (String s : input) {
  period = period.plus(parser.parsePeriod(s));
}

PeriodFormatter printer =
  new PeriodFormatterBuilder()
  .printZeroAlways().minimumPrintedDigits(2)
  .appendDays().appendLiteral(":")
  .appendHours().appendLiteral(":")
  .appendMinutes().toFormatter();
System.out.println("duration=" + printer.print(period.normalizedStandard()));
// output: duration=01:00:10

另一种修复方法是使用表达式 period.normalizedStandard(PeriodType.time()) 以便仅使用时钟单位。

你可以只加毫秒。

   static long sumAccumulatedTimes(String ... array)
   {
      long sum = 0;
      for (String time : array)
      {
         sum += new LocalTime(time).getMillisOfDay();
      }
      return sum;
   }

结果是一样的

UPD
使用 Joda API

将 long 转换为字符串
   static String millisToString(long millis)
   {
      long hours = millis / (1000 * 60 * 60);
      long minutes = (millis / (1000 * 60)) % 60;
      return hours + ":" + (minutes < 10 ? "0" : "") + minutes;
   }

@llya.

现在你的代码解决了这个问题! 但就我而言,它让我产生了 使用这么长的不兼容问题 在其他方法中 JODA .

例如

                                     //87600000
  static String parseMillisToTextTime( long time ){ 
      DateTimeFormatter fmt = DateTimeFormat.forPattern("HH:mm"); 
      return fmt.print(time); 
  } // ouput 21:20


    System.out.println(  LocalTime.fromMillisOfDay(87600000).toString("HH:mm") );
  // output 00:20


   LocalTime lt = new LocalTime(87600000);
  System.out.println("output: " + lt.toString("HH:mm"));
  // output 21:20

我改这个方法 维护负担重。

如果你想添加你的 根据这些观察结果的解决方案?