Java: получить номер недели с любой даты?
у меня есть небольшая программа, которая отображает текущую неделю с сегодняшней датой, так:
GregorianCalendar gc = new GregorianCalendar();
int day = 0;
gc.add(Calendar.DATE, day);
а затем JLabel, который отображает номер недели:
JLabel week = new JLabel("Week " + gc.get(Calendar.WEEK_OF_YEAR));
поэтому прямо сейчас я хотел бы иметь JTextField, где вы можете ввести дату, и JLabel будет обновляться с номером недели этой даты. Я действительно не уверен, как это сделать, поскольку я совершенно новичок в Java. Нужно ли сохранять входные данные в виде строки? Целое число? И какой формат должен быть (yyyyMMdd и т. д.)? Если любой мог бы мне помочь, я был бы признателен!
8 ответов
нужно ли сохранять входные данные в виде строки? Целое число?
при использовании JTextField
, вход, который вы получаете от пользователя, является String
, так как дата может содержать символы, такие как .
или -
, в зависимости от выбранного формата даты. Конечно, вы можете также использовать более сложные методы ввода, где поле ввода уже проверяет формат даты и возвращает отдельные значения для дня, месяца и года, но с помощью JTextField
is конечно, с этого легче начать.
и какой формат должен быть (yyyyMMdd и т. д.)?
это зависит от ваших требований. Вы можете использовать SimpleDateFormat класс для анализа любого формата даты:
String input = "20130507";
String format = "yyyyMMdd";
SimpleDateFormat df = new SimpleDateFormat(format);
Date date = df.parse(input);
Calendar cal = Calendar.getInstance();
cal.setTime(date);
int week = cal.get(Calendar.WEEK_OF_YEAR);
но, скорее всего, вы хотите использовать формат даты, специфичный для вашей локали:
import java.text.DateFormat;
DateFormat defaultFormat = DateFormat.getDateInstance();
Date date = defaultFormat.parse(input);
чтобы дать пользователю подсказку о том, какой формат использовать, нужно бросил DateFormat
в SimpleDateFormat
получить строку шаблона:
if (defaultFormat instanceof SimpleDateFormat) {
SimpleDateFormat sdf = (SimpleDateFormat)defaultFormat;
System.out.println("Use date format like: " + sdf.toPattern());
}
комментарий @adenoyelle выше напоминает мне:напишите модульные тесты для кода синтаксического анализа даты.
в Java 1.8 предоставляет вам некоторые новые классы в пакет java.time
:
import java.time.Instant;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.temporal.IsoFields;
ZonedDateTime now = ZonedDateTime.ofInstant(Instant.now(), ZoneId.systemDefault());
System.out.printf("Week %d%n", now.get(IsoFields.WEEK_OF_WEEK_BASED_YEAR));
большинство устаревших календарей можно легко преобразовать в java.time.ZonedDateTime
/ java.time.Instant
методами взаимодействия, в вашем конкретном случае GregorianCalendar.toZonedDateTime()
.
вы можете сохранить дату в виде строки, и пользователь может ввести ее практически в любом формате, который вы укажете. Вам просто нужно использовать DateFormat
объект для интерпретации даты, которую они вводят. Например, см. лучшие ответы on преобразовать строку в объект календаря в Java.
Calendar cal = Calendar.getInstance();
SimpleDateFormat sdf = new SimpleDateFormat("EEE MMM dd HH:mm:ss z yyyy");
cal.setTime(sdf.parse("Mon Mar 14 16:02:37 GMT 2011"));
чтобы прочитать дату из JTextField
, вы можете заменить это чем-то вроде:
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); // or any other date format
cal.setTime(sdf.parse(dateTextField.getText()));
тогда вам просто нужно прочитать номер недели из cal
in так же, как вы показали в вопросе. (Это упрощенный пример. Вам нужно будет справиться с потенциалом ParseException
выдано DateFormat
parse
метод.)
tl; dr
YearWeek.of( LocalDate.parse( "2017-01-23" ) )
.getWeek() // and .getYear()
ISO 8601 стандартная неделя
если вы хотите стандарт ISO 8601 неделя, а не локализованное определение недели, используйте YearWeek
класса в ThreeTen-Extra проект, который добавляет функциональность в java.время классы, встроенные в Java 8 и выше.
ISO 8601 определяет недели, как всегда, начиная с понедельника. Этот первая неделя-это неделя, которая содержит первый четверг календарного года. Таким образом, год недели, используемый в этом классе, не совпадает с календарным годом.
во-первых, получить сегодняшнюю дату. The LocalDate
класс представляет значение только даты без времени суток и без часового пояса.
часовой пояс имеет решающее значение для определения даты. Для любого данного момента дата варьируется по всему миру по зонам. Например, через несколько минут после полночь в Париж, Франция новый день пока еще "вчера" в Квебека Монреале.
указать правильное название часового пояса в формате continent/region
, например America/Montreal
, Africa/Casablanca
или Pacific/Auckland
. Никогда не используйте аббревиатуру из 3-4 букв, такую как EST
или IST
как они не истинные часовые пояса, не стандартизированные и даже не уникальные(!).
ZoneId z = ZoneId.of( "America/Montreal" );
LocalDate today = LocalDate.now( z );
или пусть пользователь указывает дату, введя строку. Синтаксический анализ строкового ввода даты покрывается в много другие вопросы и ответы. Проще всего, чтобы пользователь использовал стандартный формат ISO 8601, гггг-ММ-ДД, такой как 2017-01-23
.
LocalDate ld = LocalDate.parse( "2017-01-23" ) ;
для других форматов, указать DateTimeFormatter
для разбора. Search Stack Overflow для многих примеров использования этого класса.
DateTimeFormatter f = DateTimeFormatter.ofPattern( "d/M/uuuu" , Locale.US ) ;
LocalDate ld = LocalDate.parse( "1/23/2017" , f ) ;
скачать YearWeek
.
YearWeek yw = YearWeek.of( ld ) ;
чтобы создать строку, рассмотрим с помощью стандартный формат ISO 8601 для Года-недели, гггг-Www такие как 2017-W45
. Или вы можете извлечь каждый номер.
-
YearWeek::getWeek
– получает поле недели недели на основе года. -
YearWeek::getYear
– получает поле недели на основе года.
другие определения недели
выше обсуждение предполагает, что вы идете по ISO 8601 определение недель и нумерации. Если же вы хотите альтернативный определение недели и нумерации недель, см. ответ Mobolaji D. использование определения локали.
о java.время
на java.время framework встроен в Java 8 и более поздние версии. Эти классы вытесняют беспокойных старых наследие классы даты и времени, такие как java.util.Date
, Calendar
, & SimpleDateFormat
.
на Joda Времени проект, в настоящее время в режим обслуживания, советует миграцию в java.время классы.
чтобы узнать больше, см. В Oracle Учебник. И search Stack Overflow для многих примеров и объяснений. Спецификация JSR 310.
где получить java.время занятий?
-
Java SE 8, Java SE 9, и позже
- встроенный.
- часть стандартного API Java со встроенной реализацией.
- Java 9 добавляет некоторые незначительные функции и исправления.
-
Java SE 6 и Java SE 7
- большая часть java.функциональность времени обратно портирована на Java 6 & 7 в ThreeTen-Backport.
-
Android
- на ThreeTenABP проект приспосабливается ThreeTen-Backport (упомянуто выше) для Android конкретно.
- посмотреть как использовать ThreeTenABP....
в ThreeTen-Extra проект расширяет java.время с дополнительными занятиями. Этот проект является испытательной площадкой для возможных будущих дополнений к java.время. Здесь вы можете найти полезные классы, такие как Interval
, YearWeek
, YearQuarter
и больше.
WeekFields
этот метод, который я создал, работает для меня в Java 8 и позже, используя WeekFields
, DateTimeFormatter
, LocalDate
и TemporalField
.
Не забудьте правильно отформатировать дату на основе вашего варианта использования!
public int getWeekNum(String input) {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("M/dd/yy"); // Define formatting pattern to match your input string.
LocalDate date = LocalDate.parse(input, formatter); // Parse string into a `LocalDate` object.
WeekFields wf = WeekFields.of(Locale.getDefault()) ; // Use week fields appropriate to your locale. People in different places define a week and week-number differently, such as starting on a Monday or a Sunday, and so on.
TemporalField weekNum = wf.weekOfWeekBasedYear(); // Represent the idea of this locale’s definition of week number as a `TemporalField`.
int week = Integer.parseInt(String.format("%02d",date.get(weekNum))); // Using that locale’s definition of week number, determine the week-number for this particular `LocalDate` value.
return week;
}
вы можете использовать это, но вы должны проанализировать значение даты в надлежащем формате даты, используя SimpleDateFormatter
of java API
. Вы можете указать любой формат. После этого вы можете сделать вам манипуляции, чтобы получить неделю в году.
public static int getWeek() {
return Calendar.getInstance().get(Calendar.WEEK_OF_YEAR);
}
отлично работает и возвращает неделю для текущего реального времени
это сработало для меня
public void sortListItems(List<PostModel> list) {
Collections.sort(list, new Comparator<PostModel>() {
DateFormat dateFormat = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss");
@Override
public int compare(PostModel o1, PostModel o2) {
int ret = 0;
try {
ret = dateFormat.parse(o1.getDate()).compareTo(dateFormat.parse(o2.getDate()));
return ret;
} catch (ParseException e) {
e.printStackTrace();
}
return ret;
}
});
}