2013-10-19 89 views
23

如果日期發生變化,我想在天數中找到兩個Calendar對象之間的差異,如果時間從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)); 
} 

,但它不是因爲它的工作只給天之間的區別,如果有區別一個月的一文不值。

+1

類似這樣的問題就是爲什麼他們寫道喬達時間。 Java日曆是如此絕望......你必須使用它嗎? – iluxa

+5

因爲如果你必須的話,我會把它們都轉換成millis並且用這些工作,坦率地說:-) – iluxa

回答

23

試試下面的辦法:

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

它可能會增加1. – CoDe

+11

這不是原始問題的正確答案。如果一天的差異定義爲86,400,000毫秒(24小時內的毫秒數),則此答案是正確的。然而,最初的問題是「如果有日期變化,如23:59-0:00時鐘打勾,那麼應該有一天的差異」。因此,問題定義爲日曆日期相差1天時的1天差異。 – stackoverflowuser2010

6

此函數計算的天兩種曆法之間的數量的是它們之間的一個月,這是什麼OP想要的日曆天數。通過計算兩個日曆設置爲各自日期的午夜之後日曆之間的86,400,000毫秒的倍數來執行計算。

例如,我的函數將計算1月1日下午11:59和1月2日12:01 AM的日曆之間1天的差異。

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())); 
} 
-4

Calendar day1 = Calendar.getInstance();

日曆day2 = Calendar.getInstance();

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

+6

此代碼僅適用於兩個實例均爲同一年的情況。 –

2

UPDATEJoda-Time項目,現在在maintenance mode,建議遷移到java.time類。請參閱Anees A的the Answer以使用ChronoUnit和其他java.time類。

喬達時間

老java.util.Date/.Calendar類是出了名的麻煩,應該儘量避免。可以使用Joda-Time庫。除非你有Java 8技術,在這種情況下,使用它的後繼者,內置的java.time框架(截至2015年不在Android中)。

由於您只關心定義爲日期(而不是24小時)的「天數」,因此我們將重點放在日期上。 Joda-Time提供類別LocalDate以表示沒有時間和時區的僅限日期的值。

雖然缺少時區,但請注意,時區爲至關重要確定諸如「今日」之類的日期。新的一天早在東部比在西部早。所以日期在世界各地不一樣,日期取決於你的時區。

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

讓我們來計算直到下週的天數,當然應該是七天。

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

在端的getDays提取從由daysBetween返回的Days對象純int數。

轉儲到控制檯。

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

今天:2015年12月22日至weekLater:2015年12月29日是天:7

你有日曆對象。我們需要將它們轉換爲Joda-Time對象。在日曆對象的內部,有一個long整數跟蹤從UTC 1970年第一個時刻開始的毫秒數。我們可以提取該數字,並將其提供給Joda-Time。我們還需要指定我們打算確定日期所需的時區。

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(); 
10

在Java 8和更高版本中,我們可以簡單地使用java.time類。

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

daysBetween = ChronoUnit.DAYS.between(calendarObj.toInstant(), calendarObj.toInstant()); 
+0

也可以在Java 8之前使用...大部分java.time功能都被移植到[*** ThreeTen-Backport ***](http://www.threeten.org)中的Java 6和Java 7中/ threetenbp /)項目。在[*** ThreeTenABP ***](https://github.com/JakeWharton/ThreeTenABP)項目中進一步適用於Android。 –

0

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

並且已經編寫了有關api的測試用例,對於我來說,如果我通過了 2017年3月8日 - 作爲開始日期和2017年4月8日作爲結束日期,它就會失敗。

有幾個日期,你會看到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

0

擴展到@ 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)); 
} 
相關問題