2014-12-07 49 views
1

我在教自己的Java和我正在研究這個應用程序,將數到聖誕節的日子。今天和聖誕節的GregorianCalendarDate對象的HOUR_OF_DAYMONTHSECOND值都設置爲零。通過調試,我可以看到變化的天數以毫秒爲單位的差異,它給了我一個1641599724毫秒的時間,即18.99999天,但無論我嘗試什麼,它都不會達到19。天到聖誕節應用程序Java值將不會收起

我試圖Math.ceil方法,試圖圍捕,但我不能讓它等於19

FIRST:DataUtils類存儲/修改從用戶

package chapter13datesstrings; 


import java.util.*; 

public class DateUtils { 

static final int MILLS_IN_DAY = 24 * 60 * 60 * 1000; 

public static Date getCurrentDate(){ 
    GregorianCalendar currentDate = new GregorianCalendar(); 
    currentDate.set(Calendar.HOUR_OF_DAY, 0); 
    currentDate.set(Calendar.MINUTE, 0); 
    currentDate.set(Calendar.SECOND, 0); 
    return currentDate.getTime();    
} 

public static Date createDate(int year, int month, int day){ 
    GregorianCalendar date = new GregorianCalendar(year, month, day); 
    return date.getTime(); 
} 

public static Date stripTime(Date date){ 
    GregorianCalendar noTimeDate = new GregorianCalendar(); 
    noTimeDate.setTime(date); 
    noTimeDate.set(Calendar.HOUR, 0); 
    noTimeDate.set(Calendar.MINUTE,0); 
    noTimeDate.set(Calendar.SECOND, 0); 
    return noTimeDate.getTime(); 
} 

public static double daysDiff(Date date1, Date date2){ 

    date1 = stripTime(date1); 
    date2 = stripTime(date2); 

    long longDate1 = date1.getTime(); 
    long longDate2 = date2.getTime(); 

    long longDiff = longDate2 - longDate1; 

    return (int) (Math.ceil(longDiff/MILLS_IN_DAY)); 
}  


} 
輸入

SECOND:DateUtilExample類提供輸入到DataUtils類

package chapter13datesstrings; 

import java.util.*; 
import java.text.*; 

public class DateUtilExample { 


public void thisIsCode(){ 

GregorianCalendar currentGC = new GregorianCalendar(); 
int currentYear = currentGC.get(Calendar.YEAR); //sets current year 

Date currentDate = DateUtils.getCurrentDate(); //create current date object 
Date christmas = DateUtils.createDate(currentYear, Calendar.DECEMBER, 25); //set christmas date 
int daysToChristmas = DateUtils.daysDiff(currentDate, christmas); // days until christmas 

DateFormat date = DateFormat.getDateInstance(Calendar.LONG); 
String formattedToday = date.format(currentDate); 

/**** Output Items *****/ 
System.out.println("Today is " + formattedToday); 
System.out.println("Number of Days 'Till Xmas: " + daysToChristmas + " days"); 
} 


} 

主要方法類

package chapter13datesstrings; 


import java.util.Date; 
import java.text.DateFormat; 


public class Chapter13DatesStrings { 

public static void theDates(){ 
    DateUtilExample dateUtilExample = new DateUtilExample(); 
    dateUtilExample.thisIsCode(); 
} 

public static void main(String[] args) { 
theDates(); 
} 

} 
+0

僅供參考,雖然我理解你正在練習學習Java,你也應該知道,在現實世界中的Java。 util.Date/。日曆班應該避免,因爲它們很麻煩,容易混淆,並且有缺陷。對於實際工作,請使用[Joda-Time](http://www.joda.org/joda-time/)庫或java.time。 Joda-Time 2.6中的代碼示例:'DateTimeZone zone = DateTimeZone.forID(「America/Montreal」); DateTime now = DateTime.now(zone); DateTime then = new DateTime(2014,12,25,0,0,0,zone); int daysUntilXmas = Days.daysBetween(now,then).getDays();' – 2014-12-07 03:32:34

回答

2

當你在Java中劃分兩個整數,結果會自動四捨五入(「截斷」)。

表達式longDiff/MILLS_IN_DAY不等於18.99999,它等於18。 Java本質上計算18.99999,然後拋出小數點後的所有內容,之前你可以用它做任何事情。與ceil四捨五入在這一點上沒有幫助,因爲你只是最終計算ceil(18)這只是18

解決這個問題的一個方法是在分割數字之前先將數字轉換爲doubledouble是浮點值,因此將它們分開並不會將結果向下舍入。要使用雙打,與

((double)longDiff)/((double)MILLS_IN_DAY) 

更換

longDiff/MILLS_IN_DAY 

另一種解決方案,這可能是計算效率更高,但那麼一點點優雅是簡單地添加到1的結果。這並不完全相同,因爲當你處於午夜毫秒之內時,結果會比預期的多一天,但這實際上並不明顯。採取這種方法,你將取代行:

return (int) (Math.ceil(longDiff/MILLS_IN_DAY)); 

return longDiff/MILLS_IN_DAY + 1; 
+0

完美。謝謝! – 2014-12-07 01:14:08

1

或者什麼SelectricSimian說, 這一點是可以通過提供一對夫婦使用Calendar API線來完成java的。 爲了簡單地得到當前的時間和給定的一天的日子不同,你可以使用:

public static void main(String[] args) { 
    System.out.println(getDaysUntil(Calendar.DECEMBER, 25) + " day(s)."); 
    // If the date is December 25th, this will output "365 day(s)" 
    // If the date is December 24th, this will output "1 day(s)" 
} 

public static int getDaysUntil(int month, int day) { 
    /** 
    * First get a properly formatted calendar representing right now. This 
    * should include leap years and local. With this calendar, we get the 
    * day of the year. 
    */ 
    Calendar calendar = Calendar.getInstance(); 
    int today = calendar.get(Calendar.DAY_OF_YEAR); 

    /** 
    * Now change the day and month of the current calendar to the given day 
    * and month. 
    */ 
    calendar.set(Calendar.MONTH, month); 
    calendar.set(Calendar.DAY_OF_MONTH, day); 
    int desiredDay = calendar.get(Calendar.DAY_OF_YEAR); 

    /** 
    * Then we just get the difference between now and then. 
    */ 
    int difference = desiredDay - today; 

    /** 
    * If the desiredDay has passed already, or it's currently the 
    * desiredDay, we need to recalculate the difference. 
    */ 
    if (difference <= 0) { 
     /** 
     * We start by getting the days until the end of the year. 
     */ 
     calendar.set(Calendar.MONTH, 11); 
     calendar.set(Calendar.DAY_OF_MONTH, 31); 
     int daysUntilEnd = calendar.get(Calendar.DAY_OF_YEAR) - today; 

     /** 
     * Then, move the calendar forward a year and get the day of year 
     * for the desired day again. We recalculate the number of days just 
     * in case next year is a leap year. 
     */ 
     calendar.set(Calendar.YEAR, calendar.get(Calendar.YEAR) + 1); 
     calendar.set(Calendar.MONTH, month); 
     calendar.set(Calendar.DAY_OF_MONTH, day); 
     desiredDay = calendar.get(Calendar.DAY_OF_YEAR); 

     /** 
     * Finally, just add daysUntilEnd and desiredDay to get the updated 
     * difference. 
     */ 
     difference = daysUntilEnd + desiredDay; 
    } 

    return difference; 
} 
+0

絕對是一個更簡單的方法。我認爲我正在閱讀的這本書只是試圖一次捕捉多件事情,但我喜歡你這樣做的方式。 – 2014-12-07 01:32:00

+0

@ user3386635需要的代碼越少,在我看來越容易閱讀和理解。而且,重用標準API也是一種很好的做法。 我更新了我的答案,以便對日期進行更通用的處理,並考慮到當天已經過去。 – 2014-12-07 02:34:52