2015-09-28 16 views
7

Mam dwie liczby całkowite: year i week. Chciałbym zbudować LocalDateTime z tych dwóch wartości, gdzie data reprezentuje pierwszy dzień danego tygodnia w danym roku.Pobierz LocalDateTime na podstawie roku i tygodnia roku

ja już próbowałem:

LocalDateTime ldt = LocalDateTime.of(year, 1, 1, 0, 0).plusWeeks(week-1); 

To nie daje poprawny wynik, ponieważ pierwszy dzień roku nie zawsze jest początkiem pierwszego tygodnia tego roku. Nie mogę też wymyślić, jak zdobyć pierwszy dzień pierwszego tygodnia.

Czy istnieje prosty sposób, aby to zrobić za pomocą interfejsu API Data i godzina w języku Java 8?

Uwaga: Wiem, że można również utworzyć obejście z odpowiedziami podanymi here, ale wydaje się to zbyt daleko idące. Może tak nie jest, jeśli tak, daj mi znać!

+0

tydzień w ciągu roku jest specyficzne narodowe, a więc tych, dwa punkty danych nie podadzą dokładnej daty. AFAIK 'LocalDateTime' nie obsługuje tego faktu, ale' GregorianCalendar' robi. – biziclop

+0

@biziclop Myślę, że dokładnie tego chce. Regionalny tydzień "1" - więc dla niektórych chłopaków pierwszy 4-dniowy tydzień, dla innych coś innego. – dognose

+0

@dognose Następnie "kalendarz gregoriański" jest rzeczywiście drogą do zrobienia. – biziclop

Odpowiedz

9

Poniższy kod dostanie LocalDateTime i ustawić go na pierwszy dzień danego tygodni z roku na dany rok:

int week = 1; 
int year = 2016; 
WeekFields weekFields = WeekFields.of(Locale.getDefault()); 
LocalDateTime ldt = LocalDateTime.now() 
          .withYear(year) 
          .with(weekFields.weekOfYear(), week) 
          .with(weekFields.dayOfWeek(), 1); 
System.out.println(ldt); 

Należy zauważyć, że pojęcie tygodnie-z-roku to locale konkretny. Tutaj użyłem domyślnego ustawienia narodowego, ale może być konieczne użycie ustawień regionalnych podanych przez użytkownika.

Jeśli chcesz pozbyć się części czasu, możesz dodać połączenie pod numer truncatedTo(ChronoUnit.DAYS).

3

można spróbować zanalizować ciąg znaków reprezentujący dzień jesteś zainteresowany:

private static final DateTimeFormatter YEAR_WEEK = DateTimeFormatter.ofPattern("YYYY-w-e", Locale.getDefault()); 

public static LocalDate fromYearWeek(int year, int week) { 
    return LocalDate.parse(year + "-" + week + "-1", YEAR_WEEK); 
} 

Jeśli potrzebujesz LocalDateTime można następnie wykorzystać localDate.atTime(...) lub localDate.atStartOfDay() na przykład.

2
LocalDate ld = LocalDate.parse("2012-W48-1", DateTimeFormatter.ISO_WEEK_DATE); 
+0

Dziękuję za tę odpowiedź! Myślę, że jest bardzo podobny do odpowiedzi assylias, a także nieco niekompletny. Może mógłbyś to edytować, żeby wyjaśnić, dlaczego jest inaczej. – bashoogzaad

+0

jest podobny, ale unikaj tworzenia dodatkowej instancji LocalDate – Vovka

1

ThreeTen-Extra

Projekt ThreeTen-Extra rozciąga java.time z dodatkowych zajęć. Ten projekt jest poligonem wskazującym na możliwe przyszłe dodatki do java.time. Możesz znaleźć tutaj kilka przydatnych klas, takich jak YearWeek.

Jeśli przez "tydzień" miałeś na myśli standard ISO 8601 definition of a week-of-year, gdzie tydzień # 1 zawiera pierwszy czwartek roku, pozwól klasie YearWeek wykonać pracę za Ciebie.

int weekBasedYear = 2015; // Not the calendar year! 
int weekOfYear = 1; 
YearWeek yearWeek = YearWeek.of (weekBasedYear , weekOfYear); 

Można uzyskać wartość tylko dla daty reprezentowaną w obiekcie LocalDate. Określ, który dzień tygodnia chcesz używać, wyliczając DayOfWeek, gdzie poniedziałek jest pierwszym dniem tygodnia, a niedziela jest ostatnim dniem. Pamiętaj, że tydzień ISO zawsze rozpoczyna się w poniedziałek i zawsze kończy w niedzielę.

LocalDate mondayOfYearWeek = yearWeek.atDay (DayOfWeek.MONDAY); 
LocalDate sundayOfYearWeek = yearWeek.atDay (DayOfWeek.SUNDAY); 

Zrzut na konsolę. Zwróć uwagę, jak rozpoczyna się tydzień w poprzednim roku kalendarzowym (2014), a kończy w 2015 roku, ponieważ 1 stycznia 2015 roku jest czwartkiem, więc jest to tydzień nr 1 w ISO. W następną niedzielę 4 stycznia 2015 roku kończy się Tydzień ISO nr 1.

System.out.println ("yearWeek: " + yearWeek + " starts on mondayOfYearWeek: " + mondayOfYearWeek + " and ends on sundayOfYearWeek: " + sundayOfYearWeek); 

yearWeek: 2015-W01 rozpoczyna się mondayOfYearWeek: 2014-12-29, a kończy na sundayOfYearWeek: numeracja 2015-01-04

+1

jest to dobre, ale problem polega na użyciu innej zależności. Chciałbym, żeby takie intuicyjne API zostało dodane w samym jdk. –