java时差输出负值和错误值 [英] java Time difference outputs negative value and wrong values

查看:120
本文介绍了java时差输出负值和错误值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I tried the below code. java Time difference outputs negative value and wrong values when there is hours/date difference between starttime and endtime

    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和开始时间.那就是要求.

d4 =02-11-2017 16:47
d3 =02-11-2017 17:27 Diff = 0.-10.-7.0 Not able to get correct time difference? What I am missing here? Note ** : cycleEndTm -cycleStarttime should be giving positive result. I am reading cycleEndTime and start time from a map. Thats the requirement.

推荐答案

tl; dr

使用现代的 java.time 类,而不要使用 Date .将任何 Date 转换为 java.time.Instant .

tl;dr

Use modern java.time classes, never Date. Convert any Date to java.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 方法以提取天数,小时数等.

Or call the to…Part methods to extract number of days, hours, and so on.

您使用的是可怕的旧日期时间类( Date Calendar SimpleDateFormat ),这些类在几年前被取代了java.time 类.

You are using terrible old date-time classes ( Date, Calendar, SimpleDateFormat ) that were supplanted years ago by the java.time classes.

显然,您将获得一个 java.util.Date 对象.如果可能,请重写该代码以使用其替换对象 java.time.Instant 对象.两者都代表UTC的时刻,但是 Instant 的分辨率更高,只有纳秒而不是毫秒.如果不可能,请立即将 Date 转换为 Instant .调用添加到旧类中的新转换方法.

Apparently you are being handed a java.util.Date object. If possible, rewrite that code to use its replacement, the java.time.Instant object. Both represent a moment in UTC, but Instant has a finer resolution of nanoseconds rather than milliseconds. If not possible, immediately convert the Date to an Instant. Call new conversion methods added to the old classes.

Instant instant = myJavaUtilDate.toInstant() ;  // Convert from legacy class to modern class. Same moment in UTC, same point on the timeline.

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

Generate text representing that moment in standard ISO 8601 format.

使用UTC捕获当前时刻.

Capture the current moment in UTC.

Instant now = Instant.now() ;  // Capture the current moment in UTC.

持续时间

将经过时间计算为 Duration 对象.同样,它具有纳秒级的分辨率.

Duration

Calculate elapsed time as a Duration object. Again, this has a resolution of nanoseconds.

Duration d = Duration.between( instant , now ) ;

以标准 ISO 8601 格式生成表示经过时间的文本.

Generate text representing that elapsed time in standard ISO 8601 format.

String output = d.toString() ; 

或者创建您的字符串,将天"定义为24小时制,而不考虑日历.

Or create your string, defining "days" as 24-hour chunks of time without regard for the calendar.

long days = d.toDaysPart() ;
int hours = d.toHoursPart() ;
int minutes = d.toMinutesPart() ;
int seconds = d.toSecondsPart() ;

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

解析字符串

您的问题不清楚您的输入内容.如果以字符串开头,则进行解析.首先,如果可能,请更改这些字符串的来源,以使用明智定义的 ISO 8601 标准格式.如果可能的话,请定义格式设置模式以匹配输入.

Parsing strings

Your Question is not clear about your inputs. If starting with strings, parse. Firstly, if possible, change the source of those strings to use the wisely-defined ISO 8601 standard formats. If not possible, define a formatting pattern to match the input.

String inputStart = "02-10-2018 10.30";

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

将输入内容解析为 LocalDateTime ,因为它缺少时区或UTC偏移量的任何指示.

Parse your input as a LocalDateTime because it lacks any indicator of a time zone or offset-from-UTC.

LocalDateTime ldtStart = LocalDateTime.parse( inputStart , f ) ;

LocalDateTime not 片刻, not 代表时间线上的一个点.此类表示大约26-27小时(全球时区范围)内的潜在时刻.

A LocalDateTime is not a moment, does not represent a point on the timeline. This class represents potential moments along a range of about 26-27 hours, the range of time zones around the globe.

指定该字符串的源所打算的区域或偏移量,以提供确定矩所需的上下文.

Assign the zone or offset intended by the source of that string, to give the context needed to determine a moment.

continent/region <格式>指定正确的时区名称./code>,例如 美国/蒙特利尔 非洲/卡萨布兰卡 Pacific/Auckland .切勿使用2-4个字母的缩写,例如 EST IST ,因为它们不是真正的时区,不是标准化的,甚至不是唯一的(!).

Specify a proper time zone name in the format of continent/region, such as America/Montreal, Africa/Casablanca, or Pacific/Auckland. Never use the 2-4 letter abbreviation such as EST or IST as they are not true time zones, not standardized, and not even unique(!).

// 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及更高版本中.这些类取代了麻烦的旧版日期时间类,例如 Calendar ,& SimpleDateFormat


About java.time

The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.

Joda-Time 项目,现在位于<一个href ="https://en.wikipedia.org/wiki/Maintenance_mode" rel ="nofollow noreferrer">维护模式,建议迁移到要了解更多信息,请参见 Oracle教程.并在Stack Overflow中搜索许多示例和说明.规范为 JSR 310 .

To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.

您可以直接与数据库交换 java.time 对象.使用符合 JDBC驱动程序/jeps/170"rel =" nofollow noreferrer> JDBC 4.2 或更高版本.不需要字符串,不需要 java.sql.* 类.

You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for java.sql.* classes.

在哪里获取java.time类?

Where to obtain the java.time classes?

  • Later versions of Android bundle implementations of the java.time classes.
  • For earlier Android (<26), the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See How to use ThreeTenABP….

> ThreeTen-Extra 项目扩展了java.time与其他班级.该项目为将来可能在java.time中添加内容提供了一个试验场.您可能会在这里找到一些有用的类,例如 间隔 年周" YearQuarter 更多

这篇关于java时差输出负值和错误值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆