我想以小时/分钟/秒为单位计算两个日期之间的时差。
我的代码在这里有一个小问题,它是:
String dateStart = "11/03/14 09:29:58";
String dateStop = "11/03/14 09:33:43";
// Custom date format
SimpleDateFormat format = new SimpleDateFormat("yy/MM/dd HH:mm:ss");
Date d1 = null;
Date d2 = null;
try {
d1 = format.parse(dateStart);
d2 = format.parse(dateStop);
} catch (ParseException e) {
e.printStackTrace();
}
// Get msec from each, and subtract.
long diff = d2.getTime() - d1.getTime();
long diffSeconds = diff / 1000;
long diffMinutes = diff / (60 * 1000);
long diffHours = diff / (60 * 60 * 1000);
System.out.println("Time in seconds: " + diffSeconds + " seconds.");
System.out.println("Time in minutes: " + diffMinutes + " minutes.");
System.out.println("Time in hours: " + diffHours + " hours.");
这应该产生:
Time in seconds: 45 seconds.
Time in minutes: 3 minutes.
Time in hours: 0 hours.
但是我得到这个结果:
Time in seconds: 225 seconds.
Time in minutes: 3 minutes.
Time in hours: 0 hours.
在这里有人能看到我在做什么错吗?
#1 楼
请尝试long diffSeconds = diff / 1000 % 60;
long diffMinutes = diff / (60 * 1000) % 60;
long diffHours = diff / (60 * 60 * 1000);
注意:这假设
diff
是非负的。评论
@ vels4j我假设我刚刚添加的原始代码的第三行。感谢您指出这一点。
– Peter Lawrey
18年3月3日,11:43
但是diffMinutes仍然是错误的
–vels4j
18年3月3日,12:10
@ vels4j用什么方式?
– Peter Lawrey
18年3月3日在15:32
我已经更新了答案,请检查一下。澄清后放弃我的编辑
–vels4j
18年11月8日在6:05
@ vels4j您说的是错误的,因为6似乎是正确的答案,因为您在OPs问题中也有几个小时。
– Peter Lawrey
18年11月8日在9:47
#2 楼
我宁愿使用建议的java.util.concurrent.TimeUnit
类。long diff = d2.getTime() - d1.getTime();//as given
long seconds = TimeUnit.MILLISECONDS.toSeconds(diff);
long minutes = TimeUnit.MILLISECONDS.toMinutes(diff);
评论
@马克我不同意。您错过了问题的重点。尽管在帖子的其余部分中使用了“以秒为单位的时间”这一短语,但他明确表示实际上并不需要简单的转换,但他需要余数。这比接受的答案(使用方法调用,即使在JVM字节码中也包含一些指令)的效率低,不清楚(它更长,并且坦率地说,如果在此上下文中发现“ 1000”或“ 60”是幻数),则效率较低。 ,他们无法使用完整的平台),并且,从根本上讲,它无法满足OP的要求。
–Parthian Shot
2014年8月8日在17:25
有一种方法可以为此编写通用方法。见stackoverflow.com/a/10650881/82609
–塞巴斯蒂安·洛伯(Sebastien Lorber)
16年1月29日在10:20
如果我想要,相差数周,数月,数年?
– jose920405
2016年9月15日16:51
@ jose920405在这种情况下,您需要乔达时间
–约翰·亨克尔(John Henckel)
17年6月29日在21:13
这将给OP指定他们不想要的答案。
– Peter Lawrey
18年3月3日在15:33
#3 楼
如果您能够使用外部库,则建议您使用Joda-Time,请注意:Joda-Time是Java之前的Java的事实上的标准日期和时间库。 SE 8.现在,要求用户迁移到java.time(JSR-310)。
计算示例:
Seconds.between(startDate, endDate);
Days.between(startDate, endDate);
评论
请注意,如果要处理2个java.util.Date对象,则需要使用Days.daysBetween(LocalDate.fromDateFields(startDate),LocalDate.fromDateFields(endDate)));
–user799188
2012年10月9日3:00
我创建了一个如何使用乔达时间的示例:stackoverflow.com/a/15541322/562769
–马丁·托马
13年3月21日在7:53
目前的做法是什么? (使用JSR-310)
–static_rtti
18 Mar 29 '18 at 10:27
#4 楼
从Java 5开始,您可以使用java.util.concurrent.TimeUnit
避免在代码中使用诸如1000和60之类的幻数。顺便说一句,在计算时应格外注意:一年可能还会有额外的leap秒,因此实际上持续了61秒,而不是预期的60秒。 ISO规范甚至可能计划61秒钟。您可以在
java.util.Date
javadoc中找到详细信息。评论
除非有充分的商业理由将那些飞跃的秒数包括在内,否则您会很安全地将它们视为有趣但又不重要的科学好奇心。
–食指
13年4月16日在2:44
我同意“ le秒”是个小技巧。但是,夏时制或时区差异又如何呢?
–伊夫·马丁(Yves Martin)
13年5月3日在10:28
@YvesMartin“时区差异”看看他的日期格式。没有时区的地方。如果他确实希望跨时区工作,那么他将面临更大的问题。但是,夏令时是一个问题。
–Parthian Shot
2014年8月8日在17:29
«它的确持续60秒,而不是预期的59秒»您的意思是它持续61秒(0..60),而不是预期的60秒(0..59)。 ;)
– Andrea Lazzarotto
16年5月24日在11:45
修正了我的评论...一个经典的纠察队/间距问题!感谢您指出
–伊夫·马丁(Yves Martin)
16年5月24日15:15
#5 楼
尝试以下操作以方便地表示时差(以毫秒为单位):String friendlyTimeDiff(long timeDifferenceMilliseconds) {
long diffSeconds = timeDifferenceMilliseconds / 1000;
long diffMinutes = timeDifferenceMilliseconds / (60 * 1000);
long diffHours = timeDifferenceMilliseconds / (60 * 60 * 1000);
long diffDays = timeDifferenceMilliseconds / (60 * 60 * 1000 * 24);
long diffWeeks = timeDifferenceMilliseconds / (60 * 60 * 1000 * 24 * 7);
long diffMonths = (long) (timeDifferenceMilliseconds / (60 * 60 * 1000 * 24 * 30.41666666));
long diffYears = timeDifferenceMilliseconds / ((long)60 * 60 * 1000 * 24 * 365);
if (diffSeconds < 1) {
return "less than a second";
} else if (diffMinutes < 1) {
return diffSeconds + " seconds";
} else if (diffHours < 1) {
return diffMinutes + " minutes";
} else if (diffDays < 1) {
return diffHours + " hours";
} else if (diffWeeks < 1) {
return diffDays + " days";
} else if (diffMonths < 1) {
return diffWeeks + " weeks";
} else if (diffYears < 1) {
return diffMonths + " months";
} else {
return diffYears + " years";
}
}
评论
在线上long diffYears =(long)(timeDifferenceMilliseconds /(60 * 60 * 1000 * 24 * 365));您需要稍后进行长时间转换,否则除数为int并溢出:diffYears =(timeDifferenceMilliseconds /((long)60 * 60 * 1000 * 24 * 365));
– Pavel Niedoba
16年4月14日在13:38
我已经修复了代码
– Pavel Niedoba
16年4月14日在14:13
#6 楼
基本上,这比Java问题更多是数学问题。您收到的结果是正确的。这是因为225秒是3分钟(进行整数除法时)。您想要的是这样的:
除以1000得到秒数->休息是毫秒
除以60得到分钟数->休息是seconds
用60除以得到小时数->休息是分钟
或在java中:
int millis = diff % 1000;
diff/=1000;
int seconds = diff % 60;
diff/=60;
int minutes = diff % 60;
diff/=60;
hours = diff;
#7 楼
这是一个建议,使用TimeUnit
来获取每个时间部分并将其格式化。private static String formatDuration(long duration) {
long hours = TimeUnit.MILLISECONDS.toHours(duration);
long minutes = TimeUnit.MILLISECONDS.toMinutes(duration) % 60;
long seconds = TimeUnit.MILLISECONDS.toSeconds(duration) % 60;
long milliseconds = duration % 1000;
return String.format("%02d:%02d:%02d,%03d", hours, minutes, seconds, milliseconds);
}
SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss,SSS");
Date startTime = sdf.parse("01:00:22,427");
Date now = sdf.parse("02:06:38,355");
long duration = now.getTime() - startTime.getTime();
System.out.println(formatDuration(duration));
结果是:01:06:15,928
评论
谢谢你的作品
–菲利普
8月21日3:06
#8 楼
使用您的时间差作为构造函数创建一个Date
对象,然后使用Calendar方法获取值..
Date diff = new Date(d2.getTime() - d1.getTime());
Calendar calendar = Calendar.getInstance();
calendar.setTime(diff);
int hours = calendar.get(Calendar.HOUR_OF_DAY);
int minutes = calendar.get(Calendar.MINUTE);
int seconds = calendar.get(Calendar.SECOND);
评论
这些方法已被弃用。
– djechlin
13年2月14日在23:15
工作正常,但您一定不要忘记设置TimeZone:Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone(“ UTC”));
– Amra
13年7月11日在13:19
#9 楼
我知道这是一个老问题,但是我最终做了一些与接受的答案略有不同的事情。人们谈论TimeUnit
类,但是以OP想要的方式使用它没有任何答案。因此,这是另一个解决方案,如果有人错过了它;-)
public class DateTesting {
public static void main(String[] args) {
String dateStart = "11/03/14 09:29:58";
String dateStop = "11/03/14 09:33:43";
// Custom date format
SimpleDateFormat format = new SimpleDateFormat("yy/MM/dd HH:mm:ss");
Date d1 = null;
Date d2 = null;
try {
d1 = format.parse(dateStart);
d2 = format.parse(dateStop);
} catch (ParseException e) {
e.printStackTrace();
}
// Get msec from each, and subtract.
long diff = d2.getTime() - d1.getTime();
long days = TimeUnit.MILLISECONDS.toDays(diff);
long remainingHoursInMillis = diff - TimeUnit.DAYS.toMillis(days);
long hours = TimeUnit.MILLISECONDS.toHours(remainingHoursInMillis);
long remainingMinutesInMillis = remainingHoursInMillis - TimeUnit.HOURS.toMillis(hours);
long minutes = TimeUnit.MILLISECONDS.toMinutes(remainingMinutesInMillis);
long remainingSecondsInMillis = remainingMinutesInMillis - TimeUnit.MINUTES.toMillis(minutes);
long seconds = TimeUnit.MILLISECONDS.toSeconds(remainingSecondsInMillis);
System.out.println("Days: " + days + ", hours: " + hours + ", minutes: " + minutes + ", seconds: " + seconds);
}
}
尽管可以自己计算出差异,但这样做并不是很有意义,我认为
TimeUnit
是一个被人们高度忽视的类。评论
谢谢!我以同样的方式思考,但是您加快了速度:)
– Akbolat SSS
19年11月23日在16:56
#10 楼
Java中两个日期之间的差异从链接中提取代码
public class TimeDiff {
/**
* (For testing purposes)
*
*/
public static void main(String[] args) {
Date d1 = new Date();
try { Thread.sleep(750); } catch(InterruptedException e) { /* ignore */ }
Date d0 = new Date(System.currentTimeMillis() - (1000*60*60*24*3)); // About 3 days ago
long[] diff = TimeDiff.getTimeDifference(d0, d1);
System.out.printf("Time difference is %d day(s), %d hour(s), %d minute(s), %d second(s) and %d millisecond(s)\n",
diff[0], diff[1], diff[2], diff[3], diff[4]);
System.out.printf("Just the number of days = %d\n",
TimeDiff.getTimeDifference(d0, d1, TimeDiff.TimeField.DAY));
}
/**
* Calculate the absolute difference between two Date without
* regard for time offsets
*
* @param d1 Date one
* @param d2 Date two
* @param field The field we're interested in out of
* day, hour, minute, second, millisecond
*
* @return The value of the required field
*/
public static long getTimeDifference(Date d1, Date d2, TimeField field) {
return TimeDiff.getTimeDifference(d1, d2)[field.ordinal()];
}
/**
* Calculate the absolute difference between two Date without
* regard for time offsets
*
* @param d1 Date one
* @param d2 Date two
* @return The fields day, hour, minute, second and millisecond
*/
public static long[] getTimeDifference(Date d1, Date d2) {
long[] result = new long[5];
Calendar cal = Calendar.getInstance();
cal.setTimeZone(TimeZone.getTimeZone("UTC"));
cal.setTime(d1);
long t1 = cal.getTimeInMillis();
cal.setTime(d2);
long diff = Math.abs(cal.getTimeInMillis() - t1);
final int ONE_DAY = 1000 * 60 * 60 * 24;
final int ONE_HOUR = ONE_DAY / 24;
final int ONE_MINUTE = ONE_HOUR / 60;
final int ONE_SECOND = ONE_MINUTE / 60;
long d = diff / ONE_DAY;
diff %= ONE_DAY;
long h = diff / ONE_HOUR;
diff %= ONE_HOUR;
long m = diff / ONE_MINUTE;
diff %= ONE_MINUTE;
long s = diff / ONE_SECOND;
long ms = diff % ONE_SECOND;
result[0] = d;
result[1] = h;
result[2] = m;
result[3] = s;
result[4] = ms;
return result;
}
public static void printDiffs(long[] diffs) {
System.out.printf("Days: %3d\n", diffs[0]);
System.out.printf("Hours: %3d\n", diffs[1]);
System.out.printf("Minutes: %3d\n", diffs[2]);
System.out.printf("Seconds: %3d\n", diffs[3]);
System.out.printf("Milliseconds: %3d\n", diffs[4]);
}
public static enum TimeField {DAY,
HOUR,
MINUTE,
SECOND,
MILLISECOND;
}
}
评论
好。时间偏移量很重要-即使根据相同的偏移量计算出差异,但两个“日历日期”之间的任何夏时制差异也会对结果产生影响。您应该使用java.util.concurrent.TimeUnit作为常量。
–伊夫·马丁(Yves Martin)
13年5月3日在10:26
#11 楼
// d1, d2 are dates
long diff = d2.getTime() - d1.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);
System.out.print(diffDays + " days, ");
System.out.print(diffHours + " hours, ");
System.out.print(diffMinutes + " minutes, ");
System.out.print(diffSeconds + " seconds.");
#12 楼
Joda-TimeJoda-Time 2.3库提供了已经调试好的此杂物的代码。
Joad-Time包括三个代表时间跨度的类:
Period
,Interval
,和Duration
。 Period
跟踪跨度为月,日,小时等(不与时间轴相关)。 // © 2013 Basil Bourque. This source code may be used freely forever by anyone taking full responsibility for doing so.
// Specify a time zone rather than rely on default.
// Necessary to handle Daylight Saving Time (DST) and other anomalies.
DateTimeZone timeZone = DateTimeZone.forID( "America/Montreal" );
DateTimeFormatter formatter = DateTimeFormat.forPattern( "yy/MM/dd HH:mm:ss" ).withZone( timeZone );
DateTime dateTimeStart = formatter.parseDateTime( "11/03/14 09:29:58" );
DateTime dateTimeStop = formatter.parseDateTime( "11/03/14 09:33:43" );
Period period = new Period( dateTimeStart, dateTimeStop );
PeriodFormatter periodFormatter = PeriodFormat.getDefault();
String output = periodFormatter.print( period );
System.out.println( "output: " + output );
运行时…
output: 3 minutes and 45 seconds
#13 楼
这是我的代码。import java.util.Date;
// to calculate difference between two days
public class DateDifference {
// to calculate difference between two dates in milliseconds
public long getDateDiffInMsec(Date da, Date db) {
long diffMSec = 0;
diffMSec = db.getTime() - da.getTime();
return diffMSec;
}
// to convert Milliseconds into DD HH:MM:SS format.
public String getDateFromMsec(long diffMSec) {
int left = 0;
int ss = 0;
int mm = 0;
int hh = 0;
int dd = 0;
left = (int) (diffMSec / 1000);
ss = left % 60;
left = (int) left / 60;
if (left > 0) {
mm = left % 60;
left = (int) left / 60;
if (left > 0) {
hh = left % 24;
left = (int) left / 24;
if (left > 0) {
dd = left;
}
}
}
String diff = Integer.toString(dd) + " " + Integer.toString(hh) + ":"
+ Integer.toString(mm) + ":" + Integer.toString(ss);
return diff;
}
}
#14 楼
long diffSeconds =(diff / 1000)%60;尝试一下,让我知道它是否正确运行...
#15 楼
好吧,我将尝试另一个代码示例:/**
* Calculates the number of FULL days between to dates
* @param startDate must be before endDate
* @param endDate must be after startDate
* @return number of day between startDate and endDate
*/
public static int daysBetween(Calendar startDate, Calendar endDate) {
long start = startDate.getTimeInMillis();
long end = endDate.getTimeInMillis();
// It's only approximation due to several bugs (@see java.util.Date) and different precision in Calendar chosen
// by user (ex. day is time-quantum).
int presumedDays = (int) TimeUnit.MILLISECONDS.toDays(end - start);
startDate.add(Calendar.DAY_OF_MONTH, presumedDays);
// if we still didn't reach endDate try it with the step of one day
if (startDate.before(endDate)) {
startDate.add(Calendar.DAY_OF_MONTH, 1);
++presumedDays;
}
// if we crossed endDate then we must go back, because the boundary day haven't completed yet
if (startDate.after(endDate)) {
--presumedDays;
}
return presumedDays;
}
#16 楼
Date startTime = new Date();
//...
//... lengthy jobs
//...
Date endTime = new Date();
long diff = endTime.getTime() - startTime.getTime();
String hrDateText = DurationFormatUtils.formatDuration(diff, "d 'day(s)' H 'hour(s)' m 'minute(s)' s 'second(s)' ");
System.out.println("Duration : " + hrDateText);
您可以使用Apache Commons Duration Format Utils。格式类似于SimpleDateFormatter
输出:
0 days(s) 0 hour(s) 0 minute(s) 1 second(s)
#17 楼
如前所述-认为这是一个很好的答案/**
* @param d2 the later date
* @param d1 the earlier date
* @param timeUnit - Example Calendar.HOUR_OF_DAY
* @return
*/
public static int getTimeDifference(Date d2,Date d1, int timeUnit) {
Date diff = new Date(d2.getTime() - d1.getTime());
Calendar calendar = Calendar.getInstance();
calendar.setTime(diff);
int hours = calendar.get(Calendar.HOUR_OF_DAY);
int minutes = calendar.get(Calendar.MINUTE);
int seconds = calendar.get(Calendar.SECOND);
if(timeUnit==Calendar.HOUR_OF_DAY)
return hours;
if(timeUnit==Calendar.MINUTE)
return minutes;
return seconds;
}
评论
这将失败,时间单位为分钟,时间差超过一小时
– Pavel Niedoba
16-2-26在23:29
评论
发现了类似的问题:stackoverflow.com/questions/625433/…有一种更好的方法:stackoverflow.com/a/15541322/562769
对于Java 8+,有一种真正简单的方法:stackoverflow.com/a/23176621/1548776