求教关于计算时间差,多谢

bsd 2003-11-25 01:33:14
有两个Date对象如何计算二者相差多少个小时,多少天,多少个星期,多少月
比如
"2003/11/23 23:00:00"与"2003/11/24 01:00:00"之间相差
2个小时,1天,一个星期...

注:此处直接用long取毫秒求差值然后再除以每天多少小时多少秒之类的做法并不适合
...全文
59 32 点赞 打赏 收藏 举报
写回复
32 条回复
切换为时间正序
当前发帖距今超过3年,不再开放新的回复
发表回复
zhang21cnboy 2003-11-28
赫赫、这样的算法,都讨论的热火朝天。充分说明大家的水平进步了。。。。。。。。。。。。。。

  • 打赏
  • 举报
回复
thuers 2003-11-28
学习来了。
  • 打赏
  • 举报
回复
haoren0625 2003-11-28
学习
  • 打赏
  • 举报
回复
bsd 2003-11-27
贴一下偶的做法,共同探讨:)

public static long dateDiff(String part, Calendar startCal, Calendar endCal) {
long deltaMs = endCal.getTimeInMillis() - startCal.getTimeInMillis();

if ("MILLISECOND".equalsIgnoreCase(part)) {
return deltaMs;
}

int reverse = 1;
if(startCal.after(endCal)){ //if start time is after the end time
reverse = -1;
deltaMs = -deltaMs;
Calendar tmp = startCal;
startCal = endCal;
endCal = tmp;
}

long res = 0;

if ("YEAR".equalsIgnoreCase(part)) {
res = endCal.get(Calendar.YEAR) - startCal.get(Calendar.YEAR);
} else if ("MONTH".equalsIgnoreCase(part)) {
int year = endCal.get(Calendar.YEAR) - startCal.get(Calendar.YEAR);
res += year * 12;
res += endCal.get(Calendar.MONTH) - startCal.get(Calendar.MONTH);
} else if ("WEEK".equalsIgnoreCase(part)) {
res += deltaMs / (7 * 24 * 3600 * 1000);
int w = startCal.get(Calendar.DAY_OF_WEEK);
int tmp = (int)(deltaMs % (7*24*3600*1000));
startCal.add(Calendar.MILLISECOND,tmp);
int w2 = startCal.get(Calendar.DAY_OF_WEEK);
if(w2<w || (w2 == w && tmp>(24*3600*1000))){
res++;
}
} else{
long base = 0;
int type = 0;
if ("DAY".equalsIgnoreCase(part)) {
type = Calendar.DATE;
base = 24 * 3600 * 1000;
} else if ("HOUR".equalsIgnoreCase(part)) {
type = Calendar.HOUR;
base = 3600 * 1000;
} else if ("MINUTE".equalsIgnoreCase(part)) {
type = Calendar.MINUTE;
base = 60 * 1000;
} else if ("SECOND".equalsIgnoreCase(part)) {
type = Calendar.SECOND;
base = 1000;
}else{
return Long.MIN_VALUE;
}
int cur = startCal.get(type);
res = deltaMs / base;
int tmp = (int)(deltaMs % base);
startCal.add(Calendar.MILLISECOND,tmp);
if(startCal.get(type)!=cur){
res++;
}
}

return res*reverse;
}
  • 打赏
  • 举报
回复
zjq1980 2003-11-27
算了,实在是小问题,楼上的楼上正确(天数,其它没测)
  • 打赏
  • 举报
回复
zjq1980 2003-11-27
楼上言重了 :)

求星期的方式与我的基本相同
不过求天数的还有个小问题,请再仔细斟酌。
  • 打赏
  • 举报
回复
zjq1980 2003-11-27
楼主考虑全面(没测试)
  • 打赏
  • 举报
回复
wobelisk 2003-11-27
请读说明。
调用方式:
DateDiff.dateDiff("day",c1,c2);

再有bug, 自己捉。本人不再修改。可以发邮件, 上面有地址。

  • 打赏
  • 举报
回复
wobelisk 2003-11-27
我丢人啊,我不活啦。这么EASY的问题居然连贴俩贴都有虫虫。我可是三天学完JAVA,还懂.jar的啊。昨日按SQLSERVER 的 dateDiff() 测试了一下代码,修正了大大小小一堆bug。最终版本如下。当当当当,隆重推出 dateDiff()。

/*
* @(#)DateDiff.java 1.00 11/26/2003
*
*/
import java.util.Calendar;
/**
*
*
* Copyright 2003 Wobelisk. All rights reserved.
* Free Use. No response for damage caused by errors of this file.
* <p>
* dateDiff() function similar to ms sqlserver. Calculate difference between two
* Calendars. Difference can be represented by day,week,hour,minute and second.
*
* <p>
* The difference between "2003-11-22 23:59:59" and "2003-11-23 00:00:00" is
* 1 day, or 1 week, or 1 hour, or 1 minute or 1 second
* <p>
* Default week difference is based on the rule that Sunday as the first day of
* the week. In France or China where Monday is the first day of week, you
* should set the first day of week to Monday before calculation. For Example,
* <pre>
* Calendar c1=Calendar.getInstance();
* Calendar c2=Calendar.getInstance();
* c1.set(2003,10,23,23,0,0); //Sunday 2003-11-23 23:00:00
* c2.set(2003,10,24,1,0,0); //Monday 2003-11-24 01:00:00
* dateDiff("week",c1,c2); //week difference between c1 and c2 is 0 week
* c1.setFirstDayOfWeek(Calendar.MONDAY);
* c2.setFirstDayOfWeek(Calendar.MONDAY);
* dateDiff("week",c1,c2); //week difference between c1 and c2 is 1 week
* </pre>
*
* setFirstDayOfWeek() only affects week difference
*
* @author Wobelisk@163.com
* @version 1.00 11/26/2003
*
*/


public class DateDiff{
/**
* Calculate Calendar c2 - Calendar c1
* @param s the String represents type of difference: day, week, hour,
* minute, second. String is case-insensitive
* @param c1 the Calendar instance
* @param c2 the Calendar instance
*/

public static long dateDiff(String s,Calendar c1, Calendar c2){
String s1=s.toUpperCase();
if(s1.equals("DAY")){
Calendar c11=Calendar.getInstance();
Calendar c21=Calendar.getInstance();
c11.set(c1.get(Calendar.YEAR),c1.get(Calendar.MONTH),c1.get(Calendar.DAY_OF_MONTH),0,0,0);
c21.set(c2.get(Calendar.YEAR),c2.get(Calendar.MONTH),c2.get(Calendar.DAY_OF_MONTH),0,0,0);
return (c21.getTimeInMillis()-c11.getTimeInMillis())/(1000*24*3600);
} else if(s1.equals("WEEK")){
long base=dateDiff("DAY",c1,c2);
int dw1=c1.get(Calendar.DAY_OF_WEEK);
int dw2=c2.get(Calendar.DAY_OF_WEEK);

if(c1.getFirstDayOfWeek()==Calendar.MONDAY && dw1==Calendar.SUNDAY)
dw1+=7;
if(c2.getFirstDayOfWeek()==Calendar.MONDAY && dw2==Calendar.SUNDAY)
dw2+=7;
if(base>0 && dw2<dw1)
return base/7+1;
else if(base<0 && dw2>dw1)
return base/7-1;
else
return base/7;
} else if(s1.equals("HOUR")){
return dateDiff("DAY",c1,c2)*24+c2.get(Calendar.HOUR_OF_DAY)-c1.get(Calendar.HOUR_OF_DAY);
} else if(s1.equals("MINUTE")){
return dateDiff("HOUR",c1,c2)*60+c2.get(Calendar.MINUTE)-c1.get (Calendar.MINUTE);
} else if(s1.equals("SECOND")){
return dateDiff("MINUTE",c1,c2)*60+c2.get(Calendar.SECOND)-c1.get(Calendar.SECOND);
} else
return Long.MIN_VALUE; //error
}
}
  • 打赏
  • 举报
回复
zjq1980 2003-11-26
我现在的实现是用循环(小的日期一直加到不小于大的日期)
实在太蠢,不过不会出错
只是效率太低
要么就是判断两个日期之间的所有的月的天数(不过这样的效率也不见得高到哪去)

至于星期,我目前用相差天数和一个日期的星期数来计算(因为楼主要求2003/11/23与2003/11/24不在一个星期)

继续等待大家的意见。
  • 打赏
  • 举报
回复
bsd 2003-11-26
to wobelisk() ,
对不起,我给错例子了,你的代码中处理天数的这个分支
return (int)
Math.ceil((Math.abs(c1.getTimeInMillis()-c2.getTimeInMillis()))/(1000*24*3600.0));
会有问题,即如果year不同
举个例子
2003/11/25 00:00:01 跟 2004/11/26 23:59:59
算起来结果会比期望值多1天
  • 打赏
  • 举报
回复
zjq1980 2003-11-26
to wobelisk() ,
试下2002/11/25 00:00:01 跟 2003/11/26 23:59:59
  • 打赏
  • 举报
回复
wobelisk 2003-11-26
2003/11/25 00:00:01 跟 2003/11/26 23:59:59:

my output is
1 day
47 hours
2879 minutes
172798 seconds

  • 打赏
  • 举报
回复
bsd 2003-11-26
to wobelisk() ,
你的写法按天数计算还会有问题,所以后面涉及到它的都会有影响
举个例子
2003/11/25 00:00:01 跟 2003/11/26 23:59:59
算起来结果会是两天,而期望值是1天
  • 打赏
  • 举报
回复
wobelisk 2003-11-26
public int dateDiff(String s,Calendar c1, Calendar c2){
String s1=s.toUpperCase();
if(s1.equals("DAY")){
if(c1.get(Calendar.YEAR)==c2.get(Calendar.YEAR))
return c1.get(Calendar.DAY_OF_YEAR)-c2.get(Calendar.DAY_OF_YEAR);
else
return (int)
Math.ceil((Math.abs(c1.getTimeInMillis()-c2.getTimeInMillis()))/(1000*24*3600.0));
} else if(s1.equals("HOUR")){

return dateDiff("DAY",c1,c2)*24+c1.get(Calendar.HOUR_OF_DAY)-c2.get(Calendar.HOUR_OF_DAY);
//return c1.get(Calendar.HOUR_OF_DAY)-c2.get(Calendar.HOUR_OF_DAY);
} else if(s1.equals("MINUTE")){
return dateDiff("HOUR",c1,c2)*60+c1.get(Calendar.MINUTE)-c2.get(Calendar.MINUTE);
} else if(s1.equals("SECONDS")){
return dateDiff("MINUTE",c1,c2)*60+c1.get(Calendar.SECOND)-c2.get(Calendar.SECOND);
} else
return Integer.MIN_VALUE; //error
}
  • 打赏
  • 举报
回复
bsd 2003-11-26
感觉做起来求相差的年、月、毫秒都相对容易些,求星期的略为复杂一点,其它的做法都差不多
  • 打赏
  • 举报
回复
zjq1980 2003-11-26
楼上不正确

我觉得相差的年数相对较容易些,而月数、天数则相对较复杂,其中尤以天数最复杂
知道了相差的天数,再求相差的小时数,分数,秒数甚至毫秒数都是顺理成章的了
诸位用毫秒来取天数的做法肯定不能满足楼主的要求
现在已经成功取得相差天数(测试中...),正在为星期数努力

TO wobelisk() :
8点和9点不是相差1小时吗?
  • 打赏
  • 举报
回复
leshui 2003-11-26
http://www.csdn.net/develop/read_article.asp?id=20844
  • 打赏
  • 举报
回复
wobelisk 2003-11-26
不管是8:59:59与9:00:00
还是8:00:00与9:00:00
它们相差的值如果以秒计
分别为1和3600秒
如果以分计分别为1和60分
如果以小时计均为1小时
//9:00:00 - 8:59:59 = 1second= 1小时

比如8:00:01与9:59:59
按小时计希望得到的差值是1
//9:59:59-8:00:01 = 1hour59minutes58seconds= (you also want 1小时)

what do you really want?

  • 打赏
  • 举报
回复
zjq1980 2003-11-26
关注
  • 打赏
  • 举报
回复
加载更多回复
相关推荐
发帖
Java SE
加入

6.2w+

社区成员

Java 2 Standard Edition
申请成为版主
帖子事件
创建了帖子
2003-11-25 01:33
社区公告
暂无公告