2014-11-24 76 views
0

我使用的是從給定日期字符串計算在下週一的方法。問題與日曆計算跨越2歷年

public static String getStartOfNextWeek(String DATE){ 

String format = "dd.MM.yyyy";SimpleDateFormat df = new SimpleDateFormat(format); 

Date date = null; 
try { 
date = df.parse(DATE); 
} catch (ParseException e) { 
e.printStackTrace(); 
} 

Calendar cal = Calendar.getInstance(); 

cal.setTime(date); 
int week = cal.get(Calendar.WEEK_OF_YEAR); 
int year = cal.get(Calendar.YEAR); 

Calendar calendar = new GregorianCalendar(); 
calendar.clear(); 
calendar.set(Calendar.YEAR, year); 
calendar.set(Calendar.WEEK_OF_YEAR, week); 

//add 8 days to get next weeks Monday 

calendar.add(Calendar.DAY_OF_WEEK, 8); 

Date startDate = calendar.getTime(); 

SimpleDateFormat df2 = new SimpleDateFormat("dd.MM.yyyy"); 

String start = df2.format(startDate); 

return start; 

這個工作在單個日曆年完美無缺,但是當我傳遞一個跨越兩個日曆年的值時,會出現問題。

例如:

input: 15.12.2014 
output: 22.12.2014 CORRECT 
input: 22.12.2014 
output: 29.12.2014 CORRECT 
input: 29.12.2014 
output: 6.1.2014 INCORRECT 

我認識其中的錯誤所在,因爲它需要WEEK_OF_YEAR爲「1」,但一年「2014」,所以輸出在技術上是正確的。我的目的錯了。

如何將我最好的告訴大家,我想在1周下週一日曆對象,但2015年?

+0

可能重複[獲取特定日期後的第一個星期一?](http://stackoverflow.com/questions/7565356/get-first-monday-after-certain-date)和[this](http:// stackoverflow .com/q/9612328/642706)和[this](http://stackoverflow.com/q/10072914/642706)和[this](http://stackoverflow.com/q/26754164/642706)以及其他許多人。提示:Joda-Time。 – 2014-11-24 17:35:41

+0

您的輸出中的月份也是錯誤的,而不僅僅是一年。 2014-12-29之後的第一個星期一是2015-01-05(不是第6個)。 – 2014-11-25 07:10:05

+0

羅勒,仔細觀察 - 從2014年12月29日起,它將於下週一返回6.1。** 2014 **。2014年,其實**是**不正確。 – 2014-11-25 10:27:58

回答

1

UPDATE :Joda-Time項目現在在maintenance mode,團隊建議遷移到java.time類。這個答案作爲歷史保持不變。見my newer Answer

喬達時間

Joda-Time庫,版本2.5,得到正確的答案。並更容易獲得它。

// Parse input string. 
String input = "29.12.2014"; 
DateTimeFormatter formatter = DateTimeFormat.forPattern("dd.MM.yyyy"); 
LocalDate inputLocalDate = formatter.parseLocalDate(input); 

// Find desired Monday. 
LocalDate possibleMonday = inputLocalDate.withDayOfWeek(DateTimeConstants.MONDAY); 

// The possible Monday could be past, present, or future of our input date. Adjust as needed. 
LocalDate desiredMonday = null; 
if (possibleMonday.isBefore(inputLocalDate) || possibleMonday.isEqual(inputLocalDate)) { 
    desiredMonday = possibleMonday.plusWeeks(1); // If the possible Monday is past or present, add a week to get *next* Monday. 
} else { 
    desiredMonday = possibleMonday; // If the possible Monday is future, use it. 
} 

String output = formatter.print(desiredMonday); 

轉儲到控制檯。

System.out.println("input : " + input); 
System.out.println("inputLocalDate : " + inputLocalDate); 
System.out.println("desiredMonday : " + desiredMonday); 
System.out.println("output : " + output); 

運行時。

input : 29.12.2014 
inputLocalDate : 2014-12-29 
desiredMonday : 2015-01-05 
output : 05.01.2015 
+0

很好,謝謝,就是我在找的東西。簡單而全面。 – 2014-11-25 09:47:02

0

有一些合併日或日曆時奇怪的,當它涉及到分析日期,只使用日曆它的偉大工程;

String[] dt = dateStr.split("\\."); 
    GregorianCalendar cal = new GregorianCalendar(Integer.parseInt(dt[2]), (Integer.parseInt(dt[1])-1), Integer.parseInt(dt[0])); 
    cal.setFirstDayOfWeek(Calendar.MONDAY); 
    cal.clear(Calendar.DAY_OF_WEEK); 
    cal.add(Calendar.DATE, 7); 
    System.out.println(cal.get(Calendar.YEAR) + "." + (cal.get(Calendar.MONTH)+1) + "." + cal.get(Calendar.DATE)); 

編輯:你必須從一個月減1,因爲歷預計幾個月內從0到11 (Calendar.JANUARY == 0)//真

0

TL;博士

LocalDate.parse( 
    "29.12.2014" , 
    DateTimeFormatter.ofPattern("dd.MM.uuuu") 
).with(
    TemporalAdjusters.next(DayOfWeek.MONDAY) 
) 

2015年1月5日

java.time

現代的方法使用java.time類。

DateTimeFormatter f = DateTimeFormatter.ofPattern("dd.MM.uuuu") 
LocalDate ld = LocalDate.parse("29.12.2014" , f) ; 

要移動到其他日期,使用在TemporalAdjusters類中找到一個TemporalAdjuster實現。用DayOfWeek枚舉對象指定所需的星期幾。跨越年終/年初時沒有問題。

LocalDate followingMonday = ld.with(TemporalAdjusters.next(DayOfWeek.MONDAY)) ; 

如果要在星期一使用當前日期,請使用TemporalAdjusters.nextOrSame

類似的方法提供了以前天,本週內,還有:previous & previousOrSame


關於java.time

java.time框架是建立在Java 8和更高版本。這些類代替了日期時間類legacy,如java.util.Date,Calendar,& SimpleDateFormat

Joda-Time項目,現在在maintenance mode,建議遷移到java.time類。請參閱Oracle Tutorial。並搜索堆棧溢出了很多例子和解釋。規格是JSR 310

從何處獲取java.time類?

ThreeTen-Extra項目與其他類擴展java.time。這個項目是未來可能增加java.time的一個試驗場。您可以在這裏找到一些有用的類,如Interval,YearWeek,YearQuartermore