如果未指定为模式的一部分,则DateFormat将解析为当前年/月/日

时间:2022-08-25 10:22:49

Probably I am trying to achieve something which is not available out of the box from SimpleDateFormat and a limitation as to where the year/month/date are defaulted to 1970/Jan/01, if yy/mm/dd are not defined in the pattern.

可能我试图实现SimpleDateFormat开箱即用的东西以及年/月/日默认为1970 / Jan / 01的限制,如果yy / mm / dd未在模式中定义。

Example:

String pattern = "hh:mm:ss";
SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern);
Date date = simpleDateFormat.parse("08:05:05");
System.out.println(date);

The result is: Thu Jan 01 08:05:05 IST 1970

结果是:Thu Jan 01 08:05:05 IST 1970

I have a scenario where I could receive any custom pattern to my API and should be able to parse to current date/month/day if corresponding format symbols are missing in the pattern (missing y or m or d)

我有一个场景,我可以接收我的API的任何自定义模式,如果模式中缺少相应的格式符号(缺少y或m或d),我应该能够解析到当前日期/月/日

Desired result for the above example (today is 4 June 2018): Mon Jun 04 08:05:05 IST 2018

上述例子的预期结果(今天是2018年6月4日):Mon Jun 04 08:05:05 IST 2018

Could anyone help me as to how could I achieve the behavior?

任何人都可以帮助我,我怎么能实现这种行为?

1 个解决方案

#1


1  

java.time

public static void parseCustomFormat(String formatPattern, String dateTimeString) {
    LocalDate today = LocalDate.now(ZoneId.of("Asia/Kolkata"));
    DateTimeFormatter formatter = new DateTimeFormatterBuilder()
            .appendPattern(formatPattern)
            .parseDefaulting(ChronoField.YEAR_OF_ERA, today.getYear())
            .parseDefaulting(ChronoField.MONTH_OF_YEAR, today.getMonthValue())
            .parseDefaulting(ChronoField.DAY_OF_MONTH, today.getDayOfMonth())
            .toFormatter(Locale.ENGLISH);
    LocalDateTime parsedDateTime = LocalDateTime.parse(dateTimeString, formatter);
    System.out.format(Locale.ENGLISH, "%-19s -> %s%n",  dateTimeString, parsedDateTime);
}

The above method will basically use day, month and/or year from the string if the pattern says it should, and use the corresponding values form today’s date if not. For example:

如果模式表明它应该使用上述方法基本上使用字符串中的日,月和/或年,如果不是,则使用相应的值形成今天的日期。例如:

    parseCustomFormat("HH:mm:ss", "08:05:05");
    parseCustomFormat("yyyy-MM-dd'T'HH:mm:ss", "2015-11-23T21:41:45");
    parseCustomFormat("MM H:mm", "10 20:58");
    parseCustomFormat("yy d H:mm", "34 29 9:30");

When I ran this code today, the output was:

当我今天运行此代码时,输​​出为:

08:05:05            -> 2018-06-04T08:05:05
2015-11-23T21:41:45 -> 2015-11-23T21:41:45
10 20:58            -> 2018-10-04T20:58
34 29 9:30          -> 2034-06-29T09:30

Parsing will be apt to fail if the pattern contains a week year and/or week number, u for year or a day of week. It will be sure to fail if it contains hour within AM or PM (lowercase h as in the example in the question) and no AM/PM marker.

如果模式包含一年和/或一周的数字,u表示年份或一周的某一天,则解析将容易失败。如果它包含AM或PM内的小时(如问题中的示例中的小写h)并且没有AM / PM标记,则肯定会失败。

We have a legacy code which we have to support from Java1.6+

我们有一个遗留代码,我们必须从Java1.6 +支持

No big problem. I have run the above code on Java 7 with ThreeTen backport, the backport of java.time to Java 6 and 7 (see the link at the bottom), so it should work on Java 6 too. If you need a java.util.Date for your legacy code (and don’t want to upgrade it to java.time just now), convert like this:

没什么大问题。我已经在Java 7上使用ThreeTen backport运行上面的代码,java.time的后端到Java 6和7(参见底部的链接),所以它也适用于Java 6。如果你的旧代码需要一个java.util.Date(并且现在不想将它升级到java.time),请像这样转换:

    Instant inst = parsedDateTime.atZone(ZoneId.systemDefault()).toInstant();
    Date oldfashionedDate = DateTimeUtils.toDate(inst);
    System.out.format(Locale.ENGLISH, "%-19s -> %s%n",  dateTimeString, oldfashionedDate);

With this change to the above code the output on my computer was:

通过对上述代码的更改,我计算机上的输出为:

08:05:05            -> Mon Jun 04 08:05:05 CEST 2018
2015-11-23T21:41:45 -> Mon Nov 23 21:41:45 CET 2015
10 20:58            -> Thu Oct 04 20:58:00 CEST 2018
34 29 9:30          -> Thu Jun 29 09:30:00 CEST 2034

Links

#1


1  

java.time

public static void parseCustomFormat(String formatPattern, String dateTimeString) {
    LocalDate today = LocalDate.now(ZoneId.of("Asia/Kolkata"));
    DateTimeFormatter formatter = new DateTimeFormatterBuilder()
            .appendPattern(formatPattern)
            .parseDefaulting(ChronoField.YEAR_OF_ERA, today.getYear())
            .parseDefaulting(ChronoField.MONTH_OF_YEAR, today.getMonthValue())
            .parseDefaulting(ChronoField.DAY_OF_MONTH, today.getDayOfMonth())
            .toFormatter(Locale.ENGLISH);
    LocalDateTime parsedDateTime = LocalDateTime.parse(dateTimeString, formatter);
    System.out.format(Locale.ENGLISH, "%-19s -> %s%n",  dateTimeString, parsedDateTime);
}

The above method will basically use day, month and/or year from the string if the pattern says it should, and use the corresponding values form today’s date if not. For example:

如果模式表明它应该使用上述方法基本上使用字符串中的日,月和/或年,如果不是,则使用相应的值形成今天的日期。例如:

    parseCustomFormat("HH:mm:ss", "08:05:05");
    parseCustomFormat("yyyy-MM-dd'T'HH:mm:ss", "2015-11-23T21:41:45");
    parseCustomFormat("MM H:mm", "10 20:58");
    parseCustomFormat("yy d H:mm", "34 29 9:30");

When I ran this code today, the output was:

当我今天运行此代码时,输​​出为:

08:05:05            -> 2018-06-04T08:05:05
2015-11-23T21:41:45 -> 2015-11-23T21:41:45
10 20:58            -> 2018-10-04T20:58
34 29 9:30          -> 2034-06-29T09:30

Parsing will be apt to fail if the pattern contains a week year and/or week number, u for year or a day of week. It will be sure to fail if it contains hour within AM or PM (lowercase h as in the example in the question) and no AM/PM marker.

如果模式包含一年和/或一周的数字,u表示年份或一周的某一天,则解析将容易失败。如果它包含AM或PM内的小时(如问题中的示例中的小写h)并且没有AM / PM标记,则肯定会失败。

We have a legacy code which we have to support from Java1.6+

我们有一个遗留代码,我们必须从Java1.6 +支持

No big problem. I have run the above code on Java 7 with ThreeTen backport, the backport of java.time to Java 6 and 7 (see the link at the bottom), so it should work on Java 6 too. If you need a java.util.Date for your legacy code (and don’t want to upgrade it to java.time just now), convert like this:

没什么大问题。我已经在Java 7上使用ThreeTen backport运行上面的代码,java.time的后端到Java 6和7(参见底部的链接),所以它也适用于Java 6。如果你的旧代码需要一个java.util.Date(并且现在不想将它升级到java.time),请像这样转换:

    Instant inst = parsedDateTime.atZone(ZoneId.systemDefault()).toInstant();
    Date oldfashionedDate = DateTimeUtils.toDate(inst);
    System.out.format(Locale.ENGLISH, "%-19s -> %s%n",  dateTimeString, oldfashionedDate);

With this change to the above code the output on my computer was:

通过对上述代码的更改,我计算机上的输出为:

08:05:05            -> Mon Jun 04 08:05:05 CEST 2018
2015-11-23T21:41:45 -> Mon Nov 23 21:41:45 CET 2015
10 20:58            -> Thu Oct 04 20:58:00 CEST 2018
34 29 9:30          -> Thu Jun 29 09:30:00 CEST 2034

Links