Например:
Calendar c = Calendar.getInstance();
DateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
c.setTime( sdf.parse("31/12/2010"));
out.println( c.get( Calendar.WEEK_OF_YEAR ) );
Печать 1
То же самое происходит с временем Джоды.
:)
Например:
Calendar c = Calendar.getInstance();
DateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
c.setTime( sdf.parse("31/12/2010"));
out.println( c.get( Calendar.WEEK_OF_YEAR ) );
Печать 1
То же самое происходит с временем Джоды.
:)
Определение недели года Locale
зависит.
Как он определен в США, он обсуждается в других сообщениях. Например, в Германии (DIN 1355-1/ISO 8601): первая неделя * года - это первая неделя с 4 или более днями в новом году.
* первый день недели - понедельник и последний день недели - воскресенье
И Javas Calendar
обращает внимание на локаль. Например:
public static void main(String[] args) throws ParseException {
DateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
Date lastDec2010 = sdf.parse("31/12/2010");
Calendar calUs = Calendar.getInstance(Locale.US);
calUs.setTime(lastDec2010);
Calendar calDe = Calendar.getInstance(Locale.GERMAN);
calDe.setTime(lastDec2010);
System.out.println( "us: " + calUs.get( Calendar.WEEK_OF_YEAR ) );
System.out.println( "de: " + calDe.get( Calendar.WEEK_OF_YEAR ) );
}
печатает:
us: 1
de: 52
ADDED Для США (и я могу думать, что это то же самое для Мексики) 1. Неделя года - это неделя, на которую принадлежит 1. январь. - Итак, если 1. Januar - суббота, то пятница до (31. Dec) относится к той же неделе, и в этом случае этот день относится к 1. Неделе 2011 года.
Значения, рассчитанные для WEEK_OF_YEAR диапазон полей от 1 до 53. Неделя 1 для год - это самый ранний семидневный период начиная с getFirstDayOfWeek(), который содержит не менее getMinimalDaysInFirstWeek() дней от этот год. Следовательно, это зависит от значения getMinimalDaysInFirstWeek(), getFirstDayOfWeek() и день неделя 1 января. Недели между неделя 1 года и 1-й недели следующий год пронумерованы последовательно от 2 до 52 или 53 (как необходимо).
Чтобы определить, является ли эта неделя последней неделей 2010 года или первой из 2011 года, Java использует getMinimalDaysInFirstWeek
javadoc. Если этот метод возвращает 7, то первая неделя, в которой все дни недели относятся к тому же году, относится к первой неделе, если она вернется 1, то первая неделя с любыми днями следующего года будет первой неделей следующего года.
В этом случае первое января 2011 года состоится в субботу, поэтому считается первой неделей 2011 года, если вы хотите, чтобы неделя с одним днем считалась уже первой неделей следующего года, если вы не делайте этого:
Calendar c = Calendar.getInstance();
c.setMinimalDaysInFirstWeek(7);//anything more than 1 will work in this year
DateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
c.setTime( sdf.parse("31/12/2010"));
System.out.println( c.get( Calendar.WEEK_OF_YEAR ) );
возвращает:
52
IIRC, первая неделя с датой 1 января - неделя 1.
Вот почему неделя 1 возвращается за 31.12.2010.
Попробуйте 12/31/2011, и вы получите 52.
Изменить: неделя является специфичной для локали, иногда определяемой как воскресенье - суббота, иногда определяется как понедельник - воскресенье
Это связано с тем, что начало недели зависит от локального.
В США неделя 1 начинается в воскресенье до 1 января. В 2010 году это 26 декабря. Почему 31 декабря по-прежнему остается 1-й неделей.
В Европе неделя 1 начинается в понедельник до 1 января. В 2010 году это 27 декабря. Почему же в Европе 31 декабря по-прежнему остается 1-й.
java.time.LocalDate.parse(
"31/12/2010" ,
DateTimeFormatter.ofLocalizedDate( FormatStyle.SHORT ).withLocale( Locale.UK )
)
.get( IsoFields.WEEK_OF_WEEK_BASED_YEAR )
52
Или добавьте библиотеку, а затем...
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.
java.time.LocalDate.parse( "31/12/2010" , DateTimeFormatter.ofLocalizedDate( FormatStyle.SHORT ).withLocale( Locale.UK )
).getWeek() // Extract an integer number of that week of week-based-year, either 1-52 or 1-53 depending on the year.
52
Как отмечалось другими, определение недели изменяется в Locale
в старом классе java.util.Calendar
.
Этот трудный класс и его партнер java.util.Date
были вытеснены инфраструктурой java.time, встроенной в Java 8 и более поздние версии.
Класс IsoFields
определяет неделю, используя ISO 8601: неделя всегда начинается в понедельник, а неделя № 1 проводится в первый четверг календарного года.
Получить текущий момент.
ZoneId zoneId = ZoneId.of ( "America/Montreal" );
ZonedDateTime now = ZonedDateTime.now ( zoneId );
Спросите о стандартном недельном году.
int week = now.get ( IsoFields.WEEK_OF_WEEK_BASED_YEAR );
int weekYear = now.get ( IsoFields.WEEK_BASED_YEAR );
Существует множество способов определить "неделю" и "первую неделю года".
Однако существует одно основное стандартное определение: ISO 8601. Этот стандарт определяет недели года, включая первую неделю года.
неделя с годом первый четверг
Стандартные недели начинаются с понедельника и заканчиваются в воскресенье.
Неделя № 1 недельного года имеет первый четверг календарного года.
Классы java.time поддерживают неделю ISO 8601 через класс IsoFields
, содержащий три константы, которые реализуют TemporalField
:
Вызовите LocalDate::get
для доступа к TemporalField
.
LocalDate ld = LocalDate.parse( "2010-12-31" ) ;
int weekOfWeekBasedYear = ld.get( IsoFields.WEEK_OF_WEEK_BASED_YEAR ) ;
int yearOfWeekBasedYear = ld.get( IsoFields.WEEK_BASED_YEAR ) ;
ld.toString(): 2010-12-31
weekOfWeekBasedYear: 52
yearOfWeekBasedYear: 2010
Стандарт ISO 8601 определяет текстовый формат, а также значение для значений недельного года: yyyy-Www
. На определенную дату добавьте день недели с номером 1-7 в понедельник-воскресенье: yyyy-Www-d
.
Создайте такую строку.
String outputWeek = String.format( "%04d" , yearOfWeekBasedYear ) + "-W" + String.format( "%02d" , weekOfWeekBasedYear ) ;
String outputDate = outputWeek + "-" + ld.getDayOfWeek().getValue() ;
2010-W52-5
YearWeek
Эта работа намного проще, если вы добавите в свой проект библиотеку ThreeTen-Extra. Затем используйте класс YearWeek
.
YearWeek yw = YearWeek.from( ld ) ; // Determine ISO 8601 week of a `LocalDate`.
Создать стандартную строку.
String output = yw.toString() ;
2010-W52
И проанализируйте.
YearWeek yearWeek = YearWeek.parse( "2010-W52" ) ;
yearWeek.toString(): 2010-W52
Определите дату. Передайте объект java.time.DayOfWeek
enum для дня недели с понедельника по воскресенье.
LocalDate localDate = yw.atDay( DayOfWeek.MONDAY ) ;
localDate.toString(): 2010-12-27
Я настоятельно рекомендую добавить эту библиотеку в ваш проект. Затем вы можете передавать интеллектуальные объекты, а не тупые ints. Это делает ваш код более самодокументированным, обеспечивает тип безопасности и обеспечивает допустимые значения.
Структура java.time встроена в Java 8 и более поздних версий. Эти классы вытесняют неприятный старый legacy классы даты-времени, такие как java.util.Date
, Calendar
и SimpleDateFormat
.
Проект Joda-Time, теперь в режим обслуживания, советуем перейти к классам java.time.
Чтобы узнать больше, см. Учебник Oracle. И поиск Qaru для многих примеров и объяснений. Спецификация JSR 310.
Использование JDBC-драйвера, совместимого с JDBC 4.2 или позже вы можете обменивать java.time-объекты непосредственно с вашей базой данных. Нет необходимости в строках или java.sql. * Classes.
Где получить классы java.time?
Проект ThreeTen-Extra расширяет java.time с дополнительными классами. Этот проект является доказательством возможных будущих дополнений к java.time. Здесь вы можете найти полезные классы, такие как Interval
, YearWeek
, YearQuarter
и больше.
Более подробно см. мой ответ по аналогичному вопросу:
... и см. мой ответ по аналогичному вопросу:
Я считаю, что это лучший подход.
Calendar c = Calendar.getInstance();
DateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
c.setTime( sdf.parse("31/12/2010"));
int thisWeek = c.get(Calendar.WEEK_OF_YEAR);
if (c.get(Calendar.MONTH) == Calendar.DECEMBER && thisWeek == 1)
thisWeek = 53;
System.out.println(thisWeek);
Основное предположение здесь состоит в том, что в течение декабря неделя не может быть 1, следовательно, просто возвращается 53.
Пожалуйста, предложите, если я где-то ошибаюсь и почему это не реализовано в календаре Java.