我尝试了下面的代码。
当开始时间和结束时间之间存在小时/日期差异时,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
.转换任何 Date
至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
提取天数、小时数等的方法。java.time
您正在使用可怕的旧日期时间类(
Date
、 Calendar
、 SimpleDateFormat
),这些类在几年前已被 java.time 类取代。Instant
显然您正在收到
java.util.Date
目的。如果可能,重写该代码以使用它的替换,java.time.Instant
目的。两者都代表 UTC 中的一个时刻,但 Instant
具有更精细的纳秒分辨率而不是毫秒。如果不可能,立即转换 Date
到 Instant
.调用添加到旧类的新转换方法。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 个字母的缩写,例如 EST
或 IST
因为它们不是真正的时区,不是标准化的,甚至不是唯一的(!)。// 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 类?
ThreeTen-Extra项目通过附加类扩展了 java.time。该项目是 future 可能添加到 java.time 的试验场。您可以在这里找到一些有用的类,例如
Interval
, YearWeek
, YearQuarter
, 和 more .
关于java时差输出负值和错误值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52672161/