计算两个日期之间的差异:未按预期工作

时间:2014-03-04 15:54:59

标签: java android date

这是我的代码:

public enum MILLI_CONVERSIONS {
//values in milliseconds
SECOND(1000),
MINUTE(1000*60),
HOUR(1000*60*60),
DAY(1000*60*60*24),
WEEK(1000*60*60*24*7),
MONTH(1000*60*60*24*30),
YEAR(1000*60*60*24*31*12);

private final long millis;

private MILLI_CONVERSIONS(final long millis) {
    this.millis = millis;
}

public long getMillis() { 
    return millis; 
}
}

public static String getDateDifferenceFromToday(Date startDate){
Date today = new Date();
long delta = today.getTime() - startDate.getTime();

Integer diff;
String diffText = "";
//seconds
if (delta < MILLI_CONVERSIONS.MINUTE.getMillis()){ 
    diff = Integer.valueOf((int) (delta/MILLI_CONVERSIONS.SECOND.getMillis()));
    diffText = diff.toString() + " seconds ago";
}
//minutes
else if (delta < MILLI_CONVERSIONS.HOUR.getMillis()){ 
    diff = Integer.valueOf((int) (delta/MILLI_CONVERSIONS.MINUTE.getMillis()));
    diffText = diff.toString() + " minutes ago";
}
//hours
else if (delta < MILLI_CONVERSIONS.DAY.getMillis()){ 
    diff = Integer.valueOf((int) (delta/MILLI_CONVERSIONS.HOUR.getMillis()));
    diffText = diff.toString() + " hours ago";
}
//days
else if (delta < MILLI_CONVERSIONS.WEEK.getMillis()){
    diff = Integer.valueOf((int) (delta/MILLI_CONVERSIONS.DAY.getMillis()));
    diffText = diff.toString() + " days ago";
}
// weeks
else if(delta < MILLI_CONVERSIONS.MONTH.getMillis()){ 
    diff = Integer.valueOf((int) (delta/MILLI_CONVERSIONS.WEEK.getMillis()));
    diffText = diff.toString() + " weeks ago";
}
// months
else if(delta < MILLI_CONVERSIONS.YEAR.getMillis()){ 
    diff = Integer.valueOf((int) (delta/MILLI_CONVERSIONS.MONTH.getMillis()));
    diffText = diff.toString() + " months ago";
}
// years
else{ 
    diff = Integer.valueOf((int) (delta/MILLI_CONVERSIONS.YEAR.getMillis()));
    diffText = diff.toString() + " years ago";
}

return diffText;
}

似乎工作得很好,直到我打了几个星期。当它甚至一周之后,它显示0个月。然后当它是月份时,它似乎得到了适当的数月,但它显示“几年前”(例如,如果它是两个月前,而不是“2个月前”,它说“2年前”。它从来没有打过几年,它只是持续几个月(例如,如果它是16个月前,它应该说“1年前”,但它说“16年前”)。

我在我的Android应用程序中使用它,所以如果有任何库可以执行此操作,或者我缺少一些内置的计算方法,请告诉我。

感谢。

2 个答案:

答案 0 :(得分:2)

定义枚举常量时,需要使用长整数进行计算,因为溢出整数范围。例如,使用

YEAR(1000L*60*60*24*31*12)

而不是

YEAR(1000*60*60*24*31*12)

将第一个数字指定为long就足以使用long数据类型执行计算。

答案 1 :(得分:1)

你的工作方式太难了。在Java 8中使用Joda-Time库或新的java.time包。

一般来说,你应该忘记毫秒。使用日期时间和时区值,以便让Joda-Time帮助您进行夏令时(DST)和其他异常。但如果你真的是从几毫秒开始,你可以使用long和Joda-Time。

Period period = new Period( myMillis );

当您关注几个月,几天,几小时等的时间跨度时,请使用Period课程。 PeriodFormatterBuilder课程将帮助您生成表示形式作为描述性词语,例如“15年零8个月”。

PeriodFormatter yearsAndMonths = new PeriodFormatterBuilder()
 .printZeroAlways()
 .appendYears()
 .appendSuffix(" year", " years")
 .appendSeparator(" and ")
 .printZeroRarelyLast()
 .appendMonths()
 .appendSuffix(" month", " months")
 .toFormatter();

如果您在Universe的时间轴上有点(日期时间值),请使用Interval类。

Interval interval = new Interval( startDateTime, stopDateTime );

您可以将该时间间隔内的时间跨度捕获为句点。

Period period = interval.toPeriod();

您可能会发现ISO 8601标准的紧凑和标准方式的定义,以表示字符串的数月,日等。标准称之为"duration"(在Joda-Time中不是同一个术语)。格式为PnYnMnDTnHnMnS,其中P(对于句点)标记开头,每个n是一个数字,T将日期部分与时间部分分开。示例:P3Y6M是三年半。在Joda-Time中,Period类知道如何解析和生成这样的字符串。

搜索StackOverflow以查找更多示例。你不是第一个问的人。