2015-11-04 57 views
4

我創建了一個類需要有日期,start_datedate_passed兩個字段。我一直在研究java中的最佳方式,使用YYYY MM DD格式的日期,以允許簡單的日期減法和「補齊」日期的能力,例如將來會說。Java的:最簡單的方式減去日期

的想什麼,我就做

例...

library.circulate_book("Chemistry", **start date here**) //actual date or random date 
library.pass_book("Chemistry", **Date Passed here**) //random date such as 5 days after start date 
int days_had = Date_Passed - start_date 

到目前爲止,我已經找到了很多方法來格式化使用日曆日期類,日期,但還沒有找到一個看起來它會工作考慮大多數日期最終作爲字符串。任何建議/小例子非常感謝!此外,任何指向示例的鏈接都將非常棒!

回答

3

解析

首先,你必須分析你的字符串輸入轉換成日期時間對象。然後,您將使用這些對象預製business logic

停止將日期時間值作爲字符串來思考,這會讓你瘋狂。我們在代碼中使用日期 - 時間對象;我們使用該日期時間對象的字符串表示形式與用戶或其他應用交換數據。

在Java 8和更高版本,使用java.time框架。見Tutorial

你只想要一個日期,沒有時間的一天,所以我們可以使用LocalDate類。

那質樸的雙冒號語法是一個method reference,辦法說什麼方法應該由其他代碼調用。

String input = "2015 01 02"; 
DateTimeFormatter formatter = DateTimeFormatter.ofPattern ("yyyy MM dd"); 
LocalDate localDate = formatter.parse (input , LocalDate :: from); 

減去日期

這一問題已經在StackOveflow.com之前解決了許多倍。例如,How to subtract X days from a date using Java calendar?。有關詳細信息,請參閱其他答案,如this one by methis one by me以獲取更多詳細信息。提示:「已逝」是一個關鍵的搜索詞。

簡單地說,使用Period定義一些標準的日,月和年。

LocalDate weekLater = localDate.plusDays (7); 
Period period = Period.between (localDate , weekLater); 
Integer daysElapsed = period.getDays(); 

轉儲到控制檯。

System.out.println ("localDate: " + localDate + " to " + weekLater + " in days: " + daysElapsed); 

LOCALDATE的:2015年1月2日至2015年1月9日在天:7

注意的限制,即Period作品只能用整整兩天,也就是日期,只值沒有時間。這就是我們在這個問題所需要的,因此完成了工作。如果您有日期時間值(ZonedDateTime對象),請使用ThreeTen-Extra項目的Days類,如上面鏈接的問題/答案中所述。

+0

優秀的迴應,我正在瀏覽LocalDate方法,而且我可能讀錯了,但有沒有一種方法只返回本地日期,例如今天的'2015 04 11'? – Bob

+0

'now()'能夠從程序後期的日期中減去,例如'LocalDate localDate = formatter.parse(input,LocalDate :: from);' – Bob

+0

@ user38254您似乎仍然在合併日期時間值與他們的字符串表示。要獲得「今日」,只需調用LocalDate today = LocalDate.now(ZoneId.of(「America/Montreal」);)'。時區對確定一個日期至關重要(考慮一下!)。對於字符串,使用上面看到的格式化程序:'字符串輸出= today.format(formatter);'。搜索關於此主題的其他StackOveflow頁面。 –

0

如果你被卡住withan以前的Java可以使用的SimpleDateFormat。

//For substraction 
    long differenceInMillis = date1.getTime() - date2.getTime(); 

    //Date Format 
    SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy MM dd"); 
    String dateAsString = dateFormat.format(date1); //To get a text representation 
    Date dateParsed = dateFormat.parse(dateAsString); //To get it back as date 
1

下面是一個使用Calendar答案:

Calendar cal = Calendar.getInstance(); 
Calendar cal2 = Calendar.getInstance(); 

cal2.setTime(cal.getTime()); 
cal2.add(Calendar.DAY_OF_YEAR, 5); 
System.out.println((cal2.getTimeInMillis() - cal.getTimeInMillis())/(1000d * 60 * 60 * 24)); 
3

中的Java-8做到這一點,最好的辦法是不羅勒布爾克的有缺陷的答案,但這種方法:

String startDate = "2016 01 02"; 
String passedDate = "2016 02 29"; 

DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy MM dd"); 
LocalDate date1 = LocalDate.parse(startDate, formatter); 
LocalDate date2 = LocalDate.parse(passedDate, formatter); 

long elapsedDays = ChronoUnit.DAYS.between(date1, date2); 
System.out.println(elapsedDays); // 58 (correct) 

建議的使用java.time.Period.getDays()儘快是危險的,往往是錯誤的經過持續時間超過一個月。整個Period是P1M27D所以這段代碼有效只查詢經過的天量部分(也有一個經過一個月):使用類

System.out.println(Period.between(date1, date2).getDays()); // 27 (WRONG!!!) 

一個令人滿意的解決方案java.util.DateGregorianCalendar等是很難找到的。您可以使用Tacktheritrix的答案,但必須注意以下事實:經過計算的日曆天數可能因java.util.Date的子日期部分而有所不同,並且由於忽略了日光節約開關而不可靠(世界許多地方的時鐘跳了一個小時)。

備註:至少8外部庫也爲您的問題提供了很好的答案。但是我認爲,除非您尚未使用Java-8,否則您的簡單用例不適用於嵌入額外的庫。如何計算兩個日期之間經過的日期的任何替代解決方案都不會比Java-8更容易 - 只是相似。由於您接受了Basil Bourque的Java-8相關答案,因此我認爲您確實在使用Java-8,因此我忽略瞭如何解決與其他庫有關的問題的答案。