Я новичок в использовании пакета DateTimeFormatter, и то же самое мы можем получить, используя SimpleDateFormat.
Date date = new SimpleDateFormat("MMMM").parse(month);//"DECEMBER"
Date date = new SimpleDateFormat("yyyy").parse(year);//"2020"
Как добиться этого с помощью DateTimeFormatter?
@Naman Независимо от того, используете ли вы устаревшее SimpleDateFormat или современное DateTimeFormatter, MMMM означает полное название месяца, например. December, в отличие, например, от аббревиатуры месяца (MMM вместо Dec).




проверьте эту ссылку https://www.baeldung.com/java-datetimeformatter. вы можете использовать пользовательский формат как
String europeanDatePattern = "dd.MM.yyyy";
DateTimeFormatter europeanDateFormatter = DateTimeFormatter.ofPattern(europeanDatePattern);
System.out.println(europeanDateFormatter.format(LocalDate.of(2016, 7, 31)))
DateTimeFormatter не поддерживает класс util.Date, здесь вам нужно использовать класс LocalDate. Вы не можете анализировать только с помощью month или year, вы должны передать 3 значения month, day и year, чтобы получить дату.
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy MM dd");
LocalDate parsedDate = LocalDate.parse("2020 12 15", formatter);
System.out.print(parsedDate); //2020-12-15
String monthString = "December";
DateTimeFormatter monthFormatter
= DateTimeFormatter.ofPattern("MMMM", Locale.ENGLISH);
Month month = monthFormatter.parse(monthString, Month::from);
System.out.println(month);
Выход:
ДЕКАБРЬ
Год несколько проще. Нам форматтер не нужен.
String yearString = "2020";
Year year = Year.parse(yearString);
System.out.println(year);
2020
Старый класс Date, несмотря на свое название, никогда не представлял дату. Это был момент времени. Тем не менее, мы обычно использовали его для даты, времени дня, месяца, года и других целей, иногда также для того момента времени, когда это было. Одним из очень запутанных последствий было то, что объекты Date, полученные из кода в вашем вопросе, в редких случаях неправильно печатались как ноябрь вместо декабря и как 2019 вместо 2020 года. Вам больше не следует использовать класс Date. Он всегда был плохо спроектирован и давно устарел.
С другой стороны, java.time, современный API даты и времени Java, к которому принадлежит DateTimeFormatter, определяет класс для каждого такого понятия: LocalDate для даты, Month для месяца года, Year для года и т. д. Это делает наш код дает более четкое представление о том, с чем мы имеем дело, и это хорошо. Это также требует, чтобы мы узнали о различных классах и думали о том, какой из них использовать каждый раз.
Если ваша строка месяца была написана заглавными буквами, нам нужно указать программе форматирования выполнять синтаксический анализ без учета регистра:
String monthString = "DECEMBER";
DateTimeFormatter monthFormatter = new DateTimeFormatterBuilder()
.parseCaseInsensitive()
.appendPattern("MMMM")
.toFormatter(Locale.ENGLISH);
Month month = monthFormatter.parse(monthString, Month::from);
Также, если название месяца указано на английском языке, не забудьте указать англоязычную локаль.
API даты и времени java.util и их API форматирования SimpleDateFormat устарели и подвержены ошибкам. Давайте посмотрим на них в действии:
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class Main {
public static void main(String[] args) throws ParseException {
Date date1 = new SimpleDateFormat("MMMM").parse("DECEMBER");
System.out.println(date1);
Date date2 = new SimpleDateFormat("yyyy").parse("2020");
System.out.println(date2);
}
}
Выход:
Tue Dec 01 00:00:00 GMT 1970
Wed Jan 01 00:00:00 GMT 2020
Мне не нужно объяснять, какие значения по умолчанию они принимают. Вместо того, чтобы принимать такие неожиданные значения по умолчанию, они должны были поднять тревогу (сгенерировать какое-то исключение), на которую программисту было бы полезно среагировать.
Из-за таких неожиданностей рекомендуется полностью прекратить их использование и перейти на современный API даты и времени.
Примечание. По какой-либо причине, если вам нужно придерживаться Java 6 или Java 7, вы можете использовать ThreeTen-Backport, который переносит большую часть функций java.time на Java 6 и 7.
Если вы работаете над проектом Android и ваш уровень Android API по-прежнему не соответствует Java-8, проверьте API Java 8+, доступные через дешугаринг и Как использовать ThreeTenABP в Android Project.
Использование современного API даты и времени:
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
public class Main {
public static void main(String[] args) {
System.out.println(parse("DECEMBER", "MMMM"));
System.out.println(parse("2020", "uuuu"));
}
static LocalDate parse(String text, String pattern) {
try {
return LocalDate.parse(text, DateTimeFormatter.ofPattern(pattern));
} catch (DateTimeParseException e) {
System.out.println(e.getMessage());
// Return some default value
return LocalDate.MIN;
}
}
}
Выход:
Text 'DECEMBER' could not be parsed at index 0
-999999999-01-01
Text '2020' could not be parsed: Unable to obtain LocalDate from TemporalAccessor: {Year=2020},ISO of type java.time.format.Parsed
-999999999-01-01
Итак, теперь вы (программист) знаете, что вам нужно что-то сделать (например, использовать свои собственные значения по умолчанию) для разбора строк.
Демо:
import java.time.LocalDate;
import java.time.Month;
import java.time.Year;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder;
import java.time.format.DateTimeParseException;
import java.time.temporal.ChronoField;
import java.util.Locale;
public class Main {
public static void main(String[] args) {
LocalDate date = parse("DECEMBER", "MMMM");
Month month = parse("DECEMBER", "MMMM").getMonth();
System.out.println(date);
System.out.println(month);
date = parse("2020", "uuuu");
System.out.println(date);
int year = date.getYear();
System.out.println(year);
Year objYear = Year.of(year);
System.out.println(objYear);
}
static LocalDate parse(String text, String pattern) {
LocalDate today = LocalDate.now();
// Formatter using today's day, month and year as defaults
DateTimeFormatter formatter = new DateTimeFormatterBuilder()
.parseCaseInsensitive()
.appendPattern(pattern)
.parseDefaulting(ChronoField.DAY_OF_MONTH, today.getDayOfMonth())
.parseDefaulting(ChronoField.MONTH_OF_YEAR, today.getMonthValue())
.parseDefaulting(ChronoField.YEAR, today.getYear())
.toFormatter(Locale.ENGLISH);
try {
return LocalDate.parse(text, formatter);
} catch (DateTimeParseException e) {
System.out.println(e.getMessage());
// Return some default value
return LocalDate.MIN;
}
}
}
Выход:
2020-12-15
DECEMBER
2020-12-15
2020
2020
Если вы не хотите создавать объект даты или даты и времени, а хотите просто разобрать строку на Month и Year, вы можете сделать это следующим образом:
import java.time.Month;
import java.time.Year;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder;
import java.time.format.TextStyle;
import java.util.Locale;
public class Main {
public static void main(String[] args) {
Month month = new DateTimeFormatterBuilder()
.parseCaseInsensitive()
.appendPattern("MMMM")
.toFormatter(Locale.ENGLISH)
.parse("DECEMBER", Month::from);
System.out.println(month + " | " + month.getDisplayName(TextStyle.SHORT, Locale.ENGLISH) + " | "
+ month.getDisplayName(TextStyle.FULL, Locale.ENGLISH));
Year year = DateTimeFormatter.ofPattern("uuuu").parse("2020", Year::from);
System.out.println(year);
}
}
Выход:
DECEMBER | Dec | December
2020
Узнайте больше о современном API даты и времени на Trail: Date Time.
какой месяц/формат
MMMM?