在 java 中将 "mm/yy" 转换为 "yyyy-mm-dd"
Convert "mm/yy" to "yyyy-mm-dd" in java
我需要将 "11/17"
字符串日期(2017 年 11 月)转换为 "2017-11-01"
(2017 年 11 月 1 日)。
在 Java 中实现此目标的最佳方法是什么?
我试过了:
String dayMonthYear = "11/17";
dayMonthYear = "01/" + dayMonthYear;
DateTimeFormatter formatter = DateTimeFormat.forPattern("dd/MM/yy");
DateTime dt = formatter.parseDateTime(dayMonthYear);
dt.year().setCopy(dt.getYear() + 2000);
DateTimeFormatter dtfOut = DateTimeFormat.forPattern("yyyy-MM-dd");
dayMonthYear = dtfOut.print(dt);
System.out.println(dayMonthYear); // "2017-11-01";
并且:
SimpleDateFormat dateFormatTwoDigitsYear = new SimpleDateFormat(TWO_DIGITS_YEAR_DATE_FORMAT); //"dd/MM/yy"
SimpleDateFormat dateFormatFourDigitsYear = new SimpleDateFormat(FOUR_DIGITS_YEAR_DATE_FORMAT);// "yyyy-MM-dd"
Calendar calendar = Calendar.getInstance();
calendar.add(Calendar.YEAR, -100);//??? I AM NOT SURE WHY DO I NEEED THIS??
dateFormatTwoDigitsYear.set2DigitYearStart(calendar.getTime());
try
{
dayMonthYear = dateFormatFourDigitsYear.format(dateFormatTwoDigitsYear.parse(dayMonthYear));
}
catch (ParseException e)
{
log.error("Error while formatting date in yyyy-MM-dd format. Date is " + dayMonthYear);
}
我不确定为什么在第二种方法中需要这一行:
calendar.add(Calendar.YEAR, -100);
他们都在工作。但是不知道有没有更好的解决办法
您可以定义两种实用方法,一种将字符串转换为日期,另一种将其转换回字符串。
static Date stringToDate(String string) throws ParseException
{
DateFormat dateFormat = new SimpleDateFormat("MM/yyyy");
return dateFormat.parse(string);
}
static String dateToString(Date date)
{
DateFormat outputFormatter = new SimpleDateFormat("yyyy-MM-dd");
return outputFormatter.format(date);
}
static String formatString(String string)
{
return dateToString(stringToDate(string));
}
//Just call formatString() with your argument
如果您只想将第一种字符串类型转换为第二种类型,则可以组合它们,但我喜欢将它们分开,以防我需要来自字符串的日期对象或直接来自日期对象的字符串。
您不需要为年份添加值。 2 位数的值 (17) 会自动调整为 2017 年。此外,无需在输入中附加第 1 天。当日期不存在时,SimpleDateFormat
自动设置为 1:
// input format: MM/yy
SimpleDateFormat parser = new SimpleDateFormat("MM/yy");
// output format: yyyy-MM-dd
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
System.out.println(formatter.format(parser.parse("11/17"))); // 2017-11-01
PS: 如果你需要设置为另一天(1除外),你可以将日期设置为Calendar
并更改它格式化前:
// parse the date
Date date = parser.parse("11/17");
// set to a Calendar
Calendar cal = Calendar.getInstance();
cal.setTime(date);
// change to whatever day you want
cal.set(Calendar.DAY_OF_MONTH, whateverDayIwant);
// format it
System.out.println(formatter.format(cal.getTime()));
乔达时间
旧的 类(Date
、Calendar
和 SimpleDateFormat
)有 lots of problems and design issues,它们正在被新的 APIs.
我看到你在使用 Joda-Time,下面是如何使用这个 API。
在 Joda-Time 中,当您解析为 DateTime
时,它会为所有缺失的字段设置默认值(在本例中为天、小时、分钟等)。但是这个 API 还有很多其他类型最适合每个用例。
因为input只有年月,所以可以解析成org.joda.time.YearMonth
,然后把day设置为1,这样就生成了org.joda.time.LocalDate
,可以直接打印出来(如toString()
方法已经 returns 您想要的格式的日期):
DateTimeFormatter parser = DateTimeFormat.forPattern("MM/yy");
// parse to YearMonth
YearMonth ym = YearMonth.parse("11/17", parser);
// set day to 1
System.out.println(ym.toLocalDate(1)); // 2017-11-01
我更喜欢这种方法,因为您可以将其设置为您想要的任何一天,并且不需要创建一个完整的 DateTime
对象,其中包含您不 need/care 的字段(例如如小时、分钟等)。
如果你需要将这个值存储在一个String
中,只需调用toString()
方法:
// store "2017-11-01" in a String
String output = ym.toLocalDate(1).toString();
格式 yyyy-MM-dd
是 toString()
使用的默认格式。如果您需要不同的格式,可以将其传递给 toString()
:
// convert to another format (example: dd/MM/yyyy)
String output = ym.toLocalDate(1).toString("dd/MM/yyyy"); // 01/11/2017
或者您可以使用另一个 DateTimeFormatter
:
// convert to another format (example: dd/MM/yyyy)
DateTimeFormatter fmt = DateTimeFormat.forPattern("dd/MM/yyyy");
String output = fmt.print(ym.toLocalDate(1)); // 01/11/2017
PS: dt.year().setCopy
returns 一个 new 对象,正如你不t 将其分配给任何变量,此值将丢失 - 此方法不会更改原始 DateTime
对象,因此 dt
不会被其代码行更改。
Java新date/timeAPI
Joda-Time 处于维护模式,正在被新的 APIs 取代,所以我不建议用它开始一个新项目。即使在 joda's website 它说:"Note that Joda-Time is considered to be a largely “finished” project. No major enhancements are planned. If using Java SE 8, please migrate to java.time (JSR-310).".
如果您不能(或不想)从 Joda-Time 迁移到新的 API,您可以忽略此部分。
如果您正在使用 Java 8,请考虑使用 new java.time
API. It's easier, less bugged and less error-prone than the old APIs.
如果您使用 Java 6 或 7,您可以使用 ThreeTen Backport, a great backport for Java 8's new date/time classes. And for Android, you'll also need the ThreeTenABP (more on how to use it ).
下面的代码适用于两者。
唯一的区别是包名称(在 Java 8 中是 java.time
,在 ThreeTen Backport(或 Android 的 ThreeTenABP)中是 org.threeten.bp
),但是类 和方法 names 相同。
代码与 Joda-Time 非常相似(API 不完全相同,但 they have lots of similarities)。您可以使用 Java 8 的 java.time.format.DateTimeFormatter
并将输入解析为 java.time.YearMonth
(或者,在 Java 7 的 ThreeTen Backport 中,使用 org.threeten.bp.format.DateTimeFormatter
并解析为org.threeten.bp.YearMonth
):
DateTimeFormatter parser = DateTimeFormatter.ofPattern("MM/yy");
YearMonth ym = YearMonth.parse("11/17", parser);
System.out.println(ym.atDay(1)); // 2017-11-01
如果你需要将这个值存储在一个String
中,只需调用toString()
方法:
// store "2017-11-01" in a String
String output = ym.atDay(1).toString();
格式 yyyy-MM-dd
是 toString()
使用的默认格式。如果你需要不同的格式,你可以使用另一个 DateTimeFormatter
:
// convert to another format (example: dd/MM/yyyy)
DateTimeFormatter fmt = DateTimeFormatter.ofPattern("dd/MM/yyyy");
String output = fmt.format(ym.atDay(1)); // 01/11/2017
我需要将 "11/17"
字符串日期(2017 年 11 月)转换为 "2017-11-01"
(2017 年 11 月 1 日)。
在 Java 中实现此目标的最佳方法是什么?
我试过了:
String dayMonthYear = "11/17";
dayMonthYear = "01/" + dayMonthYear;
DateTimeFormatter formatter = DateTimeFormat.forPattern("dd/MM/yy");
DateTime dt = formatter.parseDateTime(dayMonthYear);
dt.year().setCopy(dt.getYear() + 2000);
DateTimeFormatter dtfOut = DateTimeFormat.forPattern("yyyy-MM-dd");
dayMonthYear = dtfOut.print(dt);
System.out.println(dayMonthYear); // "2017-11-01";
并且:
SimpleDateFormat dateFormatTwoDigitsYear = new SimpleDateFormat(TWO_DIGITS_YEAR_DATE_FORMAT); //"dd/MM/yy"
SimpleDateFormat dateFormatFourDigitsYear = new SimpleDateFormat(FOUR_DIGITS_YEAR_DATE_FORMAT);// "yyyy-MM-dd"
Calendar calendar = Calendar.getInstance();
calendar.add(Calendar.YEAR, -100);//??? I AM NOT SURE WHY DO I NEEED THIS??
dateFormatTwoDigitsYear.set2DigitYearStart(calendar.getTime());
try
{
dayMonthYear = dateFormatFourDigitsYear.format(dateFormatTwoDigitsYear.parse(dayMonthYear));
}
catch (ParseException e)
{
log.error("Error while formatting date in yyyy-MM-dd format. Date is " + dayMonthYear);
}
我不确定为什么在第二种方法中需要这一行:
calendar.add(Calendar.YEAR, -100);
他们都在工作。但是不知道有没有更好的解决办法
您可以定义两种实用方法,一种将字符串转换为日期,另一种将其转换回字符串。
static Date stringToDate(String string) throws ParseException
{
DateFormat dateFormat = new SimpleDateFormat("MM/yyyy");
return dateFormat.parse(string);
}
static String dateToString(Date date)
{
DateFormat outputFormatter = new SimpleDateFormat("yyyy-MM-dd");
return outputFormatter.format(date);
}
static String formatString(String string)
{
return dateToString(stringToDate(string));
}
//Just call formatString() with your argument
如果您只想将第一种字符串类型转换为第二种类型,则可以组合它们,但我喜欢将它们分开,以防我需要来自字符串的日期对象或直接来自日期对象的字符串。
您不需要为年份添加值。 2 位数的值 (17) 会自动调整为 2017 年。此外,无需在输入中附加第 1 天。当日期不存在时,SimpleDateFormat
自动设置为 1:
// input format: MM/yy
SimpleDateFormat parser = new SimpleDateFormat("MM/yy");
// output format: yyyy-MM-dd
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
System.out.println(formatter.format(parser.parse("11/17"))); // 2017-11-01
PS: 如果你需要设置为另一天(1除外),你可以将日期设置为Calendar
并更改它格式化前:
// parse the date
Date date = parser.parse("11/17");
// set to a Calendar
Calendar cal = Calendar.getInstance();
cal.setTime(date);
// change to whatever day you want
cal.set(Calendar.DAY_OF_MONTH, whateverDayIwant);
// format it
System.out.println(formatter.format(cal.getTime()));
乔达时间
旧的 类(Date
、Calendar
和 SimpleDateFormat
)有 lots of problems and design issues,它们正在被新的 APIs.
我看到你在使用 Joda-Time,下面是如何使用这个 API。
在 Joda-Time 中,当您解析为 DateTime
时,它会为所有缺失的字段设置默认值(在本例中为天、小时、分钟等)。但是这个 API 还有很多其他类型最适合每个用例。
因为input只有年月,所以可以解析成org.joda.time.YearMonth
,然后把day设置为1,这样就生成了org.joda.time.LocalDate
,可以直接打印出来(如toString()
方法已经 returns 您想要的格式的日期):
DateTimeFormatter parser = DateTimeFormat.forPattern("MM/yy");
// parse to YearMonth
YearMonth ym = YearMonth.parse("11/17", parser);
// set day to 1
System.out.println(ym.toLocalDate(1)); // 2017-11-01
我更喜欢这种方法,因为您可以将其设置为您想要的任何一天,并且不需要创建一个完整的 DateTime
对象,其中包含您不 need/care 的字段(例如如小时、分钟等)。
如果你需要将这个值存储在一个String
中,只需调用toString()
方法:
// store "2017-11-01" in a String
String output = ym.toLocalDate(1).toString();
格式 yyyy-MM-dd
是 toString()
使用的默认格式。如果您需要不同的格式,可以将其传递给 toString()
:
// convert to another format (example: dd/MM/yyyy)
String output = ym.toLocalDate(1).toString("dd/MM/yyyy"); // 01/11/2017
或者您可以使用另一个 DateTimeFormatter
:
// convert to another format (example: dd/MM/yyyy)
DateTimeFormatter fmt = DateTimeFormat.forPattern("dd/MM/yyyy");
String output = fmt.print(ym.toLocalDate(1)); // 01/11/2017
PS: dt.year().setCopy
returns 一个 new 对象,正如你不t 将其分配给任何变量,此值将丢失 - 此方法不会更改原始 DateTime
对象,因此 dt
不会被其代码行更改。
Java新date/timeAPI
Joda-Time 处于维护模式,正在被新的 APIs 取代,所以我不建议用它开始一个新项目。即使在 joda's website 它说:"Note that Joda-Time is considered to be a largely “finished” project. No major enhancements are planned. If using Java SE 8, please migrate to java.time (JSR-310).".
如果您不能(或不想)从 Joda-Time 迁移到新的 API,您可以忽略此部分。
如果您正在使用 Java 8,请考虑使用 new java.time
API. It's easier, less bugged and less error-prone than the old APIs.
如果您使用 Java 6 或 7,您可以使用 ThreeTen Backport, a great backport for Java 8's new date/time classes. And for Android, you'll also need the ThreeTenABP (more on how to use it
下面的代码适用于两者。
唯一的区别是包名称(在 Java 8 中是 java.time
,在 ThreeTen Backport(或 Android 的 ThreeTenABP)中是 org.threeten.bp
),但是类 和方法 names 相同。
代码与 Joda-Time 非常相似(API 不完全相同,但 they have lots of similarities)。您可以使用 Java 8 的 java.time.format.DateTimeFormatter
并将输入解析为 java.time.YearMonth
(或者,在 Java 7 的 ThreeTen Backport 中,使用 org.threeten.bp.format.DateTimeFormatter
并解析为org.threeten.bp.YearMonth
):
DateTimeFormatter parser = DateTimeFormatter.ofPattern("MM/yy");
YearMonth ym = YearMonth.parse("11/17", parser);
System.out.println(ym.atDay(1)); // 2017-11-01
如果你需要将这个值存储在一个String
中,只需调用toString()
方法:
// store "2017-11-01" in a String
String output = ym.atDay(1).toString();
格式 yyyy-MM-dd
是 toString()
使用的默认格式。如果你需要不同的格式,你可以使用另一个 DateTimeFormatter
:
// convert to another format (example: dd/MM/yyyy)
DateTimeFormatter fmt = DateTimeFormatter.ofPattern("dd/MM/yyyy");
String output = fmt.format(ym.atDay(1)); // 01/11/2017