2014-11-24 3 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; 

이 작업은 1 년 동안 완벽하게 작동하지만 2 년 동안 문제가 발생하면 문제가 발생합니다. 예를 들어

:

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 

실수가 위치한 곳은 "1"로 WEEK_OF_YEAR 걸리지 만 년 "2014"로, 이렇게 출력이 기술적으로 정확하기 때문에 나는 알고 있습니다. 내 목적이 잘못되었습니다.

1 주일에 2015 년 다음 월요일을 원한다는 것을 캘린더 개체에 어떻게 알릴 수 있습니까?

+0

가능한 복제본 [특정 날짜 이후 첫 번째 월요일에 도착할 수 있습니까?] (http://stackoverflow.com/questions/7565356/get-first-monday-after-date) 및 [this] (http : // stackoverflow .com/q/9612328/642706) 및 [this] (http://stackoverflow.com/q/10072914/642706) 및 [this] (http://stackoverflow.com/q/26754164/642706) 및 기타 . 팁 : Joda-Time. –

+0

당신의 산출물에 단지 일년이 아닌 일 또한 잘못되었습니다. 2014-12-29에 이어 첫 번째 월요일은 2015-01-05 (6 일 아니라)입니다. –

+0

Basil, 자세히보세요 - 다음 월요일 29.12에서 6.1.1 ** 2014 **를 반환합니다.실제로 ** ** 잘못된 것입니다. –

답변

1

UPDATE 범위를 기대하기 때문에 당신은 달에서 1을 뺄 필요가 :Joda-Time 프로젝트는 maintenance mode이며, 팀에서는 java.time 클래스로 마이그레이션을 조언합니다. 이 답은 역사 그대로 남습니다. my newer Answer을 참조하십시오.

Joda 타임

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

위대한, 고마워, 내가 무엇을 찾고 있었는지. 간단하고 포괄적 인. –

0

Date와 Calender를 결합 할 때 이상한 점이 있습니다. 날짜를 구문 분석 할 때 Calender 만 사용하면 효과가 있습니다.

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

편집 : 달력은 달에서 0 (11) (Calendar.JANUARY == 0) // 사실

0

TL; DR

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 enum 개체로 원하는 요일을 지정하십시오. 연말 연시를 초월한 문제는 없습니다.

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

월요일이 현재 날짜 인 경우 TemporalAdjusters.nextOrSame을 사용하십시오.

비슷한 방법뿐만 아니라, 이전일-의 주 제공 : previous & previousOrSame.


소개 java.time은

java.time 프레임 워크는 나중에 자바 8에 내장되어 있습니다. 이러한 클래스는 java.util.Date, Calendar, & SimpleDateFormat과 같이 번거로운 이전 legacy 날짜 - 시간 클래스를 대체합니다.

maintenance mode에있는 Joda-Time 프로젝트는 java.time 클래스로의 마이그레이션을 권장합니다.

자세히 알아 보려면 Oracle Tutorial을 참조하십시오. 그리고 많은 예제와 설명을 위해 스택 오버플로를 검색하십시오. 사양은 JSR 310입니다.

어디에서 java.time 클래스를 얻을 수 있습니까?

  • Java SE 8, Java SE 9, 나중에
    • 내장한다.
    • 번들로 구현 된 표준 Java API의 일부입니다.
    • Java 9에는 몇 가지 사소한 기능과 수정 사항이 추가되었습니다.
  • Java SE 6 및 java.time 기능의 대부분
  • Android

ThreeTen-Extra 프로젝트는 추가 클래스와 java.time를 확장합니다. 이 프로젝트는 향후 java.time에 추가 될 수있는 가능성을 입증합니다. 여기에 Interval, YearWeek, YearQuartermore과 같은 유용한 클래스가 있습니다.

관련 문제