Вопрос по java – Понимание java.util.Calendar WEEK_OF_YEAR [дубликат]

10

This question already has an answer here:

Я пытаюсь понять, какjava.util.Calendar.get(java.util.Calendar.WEEK_OF_YEAR) работает, но, похоже, мне не хватает некоторых моментов.

String time = "1998-12-31"; // year month day
java.util.Calendar date = java.util.Calendar.getInstance();
date.setTime((new java.text.SimpleDateFormat("yyyy-MM-dd")).parse(time));
System.err.println("Week of year = " + date.get(java.util.Calendar.WEEK_OF_YEAR));
// Week of year = 1 Why ???

Зачемdate.get(java.util.Calendar.WEEK_OF_YEAR) возвращает 1 за последнюю неделю года?

Более того,WEEK_OF_YEAR за"1998-01-01" это 1 и для"1998-12-23" это 52.
У кого-нибудь есть объяснение этому поведению?

@Corbin, & quot; Первый день недели = 1 & quot; и "Минимальные дни на первой неделе = 1". Но я все еще не понимаю, как это может повлиять на последнюю неделю года, чтобы быть 1. khachik
Это печатаетWeek of year = 53 для меня. Просто проверьте код, который вы опубликовали, и полученный вами результат находится в том же месте. adarshr
Это будет зависеть от конкретной локали. Внимательно ли вы прочитали руководство по WEEK_OF_YEAR и изучили ваши значения для getFirstDayOfWeek и getMinimalDaysInFirstWeek? Corbin
@adashr, проверил, печатает 1. khachik
В некоторых странах (например, в США, согласно Википедии) первая неделя - это неделя с 1 января. 31. Дез 98 был четверг, так что это в первую неделю 1999 года IchBinKeinBaum

Ваш Ответ

2   ответа
5

tl;dr

java.time.LocalDate.parse( "1998-12-31" )
    .get( IsoFields.WEEK_OF_WEEK_BASED_YEAR )

53

Или добавьте библиотеку, а затем & # x2026;

org.threeten.extra.YearWeek.from(     // Convert from a `LocalDate` object to a `YearWeek` object representing the entire week of that date’s week-based year.
    LocalDate.parse( "1998-12-31" )   // Parse string into a `LocalDate` objects. 
).getWeek()                           // Extract an integer number of that week of week-based-year, either 1-52 or 1-53 depending on the year.

53

Details

I'm trying to understand how java.util.Calendar.get(java.util.Calendar.WEEK_OF_YEAR) works

Don’t! Этот класс - кровавый беспорядок, и лучше его оставить забытым.

ответ по нпэ верно. ВCalendarопределение недели зависит от региона. Благими намерениями, но сбивает с толку.

Standard week definition

Существует множество способов определения & # x201C; недели & # x201D; и & # x201C; первая неделя года & # x201D ;.

Тем не менее, естьодно основное стандартное определение:Стандарт ISO 8601, Этот стандарт определяетнедели года, в том числепервая неделя года.

the week with the year's first Thursday

Стандартная неделя начинается с понедельника и заканчивается воскресеньем.

Неделя № 1 стандартного года на основе недели имеет первый четверг календарного года.

java.time

java.time классы вытеснили хлопотные унаследованные классы даты и времени. Эти современные классы поддерживают неделю ISO 8601 черезIsoFields класс, содержащий три константы, которые реализуютTemporalField:

ВызовLocalDate::get чтобы получить доступ кTemporalField.

LocalDate ld = LocalDate.parse( "1998-12-31" ) ;
int weekOfWeekBasedYear = ld.get( IsoFields.WEEK_OF_WEEK_BASED_YEAR ) ;
int yearOfWeekBasedYear = ld.get( IsoFields.WEEK_BASED_YEAR ) ;

ld.toString(): 1998-12-31

weekOfWeekBasedYear: 53

yearOfWeekBasedYear: 1998

Обратите внимание, что следующий день, первый день нового календарного 1999 года, также относится к той же неделе, неделе № 53 недельного 1998 года.

LocalDate firstOf1999 = ld.plusDays( 1 );
int weekOfWeekBasedYear_FirstOf1999 = firstOf1999.get( IsoFields.WEEK_OF_WEEK_BASED_YEAR ) ;
int yearOfWeekBasedYear_FirstOf1999 = firstOf1999.get( IsoFields.WEEK_BASED_YEAR ) ;

firstOf1999.toString(): 1999-01-01

weekOfWeekBasedYear_FirstOf1999: 53

yearOfWeekBasedYear_FirstOf1999: 1998

ISO 8601 string format

ISO 8601 Стандарт определяет текстовый формат, а также значение для значений недельного года:yyyy-Www, Для конкретной даты добавьте день недели с номером 1-7 для понедельника-воскресенья:yyyy-Www-d.

Построить такую строку.

String outputWeek = ld.format( DateTimeFormatter.ISO_WEEK_DATE ) ;  // yyyy-Www 

1998-W53

String outputDate = outputWeek + "-" + ld.getDayOfWeek().getValue() ;  // yyyy-Www-d

1998-W53-4

YearWeek

Эта работа намного проще, если вы добавитеThreeTen-Extra библиотека для вашего проекта. Затем используйтеYearWeek учебный класс.

YearWeek yw = YearWeek.from( ld ) ;  // Determine ISO 8601 week of a `LocalDate`. 

Сгенерируйте стандартную строку.

String output = yw.toString() ;

1998-W53

И разбор.

YearWeek yearWeek = YearWeek.parse( "1998-W53" ) ;  

yearWeek.toString(): 1998-W53

Определить дату. Пройтиjava.time.DayOfWeek enum объект для дня недели с понедельника по воскресенье.

LocalDate localDate = yw.atDay( DayOfWeek.MONDAY ) ;

localDate.toString(): 1998-12-28

Я настоятельно рекомендую добавить эту библиотеку в ваш проект. Тогда вы можете передавать умные объекты, а не тупые целые. Это делает ваш код более самодокументированным, обеспечиваеттипа безопасностии обеспечивает действительные значения.


About java.time

java.time фреймворк встроен в Java 8 и выше. Эти классы вытесняют хлопотное староенаследие классы даты и времени, такие какjava.util.Date, Calendar& amp;SimpleDateFormat.

Joda-Time проект, сейчас вРежим технического обслуживанияПосоветует миграцию наjava.time классы.

Чтобы узнать больше, см.Oracle Tutorial, И поиск переполнения стека для многих примеров и объяснений. СпецификацияJSR 310.

ИспользуяДрайвер JDBC совместимый сJDBC 4.2 или позже, вы можете обменятьjava.time объекты непосредственно с вашей базой данных. Нет необходимости ни в строках, ни в java.sql. * Классах.

Где взять классы java.time?

ThreeTen-Extra Проект расширяет java.time дополнительными классами. Этот проект является полигоном для возможных будущих дополнений к java.time. Вы можете найти некоторые полезные классы здесь, такие какInterval, YearWeek, YearQuarter, а такжеБольше.


Joda-Time

UPDATE: Joda времени проект сейчас вРежим технического обслуживания, с командой, советующей перейти наjava.time классы. Этот раздел остался нетронутым как история.

Отличная среда Joda-Time использует ISO 8601 для своих значений по умолчанию. Его уроки включают эту информацию за неделю года. Joda-Time - популярная замена общеизвестно хлопотного java.util.Date & amp; Классы java.util.Calendar в комплекте с Java.

Example Code

Вот пример кода, чтобы получить первый момент первого дня первой недели года текущей даты-времени.

Обратите внимание на призыв кwithTimeAtStartOfDay чтобы получить первый момент дня.

DateTimeZone timeZone = DateTimeZone.forID( "Europe/Paris" );

DateTime now = new DateTime( timeZone );
DateTime firstWeekStart = now.withWeekOfWeekyear(1).withDayOfWeek(1).withTimeAtStartOfDay();
DateTime firstWeekStop = firstWeekStart.plusWeeks( 1 );
Interval firstWeek = new Interval( firstWeekStart, firstWeekStop );

Дамп на консоль & # x2026;

System.out.println( "now: " + now );
System.out.println( "firstWeekStart: " + firstWeekStart );
System.out.println( "firstWeekStop: " + firstWeekStop );
System.out.println( "firstWeek: " + firstWeek );

При запуске & # x2026;

now: 2014-02-07T12:49:33.623+01:00
firstWeekStart: 2013-12-30T00:00:00.000+01:00
firstWeekStop: 2014-01-06T00:00:00.000+01:00
firstWeek: 2013-12-30T00:00:00.000+01:00/2014-01-06T00:00:00.000+01:00
Error: User Rate Limit Exceededjava.time?
Error: User Rate Limit Exceeded
11

Отjava.util.Calendar javadoc:

First Week

Calendar defines a locale-specific seven day week using two parameters: the first day of the week and the minimal days in first week (from 1 to 7). These numbers are taken from the locale resource data when a Calendar is constructed. They may also be specified explicitly through the methods for setting their values.

When setting or getting the WEEK_OF_MONTH or WEEK_OF_YEAR fields, Calendar must determine the first week of the month or year as a reference point. The first week of a month or year is defined as the earliest seven day period beginning on getFirstDayOfWeek() and containing at least getMinimalDaysInFirstWeek() days of that month or year. Weeks numbered ..., -1, 0 precede the first week; weeks numbered 2, 3,... follow it. Note that the normalized numbering returned by get() may be different. For example, a specific Calendar subclass may designate the week before week 1 of a year as week n of the previous year.

Так что это зависит от региона. В вашем случае, если неделя содержит дни с нового года, она считается как неделя 1 с нового года.

Вы можете изменить это поведение, используяКалендарь # setMinimalDaysInFirstWeek (INT).

Error: User Rate Limit Exceeded
Error: User Rate Limit ExceededsetMinimalDaysInFirstWeekError: User Rate Limit Exceeded khachik

Похожие вопросы