如何获得两个日历实例之间的天数?

我想要查找两个Calendar对象的天数之间的差异,如果有date变化,如23:59-0:00时钟打勾应该有一个日子的差异。

我写了这个

 public static int daysBetween(Calendar startDate, Calendar endDate) { return Math.abs(startDate.get(Calendar.DAY_OF_MONTH)-endDate.get(Calendar.DAY_OF_MONTH)); } 

但它不工作,因为它只是有差距的日子,如果有月份的差异是毫无价值的。

Solutions Collecting From Web of "如何获得两个日历实例之间的天数?"

尝试以下方法:

 public static long daysBetween(Calendar startDate, Calendar endDate) { long end = endDate.getTimeInMillis(); long start = startDate.getTimeInMillis(); return TimeUnit.MILLISECONDS.toDays(Math.abs(end - start)); } 

在Java 8和更高版本中,我们可以简单地使用java.time类。

 hoursBetween = ChronoUnit.HOURS.between(calendarObj.toInstant(), calendarObj.toInstant()); daysBetween = ChronoUnit.DAYS.between(calendarObj.toInstant(), calendarObj.toInstant()); 

此函数计算两个日历之间的天数,作为它们之间月份的日历天数,这是OP想要的。 通过计算两个日历设置为各自date的午夜之后日历之间的86,400,000毫秒的倍数来执行计算。

例如,我的函数将计算1月1日下午11:59和1月2日12:01上午的日历之间的差异。

 import java.util.concurrent.TimeUnit; /** * Compute the number of calendar days between two Calendar objects. * The desired value is the number of days of the month between the * two Calendars, not the number of milliseconds' worth of days. * @param startCal The earlier calendar * @param endCal The later calendar * @return the number of calendar days of the month between startCal and endCal */ public static long calendarDaysBetween(Calendar startCal, Calendar endCal) { // Create copies so we don't update the original calendars. Calendar start = Calendar.getInstance(); start.setTimeZone(startCal.getTimeZone()); start.setTimeInMillis(startCal.getTimeInMillis()); Calendar end = Calendar.getInstance(); end.setTimeZone(endCal.getTimeZone()); end.setTimeInMillis(endCal.getTimeInMillis()); // Set the copies to be at midnight, but keep the day information. start.set(Calendar.HOUR_OF_DAY, 0); start.set(Calendar.MINUTE, 0); start.set(Calendar.SECOND, 0); start.set(Calendar.MILLISECOND, 0); end.set(Calendar.HOUR_OF_DAY, 0); end.set(Calendar.MINUTE, 0); end.set(Calendar.SECOND, 0); end.set(Calendar.MILLISECOND, 0); // At this point, each calendar is set to midnight on // their respective days. Now use TimeUnit.MILLISECONDS to // compute the number of full days between the two of them. return TimeUnit.MILLISECONDS.toDays( Math.abs(end.getTimeInMillis() - start.getTimeInMillis())); } 

更新现在处于维护模式的Joda-Time项目build议迁移到java.time类。 请参阅Anees A 的答案以了解ChronoUnit和其他java.time类的使用。

乔达时间

旧的java.util.Date/.Calendar类是非常麻烦的,应该避免。

而是使用乔达时间库。 除非你有Java 8技术,在这种情况下,使用它的后继者,内置的java.time框架(不在2015年的Android)。

由于您只关心定义为date(而不是24小时)的“天数”,因此我们关注date。 Joda-Time提供LocalDate类来表示一个没有时间和时区的date值。

虽然缺乏时区,但请注意,时区对于确定“今天”这样的date至关重要 。 东方的新的一天比西方早。 所以date在世界各地不一样,date取决于你的时区。

 DateTimeZone zone = DateTimeZone.forID ( "America/Montreal" ); LocalDate today = LocalDate.now ( zone ); 

我们来计算下个星期的天数,当然是七。

 LocalDate weekLater = today.plusWeeks ( 1 ); int elapsed = Days.daysBetween ( today , weekLater ).getDays (); 

最后getDaysdaysBetween返回的Days对象中提取一个纯int数。

转储到控制台。

 System.out.println ( "today: " + today + " to weekLater: " + weekLater + " is days: " + days ); 

今天:2015-12-22到周末:2015-12-29是天:7

你有日历对象。 我们需要将它们转换成Joda-Time对象。 在内部,Calendar对象具有一个long整数,跟踪从1970年的第一个时间点UTC开始的毫秒数。 我们可以提取这个数字,并把它喂给Joda-Time。 我们还需要指定我们打算确定date所需的时区。

 long startMillis = myStartCalendar.getTimeInMillis(); DateTime startDateTime = new DateTime( startMillis , zone ); long stopMillis = myStopCalendar.getTimeInMillis(); DateTime stopDateTime = new DateTime( stopMillis , zone ); 

从DateTime对象转换到LocalDate。

 LocalDate start = startDateTime.toLocalDate(); LocalDate stop = stopDateTime.toLocalDate(); 

现在执行我们前面看到的相同的计算过程。

 int elapsed = Days.daysBetween ( start , stop ).getDays (); 

我有类似(不完全相同)的方法在https://stackoverflow.com/a/31800947/3845798上面给出。

并且围绕api编写了testing用例,对于我来说,如果我通过了2017年3月8日 – 作为开始date和2017年4月8日作为结束date,那么它将失败。

有几个date,你会看到1天的差异。 因此,我对api做了一些小的改动,现在我的api看起来像这样

  public long getDays(long currentTime, long endDateTime) { Calendar endDateCalendar; Calendar currentDayCalendar; //expiration day endDateCalendar = Calendar.getInstance(TimeZone.getTimeZone("EST")); endDateCalendar.setTimeInMillis(endDateTime); endDateCalendar.set(Calendar.MILLISECOND, 0); endDateCalendar.set(Calendar.MINUTE, 0); endDateCalendar.set(Calendar.HOUR, 0); endDateCalendar.set(Calendar.HOUR_OF_DAY, 0); //current day currentDayCalendar = Calendar.getInstance(TimeZone.getTimeZone("EST")); currentDayCalendar.setTimeInMillis(currentTime); currentDayCalendar.set(Calendar.MILLISECOND, 0); currentDayCalendar.set(Calendar.MINUTE, 0); currentDayCalendar.set(Calendar.HOUR,0); currentDayCalendar.set(Calendar.HOUR_OF_DAY, 0); long remainingDays = (long)Math.ceil((float) (endDateCalendar.getTimeInMillis() - currentDayCalendar.getTimeInMillis()) / (24 * 60 * 60 * 1000)); return remainingDays;} 

我没有使用造成我一些问题的TimeUnit.MILLISECONDS.toDays。

扩展到@ JK1很好的回答:

 public static long daysBetween(Calendar startDate, Calendar endDate) { //Make sure we don't change the parameter passed Calendar newStart = Calendar.getInstance(); newStart.setTimeInMillis(startDate.); newStart.set(Calendar.HOUR_OF_DAY, 0) newStart.set(Calendar.MINUTE, 0) newStart.set(Calendar.SECOND, 0) newStart.set(Calendar.MILLISECOND, 0) Calendar newEnd = Calendar.getInstance(); newEnd.setTimeInMillis(startDate.); newEnd.set(Calendar.HOUR_OF_DAY, 0) newEnd.set(Calendar.MINUTE, 0) newEnd.set(Calendar.SECOND, 0) newEnd.set(Calendar.MILLISECOND, 0) long end = newEnd.getTimeInMillis(); long start = newStart.getTimeInMillis(); return TimeUnit.MILLISECONDS.toDays(Math.abs(end - start)); } 

日历day1 = Calendar.getInstance();

日历day2 = Calendar.getInstance();

int diff = day1.get(Calendar.DAY_OF_YEAR) – day2.get(Calendar.DAY_OF_YEAR);