java时差输出负值和错误值

标签 java time simpledateformat duration

我尝试了下面的代码。
当开始时间和结束时间之间存在小时/日期差异时,java时间差输出负值和错误值

    Date d3 = null;
    Date d4 = null;
    List<String> activeTimeList = new ArrayList();
    int c = Integer.parseInt(cycle.get("Cycle No:").toString());
    try {
        for(int i = 0; i<c;i++) {
            SimpleDateFormat format = new SimpleDateFormat("MM-dd-yyyy HH:mm", Locale.US); //("MM/dd/yyyy HH:mm:ss");
            format.setTimeZone(TimeZone.getTimeZone("GMT"));
            String cycleEndTm = cycle.get("End Time"+i+"").toString().trim();
            String cycleStartTm = cycle.get("Start Time"+i+"").toString().trim();

            d3 = format.parse(cycleEndTm);
            d4 = format.parse(cycleStartTm);
            long diff =  d3.getTime() - d4.getTime();
            long diffSeconds = diff / 1000 % 60;
            long diffMinutes = diff / (60 * 1000) % 60;
            long diffHours = diff / (60 * 60 * 1000) % 24;
            long diffDays = diff / (24 * 60 * 60 * 1000);
            String time1 = diffDays+"."+diffHours+"."+diffMinutes+"."+diffSeconds;

Log :
0.-10.-7.0

d4 =02-11-2017 16:47
d3 =02-11-2017 17:27 差异​​ = 0.-10.-7.0
无法获得正确的时差?我在这里缺少什么?
注意**:cycleEndTm -cycleStarttime 应该给出肯定的结果。我正在阅读 cycleEndTime 并从 map 开始时间。这就是要求。

最佳答案

tl;博士

使用现代 java.time 类,永远不要Date .转换任何 Datejava.time.Instant .

Duration                              // Represent a span-of-time as 24-hour days, hours, minutes, seconds, and nanoseconds.
.between(                             // Calculate elapsed time.
    javaUtilDateStart.toInstant() ,   // Convert any `java.util.Date` to `java.time.Instant`. Never use `Date`; it is a terrible class, ditto for `Calendar`. 
    javaUtilDateStop.toInstant()
)                                      // Returns a `Duration` object.
.toString()                            // Generate text in standard ISO 8601 format.

或调用to…Part提取天数、小时数等的方法。

java.time

您正在使用可怕的旧日期时间类( DateCalendarSimpleDateFormat ),这些类在几年前已被 java.time 类取代。
Instant
显然您正在收到 java.util.Date目的。如果可能,重写该代码以使用它的替换,java.time.Instant目的。两者都代表 UTC 中的一个时刻,但 Instant具有更精细的纳秒分辨率而不是毫秒。如果不可能,立即转换 DateInstant .调用添加到旧类的新转换方法。
Instant instant = myJavaUtilDate.toInstant() ;  // Convert from legacy class to modern class. Same moment in UTC, same point on the timeline.

以标准 ISO 8601 生成表示该时刻的文本格式。

以 UTC 捕获当前时刻。
Instant now = Instant.now() ;  // Capture the current moment in UTC.
Duration
将耗时计算为 Duration 目的。同样,这具有纳秒级的分辨率。
Duration d = Duration.between( instant , now ) ;

以标准 ISO 8601 生成表示已用时间的文本格式。
String output = d.toString() ; 

或者创建您的字符串,将“天”定义为 24 小时的时间段,而不考虑日历。
long days = d.toDaysPart() ;
int hours = d.toHoursPart() ;
int minutes = d.toMinutesPart() ;
int seconds = d.toSecondsPart() ;

String output = days + "." + hours + "." + minutes + "." + seconds ;

解析字符串

您的问题不清楚您的输入。如果以字符串开头,则解析。首先,如果可能,更改这些字符串的来源以使用明智定义的 ISO 8601标准格式。如果不可能,请定义格式模式以匹配输入。
String inputStart = "02-10-2018 10.30";

DateTimeFormatter f = DateTimeFormatter.ofPattern( "dd-MM-uuuu HH.mm" );

将您的输入解析为 LocalDateTime 因为它缺少任何时区指示符或与 UTC 的偏移量。
LocalDateTime ldtStart = LocalDateTime.parse( inputStart , f ) ;

一个 LocalDateTime不是片刻,不代表时间线上的一个点。此类代表大约 26-27 小时范围内的潜在时刻,即全局时区范围。

分配该字符串的源所要的区域或偏移量,以提供确定时刻所需的上下文。

指定 proper time zone name格式为 continent/region ,如 America/Montreal , Africa/Casablanca , 或 Pacific/Auckland .切勿使用 2-4 个字母的缩写,例如 ESTIST因为它们不是真正的时区,不是标准化的,甚至不是唯一的(!)。
// Transform the indefinite `LocalDateTime` to a definite moment by assigning the time zone intended by that input string.
ZoneId z = ZoneId.of( "Africa/Tunis" );
ZonedDateTime zdtStart = ldtStart.atZone( z );

计算你过去的时间跨度。
Duration d = Duration.between( zdtStart , zdtStop ) ;

关于 java.time

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

Joda-Time项目,现在在 maintenance mode , 建议迁移到 java.time类。

要了解更多信息,请参阅 Oracle Tutorial .并在 Stack Overflow 上搜索许多示例和解释。规范为 JSR 310 .

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

从哪里获得 java.time 类?
  • Java SE 8 , Java SE 9 , Java SE 10 , Java SE 11 , 和更高版本 - 标准 Java API 的一部分,具有捆绑的实现。
  • Java 9 添加了一些小功能和修复。
  • Java SE 6Java SE 7
  • 大多数 java.time 功能在 ThreeTen-Backport 中向后移植到 Java 6 和 7。 .
  • Android
  • java.time 类的更高版本的 Android 捆绑实现。
  • 对于早期的 Android (<26),ThreeTenABP项目适应ThreeTen-Backport (上文提到的)。见 How to use ThreeTenABP… .

  • ThreeTen-Extra项目通过附加类扩展了 java.time。该项目是 future 可能添加到 java.time 的试验场。您可以在这里找到一些有用的类,例如 Interval , YearWeek , YearQuarter , 和 more .

    关于java时差输出负值和错误值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52672161/

    相关文章:

    java - 有没有类似于传统线程的onPreExecute和onPostExecute的东西?

    java - 尝试使用多个资源会导致 Sonar qube 问题

    java webapps 并将现有项目开源到 github - 属性文件

    java - 使用 Jackson 进行 XML 反序列化

    string - 如何从字符串中的给定日期找到工作日?

    javascript - 如何为此设置超时?

    time - gnuplot用x值标记特定的y数据点

    Java:解析并应用新模式后日期发生变化

    java - Java 中带有额外数字的无法解析的日期

    java - Android:我无法弄清楚 SimpleDateFormat