Java中两个日期之间的天数差异?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3299972/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Difference in days between two dates in Java?
提问by Venkat
I need to find the number of days between two dates: one is from a report and one is the current date. My snippet:
我需要找到两个日期之间的天数:一个来自报告,一个是当前日期。我的片段:
int age=calculateDifference(agingDate, today);
Here calculateDifference
is a private method, agingDate
and today
are Date
objects, just for your clarification. I've followed two articles from a Java forum, Thread 1/ Thread 2.
这calculateDifference
是一个私有方法,agingDate
并且today
是Date
对象,仅供您说明。我关注了 Java 论坛上的两篇文章Thread 1/ Thread 2。
It works fine in a standalone program although when I include this into my logic to read from the report I get an unusual difference in values.
它在独立程序中运行良好,但当我将其包含在我的逻辑中以从报告中读取时,我得到了不寻常的值差异。
Why is it happening and how can I fix it?
为什么会发生这种情况,我该如何解决?
EDIT :
编辑 :
I'm getting a greater number of days compared to the actual amount of Days.
与实际天数相比,我得到的天数更多。
public static int calculateDifference(Date a, Date b)
{
int tempDifference = 0;
int difference = 0;
Calendar earlier = Calendar.getInstance();
Calendar later = Calendar.getInstance();
if (a.compareTo(b) < 0)
{
earlier.setTime(a);
later.setTime(b);
}
else
{
earlier.setTime(b);
later.setTime(a);
}
while (earlier.get(Calendar.YEAR) != later.get(Calendar.YEAR))
{
tempDifference = 365 * (later.get(Calendar.YEAR) - earlier.get(Calendar.YEAR));
difference += tempDifference;
earlier.add(Calendar.DAY_OF_YEAR, tempDifference);
}
if (earlier.get(Calendar.DAY_OF_YEAR) != later.get(Calendar.DAY_OF_YEAR))
{
tempDifference = later.get(Calendar.DAY_OF_YEAR) - earlier.get(Calendar.DAY_OF_YEAR);
difference += tempDifference;
earlier.add(Calendar.DAY_OF_YEAR, tempDifference);
}
return difference;
}
Note :
笔记 :
Unfortunately, none of the answers helped me solve the problem. I've accomplished this problemwith the help of Joda-timelibrary.
采纳答案by Adam Schmideg
I would suggest you use the excellent Joda Timelibrary instead of the flawed java.util.Date and friends. You could simply write
我建议你使用优秀的Joda Time库而不是有缺陷的 java.util.Date 和朋友。你可以简单地写
import java.util.Date;
import org.joda.time.DateTime;
import org.joda.time.Days;
Date past = new Date(110, 5, 20); // June 20th, 2010
Date today = new Date(110, 6, 24); // July 24th
int days = Days.daysBetween(new DateTime(past), new DateTime(today)).getDays(); // => 34
回答by Carl Manaster
You say it "works fine in a standalone program," but that you get "unusual difference values" when you "include this into my logic to read from report". That suggests that your report has some values for which it doesn't work correctly, and your standalone program doesn't have those values. Instead of a standalone program, I suggest a test case. Write a test case much as you would a standalone program, subclassing from JUnit's TestCase class. Now you can run a very specific example, knowing what value you expect (and don't give it today for the test value, because today changes over time). If you put in the values you used in the standalone program, your tests will probably pass. That's great - you want those cases to keep working. Now, add a value from your report, one that doesn't work right. Your new test will probably fail. Figure out why it's failing, fix it, and get to green (all tests passing). Run your report. See what's still broken; write a test; make it pass. Pretty soon you'll find your report is working.
您说它“在独立程序中运行良好”,但是当您“将其包含在我的逻辑中以从报告中读取”时,您会得到“不寻常的差异值”。这表明您的报告有一些无法正常工作的值,而您的独立程序没有这些值。我建议使用一个测试用例,而不是一个独立的程序。像编写独立程序一样编写测试用例,从 JUnit 的 TestCase 类继承。现在你可以运行一个非常具体的例子,知道你期望什么值(并且今天不要给它作为测试值,因为今天会随着时间的推移而变化)。如果您输入您在独立程序中使用的值,您的测试可能会通过。太好了 - 您希望这些案例继续工作。现在,从您的报告中添加一个值,一个不 工作正常。您的新测试可能会失败。找出它失败的原因,修复它,然后变绿(所有测试都通过)。运行您的报告。看看还有什么坏掉的;写一个测试;让它通过。很快您就会发现您的报告正在发挥作用。
回答by Suji
I might be too late to join the game but what the heck huh? :)
我加入游戏可能为时已晚,但这到底是怎么回事?:)
Do you think this is a threading issue? How are you using the output of this method for example? OR
您认为这是线程问题吗?例如,您如何使用此方法的输出?或者
Can we change your code to do something as simple as:
我们可以更改您的代码来做一些简单的事情:
Calendar calendar1 = Calendar.getInstance();
Calendar calendar2 = Calendar.getInstance();
calendar1.set(<your earlier date>);
calendar2.set(<your current date>);
long milliseconds1 = calendar1.getTimeInMillis();
long milliseconds2 = calendar2.getTimeInMillis();
long diff = milliseconds2 - milliseconds1;
long diffSeconds = diff / 1000;
long diffMinutes = diff / (60 * 1000);
long diffHours = diff / (60 * 60 * 1000);
long diffDays = diff / (24 * 60 * 60 * 1000);
System.out.println("\nThe Date Different Example");
System.out.println("Time in milliseconds: " + diff
+ " milliseconds.");
System.out.println("Time in seconds: " + diffSeconds
+ " seconds.");
System.out.println("Time in minutes: " + diffMinutes
+ " minutes.");
System.out.println("Time in hours: " + diffHours
+ " hours.");
System.out.println("Time in days: " + diffDays
+ " days.");
}
回答by Peter Lawrey
It depends on what you define as the difference. To compare two dates at midnight you can do.
这取决于您定义的差异。要在午夜比较两个日期,您可以这样做。
long day1 = ...; // in milliseconds.
long day2 = ...; // in milliseconds.
long days = (day2 - day1) / 86400000;
回答by KennethB
Illustration of the problem: (My code is computing delta in weeks, but same issue applies with delta in days)
问题说明:(我的代码以周为单位计算增量,但同样的问题适用于以天为单位的增量)
Here is a very reasonable-looking implementation:
这是一个非常合理的实现:
public static final long MILLIS_PER_WEEK = 7L * 24L * 60L * 60L * 1000L;
static public int getDeltaInWeeks(Date latterDate, Date earlierDate) {
long deltaInMillis = latterDate.getTime() - earlierDate.getTime();
int deltaInWeeks = (int)(deltaInMillis / MILLIS_PER_WEEK);
return deltaInWeeks;
}
But this test will fail:
但是这个测试会失败:
public void testGetDeltaInWeeks() {
delta = AggregatedData.getDeltaInWeeks(dateMar09, dateFeb23);
assertEquals("weeks between Feb23 and Mar09", 2, delta);
}
The reason is:
原因是:
Mon Mar 09 00:00:00 EDT 2009 = 1,236,571,200,000
Mon Feb 23 00:00:00 EST 2009 = 1,235,365,200,000
MillisPerWeek = 604,800,000
Thus,
(Mar09 - Feb23) / MillisPerWeek =
1,206,000,000 / 604,800,000 = 1.994...
周一09年3月00:00:00 EDT 2009年= 1,236,571,200,000
周一年02月23日00:00:00东部时间2009 = 1,235,365,200,000
MillisPerWeek = 604800000
。因此,
(Mar09 - Feb23)/ MillisPerWeek =
12.06亿/ 604800000 = 1.994 ...
but anyone looking at a calendar would agree that the answer is 2.
但是任何查看日历的人都会同意答案是 2。
回答by ccpizza
Look at the getFragmentInDaysmethods in this apache commons-lang class DateUtils
.
查看这个 apache commons-lang 类中的getFragmentInDays方法DateUtils
。
回答by Mad_troll
The diff / (24 * etc) does not take Timezone into account, so if your default timezone has a DST in it, it can throw the calculation off.
diff / (24 * etc) 不考虑时区,因此如果您的默认时区中包含 DST,它可以取消计算。
This linkhas a nice little implementation.
这个链接有一个很好的小实现。
Here is the source of the above link in case the link goes down:
这是上述链接的来源,以防链接断开:
/** Using Calendar - THE CORRECT WAY**/
public static long daysBetween(Calendar startDate, Calendar endDate) {
//assert: startDate must be before endDate
Calendar date = (Calendar) startDate.clone();
long daysBetween = 0;
while (date.before(endDate)) {
date.add(Calendar.DAY_OF_MONTH, 1);
daysBetween++;
}
return daysBetween;
}
and
和
/** Using Calendar - THE CORRECT (& Faster) WAY**/
public static long daysBetween(final Calendar startDate, final Calendar endDate)
{
//assert: startDate must be before endDate
int MILLIS_IN_DAY = 1000 * 60 * 60 * 24;
long endInstant = endDate.getTimeInMillis();
int presumedDays =
(int) ((endInstant - startDate.getTimeInMillis()) / MILLIS_IN_DAY);
Calendar cursor = (Calendar) startDate.clone();
cursor.add(Calendar.DAY_OF_YEAR, presumedDays);
long instant = cursor.getTimeInMillis();
if (instant == endInstant)
return presumedDays;
final int step = instant < endInstant ? 1 : -1;
do {
cursor.add(Calendar.DAY_OF_MONTH, step);
presumedDays += step;
} while (cursor.getTimeInMillis() != endInstant);
return presumedDays;
}
回答by Soumyarup Dasgupta
import java.util.Calendar;
import java.util.Date;
public class Main {
public static long calculateDays(String startDate, String endDate)
{
Date sDate = new Date(startDate);
Date eDate = new Date(endDate);
Calendar cal3 = Calendar.getInstance();
cal3.setTime(sDate);
Calendar cal4 = Calendar.getInstance();
cal4.setTime(eDate);
return daysBetween(cal3, cal4);
}
public static void main(String[] args) {
System.out.println(calculateDays("2012/03/31", "2012/06/17"));
}
/** Using Calendar - THE CORRECT WAY**/
public static long daysBetween(Calendar startDate, Calendar endDate) {
Calendar date = (Calendar) startDate.clone();
long daysBetween = 0;
while (date.before(endDate)) {
date.add(Calendar.DAY_OF_MONTH, 1);
daysBetween++;
}
return daysBetween;
}
}
回答by angelcervera
Solution using difference between milliseconds time, with correct rounding for DST dates:
使用毫秒时间差的解决方案,并正确舍入 DST 日期:
public static long daysDiff(Date from, Date to) {
return daysDiff(from.getTime(), to.getTime());
}
public static long daysDiff(long from, long to) {
return Math.round( (to - from) / 86400000D ); // 1000 * 60 * 60 * 24
}
One note: Of course, dates must be in some timezone.
一个注意事项:当然,日期必须在某个时区。
The important code:
重要代码:
Math.round( (to - from) / 86400000D )
If you don't want round, you can use UTC dates,
如果你不想圆,你可以使用UTC日期,
回答by cesin
I use this funcion:
我使用这个功能:
DATEDIFF("31/01/2016", "01/03/2016") // me return 30 days
my function:
我的功能:
import java.util.Date;
public long DATEDIFF(String date1, String date2) {
long MILLISECS_PER_DAY = 24 * 60 * 60 * 1000;
long days = 0l;
SimpleDateFormat format = new SimpleDateFormat("dd/MM/yyyy"); // "dd/MM/yyyy HH:mm:ss");
Date dateIni = null;
Date dateFin = null;
try {
dateIni = (Date) format.parse(date1);
dateFin = (Date) format.parse(date2);
days = (dateFin.getTime() - dateIni.getTime())/MILLISECS_PER_DAY;
} catch (Exception e) { e.printStackTrace(); }
return days;
}