如何使用 DateTimeFormatter 从 MONTH("MMMM") 或 YEAR("yyyy") 获取 Date 对象
How to get Date object from MONTH("MMMM") or YEAR("yyyy") using DateTimeFormatter
我刚开始使用 DateTimeFormatter 包,我们可以使用 SimpleDateFormat 获得同样的东西。
Date date = new SimpleDateFormat("MMMM").parse(month);//"DECEMBER"
Date date = new SimpleDateFormat("yyyy").parse(year);//"2020"
如何使用 DateTimeFormatter 实现此目的?
检查此 link 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
class,这里需要使用LocalDate
class。你不能只用month
或year
解析,你应该传递month
、day
和year
的3个值来获取Date.
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);
输出:
DECEMBER
年份比较简单。我们不需要格式化程序。
String yearString = "2020";
Year year = Year.parse(yearString);
System.out.println(year);
2020
old Date
class 尽管它的名字从未代表日期。这是一个时间点。然而,我们通常将它用于日期、一天中的某个时间、一个月、一年以及更多目的,有时也用于它所在的时间点。一个非常令人困惑的结果是,从您问题中的代码获得的 Date
对象在极少数情况下会错误地打印为 11 月而不是 12 月,以及 2019 年而不是 2020 年。您不应再使用 Date
class。它总是设计得很差,而且早就过时了。
另一方面java.time,DateTimeFormatter
所属的现代Java日期和时间API,定义class 代表每个这样的概念:LocalDate
代表日期,Month
代表一年中的一个月,Year
代表一年,等等。它使我们的代码更清楚我们的内容正在处理,这很好。它还需要我们了解不同的 classes 并考虑每次使用哪个。
如果您的月份字符串全部大写,我们需要告诉格式化程序在不考虑大小写的情况下进行解析:
String monthString = "DECEMBER";
DateTimeFormatter monthFormatter = new DateTimeFormatterBuilder()
.parseCaseInsensitive()
.appendPattern("MMMM")
.toFormatter(Locale.ENGLISH);
Month month = monthFormatter.parse(monthString, Month::from);
此外,当您的月份名称为英文时,请记住指定英语语言环境。
java.util
的日期时间 API 及其格式 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
我不需要解释他们采用的默认值。他们不应该采用这种意想不到的默认值,而应该发出警报(抛出一些异常),这将有助于程序员做出反应。
因为有这样的惊喜,建议完全停止使用,改用modern date-time API。
注:出于任何原因,如果你必须坚持Java6或Java7,你可以使用ThreeTen-Backport将大部分 java.time 功能移植到 Java 6 & 7.
如果您正在为 Android 项目工作,并且您的 Android API 水平仍然不符合 Java-8,请检查 Java 8+ APIs available through desugaring and 。
使用现代日期时间 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 的更多信息
我刚开始使用 DateTimeFormatter 包,我们可以使用 SimpleDateFormat 获得同样的东西。
Date date = new SimpleDateFormat("MMMM").parse(month);//"DECEMBER"
Date date = new SimpleDateFormat("yyyy").parse(year);//"2020"
如何使用 DateTimeFormatter 实现此目的?
检查此 link 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
class,这里需要使用LocalDate
class。你不能只用month
或year
解析,你应该传递month
、day
和year
的3个值来获取Date.
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);
输出:
DECEMBER
年份比较简单。我们不需要格式化程序。
String yearString = "2020";
Year year = Year.parse(yearString);
System.out.println(year);
2020
old Date
class 尽管它的名字从未代表日期。这是一个时间点。然而,我们通常将它用于日期、一天中的某个时间、一个月、一年以及更多目的,有时也用于它所在的时间点。一个非常令人困惑的结果是,从您问题中的代码获得的 Date
对象在极少数情况下会错误地打印为 11 月而不是 12 月,以及 2019 年而不是 2020 年。您不应再使用 Date
class。它总是设计得很差,而且早就过时了。
另一方面java.time,DateTimeFormatter
所属的现代Java日期和时间API,定义class 代表每个这样的概念:LocalDate
代表日期,Month
代表一年中的一个月,Year
代表一年,等等。它使我们的代码更清楚我们的内容正在处理,这很好。它还需要我们了解不同的 classes 并考虑每次使用哪个。
如果您的月份字符串全部大写,我们需要告诉格式化程序在不考虑大小写的情况下进行解析:
String monthString = "DECEMBER";
DateTimeFormatter monthFormatter = new DateTimeFormatterBuilder()
.parseCaseInsensitive()
.appendPattern("MMMM")
.toFormatter(Locale.ENGLISH);
Month month = monthFormatter.parse(monthString, Month::from);
此外,当您的月份名称为英文时,请记住指定英语语言环境。
java.util
的日期时间 API 及其格式 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
我不需要解释他们采用的默认值。他们不应该采用这种意想不到的默认值,而应该发出警报(抛出一些异常),这将有助于程序员做出反应。
因为有这样的惊喜,建议完全停止使用,改用modern date-time API。
注:出于任何原因,如果你必须坚持Java6或Java7,你可以使用ThreeTen-Backport将大部分 java.time 功能移植到 Java 6 & 7.
如果您正在为 Android 项目工作,并且您的 Android API 水平仍然不符合 Java-8,请检查 Java 8+ APIs available through desugaring and
使用现代日期时间 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 的更多信息