У меня есть небольшая программа, отображающая текущую неделю с сегодняшней даты, например:
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 и т. Д.)? Если бы кто-нибудь мог мне помочь, я был бы признателен!
Нужно ли сохранять ввод в виде строки? Целое число?
При использовании JTextField
вход, который вы получаете от пользователя, является String
, так как дата может содержать символы типа .
или -
, в зависимости от выбранного формата даты. Разумеется, вы также можете использовать несколько более сложных методов ввода, где поле ввода уже проверяет формат даты и возвращает отдельные значения для дня, месяца и года, но с использованием JTextField
конечно, легче начать.
И в каком формате он должен быть (yyyyMMdd и т. Д.)?
Это зависит от ваших требований. Вы можете использовать class 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 предоставляет вам несколько новых classов в пакете 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
для интерпретации даты ввода. Например, см. Главный ответ на тему Преобразование String в объект Calendar в 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
же, как вы показали в вопросе. (Это упрощенный пример. Вам нужно будет обработать потенциальное ParseException
, DateFormat
методом parse
DateFormat
.)
YearWeek.of( LocalDate.parse( "2017-01-23" ) ) .getWeek() // and .getYear()
Если вы хотите, чтобы стандартная неделя ISO 8601 , а не локализованное определение недели, используйте class YearWeek
найденный в проекте ThreeTen-Extra, который добавляет функциональность classам java.time, встроенным в Java 8 и более поздние версии .
ISO-8601 определяет неделю, как всегда, начиная с понедельника. Первая неделя – это неделя, которая содержит первый четверг календарного года. Таким образом, недельный год, используемый в этом classе, не совпадает с календарным годом.
Во-первых, получите сегодняшнюю дату. Класс 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, YYYY-MM-DD, такой как 2017-01-23
.
LocalDate ld = LocalDate.parse( "2017-01-23" ) ;
Для других форматов задайте параметр DateTimeFormatter
для синтаксического анализа. Поиск переполнения стека для многих примеров использования этого classа.
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 на год-неделю , yyyy-Www, например 2017-W45
. Или вы можете извлечь каждый номер.
YearWeek::getWeek
– получает поле недели недели по неделям. YearWeek::getYear
– получает поле недели за год. Вышеприведенное обсуждение предполагает, что вы определяете определение недель и нумерацию по стандарту ISO 8601 . Если вместо этого вы хотите альтернативное определение недельной и недельной нумерации, см. Ответ Mobolaji D., используя определение локали.
Рамка java.time встроена в Java 8 и более поздние версии . Эти classы вытесняют неприятные старые устаревшие classы времени, такие как java.util.Date
, Calendar
и SimpleDateFormat
.
Проект Joda-Time , теперь в режиме обслуживания , советует перейти на classы java.time .
Чтобы узнать больше, ознакомьтесь с учебным пособием Oracle . И поиск Stack Overflow для многих примеров и объяснений. Спецификация – JSR 310 .
Где можно получить classы java.time?
Проект ThreeTen-Extra расширяет java.time с дополнительными classами. Этот проект является доказательством возможных будущих дополнений к java.time. Здесь вы можете найти полезные classы, такие как 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
из java API
. Вы можете указать любой желаемый формат. После этого вы сможете манипулировать, чтобы получить неделю в году.
public static int getWeek() { return Calendar.getInstance().get(Calendar.WEEK_OF_YEAR); }
Работает отлично и возвращает неделю для текущего реального времени
этот работал для меня
public void sortListItems(List list) { Collections.sort(list, new Comparator () { 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; } }); }