DateTimerFormatter在Java中是一个日期时间格式化类。

huangapple go评论82阅读模式
英文:

DateTimerFormatter in Java

问题

以下是您要求的翻译内容:

我正在以这种格式从用户那里获取输入:“Tue,12 May”,并且我想将格式更改为:“Tue_12_May”。

输入格式可以有3/4个字母的月份,例如:MayJulyFeb等。月份的输出格式不重要。

到目前为止,我尝试了以下代码片段:

public static String dateFormatter(String dateWithSpace) {
    DateTimeFormatter formatter1 = new DateTimeFormatterBuilder().parseCaseInsensitive().appendPattern("EEE, dd LLL").toFormatter(Locale.ENGLISH);
    DateTimeFormatter formatter2 = DateTimeFormatter.ofPattern("E_d_M/L");
    LocalDate date = LocalDate.parse(dateWithSpace.trim(), formatter1);
    return date.format(formatter2);
}

我一直得到这个错误:

java.time.format.DateTimeParseException: Text 'Tue, 12 May' could not be parsed at index 8

英文:

I am getting input from user in this format "Tue, 12 May" and I would like to change the format into this: "Tue_12_May".

The input format can have 3/4 letters for month, for example: May or July or Feb etc. Output format for month doesn't matter.

So far I have tried the following code snippet:

public static String dateFormatter(String dateWithSpace) {
    DateTimeFormatter formatter1 = new DateTimeFormatterBuilder().parseCaseInsensitive().appendPattern("EEE, dd LLL").toFormatter(Locale.ENGLISH);
    DateTimeFormatter formatter2 = DateTimeFormatter.ofPattern("E_d_M/L");
    LocalDate date = LocalDate.parse(dateWithSpace.trim(), formatter1);
    return date.format(formatter2);
}

I keep getting this error:

> java.time.format.DateTimeParseException: Text 'Tue, 12 May' could not
> be parsed at index 8

答案1

得分: 3

骇客

String dateWithSpace = "Tue, 12 May";
DateTimeFormatter formatter1 = new DateTimeFormatterBuilder()
        .parseCaseInsensitive()
        .appendPattern("EEE, d [MMMM][MMM]")
        .toFormatter(Locale.ENGLISH);
DateTimeFormatter formatter2 = DateTimeFormatter.ofPattern("E_d_MMMM", Locale.ENGLISH);
TemporalAccessor parsed = formatter1.parse(dateWithSpace.trim());
String formatted = formatter2.format(parsed);

System.out.println(formatted);

输出:

> Tue_12_May

在这里的挑战是我们不能仅仅使用LocalDate来表示“Tuesday 12th May”。对于LocalDate,我们需要年份。我们不能随意选择某一年,因为这两个原因:(1) 无论我们决定什么年份,都可能是错误的,从而在我们的程序中引入错误,即使错误一开始不会表现出来;(2) 如果我们没有运气选择5月12日恰好是星期二的年份,LocalDate会抱怨错误的星期几。即使我们以某种方式强制进行,它也不会打印回Tue,而是打印我们选择年份的正确星期几。也没有任何其他类型同时在没有年份的情况下保存星期几、月份和日期。

较好的解决方案是找出哪一年是正确的。也许尝试今年和明年,如果都不匹配则抛出异常?

同时,我的方法是不决定任何具体的类型,而是只使用未决定的TemporalAccessor接口。

编辑: 为了在完整的情况下接受短月份名称(JuneJuly以及May)和较长月份名称的三个字母缩写(例如,FebDec),我使用了[MMMM][MMM]:可选的完整月份名称,后跟可选的月份缩写。所以其中一个将始终匹配,另一个将被忽略。

其他示例的输入和输出:

Wed, 1 July  -> Wed_1_July
Thu, 27 Aug  -> Thu_27_August
Mon, 8 Feb   -> Mon_8_February

关于你的代码

我有一些评论,大多数是次要的:

  • 对于你的示例字符串,你应该不需要使用parseCaseInsensitive()(也许对于你可能得到的其他字符串有用,我无法知道)。
  • 编辑: 要接受一位数字的日期,请在解析的格式模式字符串中只使用一个d。它仍然也会接受两位数字的日期。进一步决定输出中是否始终使用两位数字,或者只在每月的前9天使用一位数字。
  • 解析的格式模式中,最好使用MMM代替LLLLLL用于月份不是日期的一部分时(在某些语言中,这会影响要使用的月份名称的形式)。
  • 在格式化中也使用MMM作为月份缩写,而不是M/L
  • 在格式化中也提供一个地区(locale)。
英文:

The hack

	String dateWithSpace = "Tue, 12 May";
    DateTimeFormatter formatter1 = new DateTimeFormatterBuilder()
            .parseCaseInsensitive()
            .appendPattern("EEE, d [MMMM][MMM]")
            .toFormatter(Locale.ENGLISH);
    DateTimeFormatter formatter2 = DateTimeFormatter.ofPattern("E_d_MMMM", Locale.ENGLISH);
    TemporalAccessor parsed = formatter1.parse(dateWithSpace .trim());
    String formatted = formatter2.format(parsed);

    System.out.println(formatted);

Output:

> Tue_12_May

The challenge here is that we cannot represent “Tuesday 12th May” in a LocalDate. For a LocalDate we need a year. We cannot just decide on some fixed year for two reasons: (1) Whatever we decide would probably be wrong and hence introduce an error in our program, also when the error would not surface initially; (2) LocalDate would object to the incorrect day of week if we didn’t have the luck to pick a year where May 12 falls on a Tuesday. And even if we forced it somehow, it would not print Tue back, but the correct day of week for the year we had picked. There isn’t any other type that holds a day of week, day of month and month without a year either.

The good solution would be to find out which year is correct. Maybe try this year and next year in turn and throw an exception if neither matches?

In the meantime my hack is not to decide on any concrete type but just use the undecided TemporalAccessor interface.

EDIT: To accept short month names in full (June, July and also May) and three letter abbreviations for longer month names (e.g., Feb, Dec), I am using [MMMM][MMM]: optional full month name followed by optional month abbreviation. So one of them will always match and the other be ignored.

Other examples of input and output:

Wed, 1 July  -> Wed_1_July
Thu, 27 Aug  -> Thu_27_August
Mon, 8 Feb   -> Mon_8_February

On your code

I have some comments, most of them minor:

  • You shouldn’t need parseCaseInsensitive() for your example string (maybe for other strings you might be getting, I cannot know).
  • EDIT: To accept one digit day of month put just one d in the format pattern string for parsing. It will still accept two digits too. Further decide whether you want two digits in the output always or only one digit for the first 9 days of the month.
  • Prefer MMM over LLL in the format pattern for parsing. LLL is for when the month is not part of a date (in some languages that makes a difference as to what form of the month name to use).
  • For formatting too use MMM for month abbreviation, not M/L.
  • Provide a locale for formatting too.

答案2

得分: 0

你可以简单地按照以下方式完成:

public static String dateFormatter(String dateWithSpace) {
    DateTimeFormatter formatter1 = new DateTimeFormatterBuilder()
                    .appendOptional(DateTimeFormatter.ofPattern("E, d LLLL"))
                    .appendOptional(DateTimeFormatter.ofPattern("E, d LLL"))
                    .toFormatter();
    DateTimeFormatter formatter2 = DateTimeFormatter.ofPattern("E_d_LLL");
    return formatter2.format(formatter1.parse(dateWithSpace));
}

在你的情况下,问题在于你正在使用 LocalDate,但缺少了 LocalDate 的一个重要参数,即年份。你可以参考 LocalDate文档

LocalDate 是一个表示日期的不可变日期时间对象,通常被视为年-月-日。其他日期字段,如年份中的天数、星期几和年份中的周数,也可以被访问。例如,值 "2007年10月2日" 可以被存储在一个 LocalDate 中。

英文:

You could do it simply in this way:

public static String dateFormatter(String dateWithSpace) {
    DateTimeFormatter formatter1 = new DateTimeFormatterBuilder()
                    .appendOptional(DateTimeFormatter.ofPattern("E, d LLLL"))
                    .appendOptional(DateTimeFormatter.ofPattern("E, d LLL"))
                    .toFormatter();
    DateTimeFormatter formatter2 = DateTimeFormatter.ofPattern("E_d_LLL");
    return formatter2.format(formatter1.parse(dateWithSpace));
}

In your case the problem is that you are using LocalDate, but missing one important parameter of LocalDate, i.e. year. You can refer to the LocalDate Documentation:

> LocalDate is an immutable date-time object that represents a date,
> often viewed as year-month-day. Other date fields, such as
> day-of-year, day-of-week and week-of-year, can also be accessed. For
> example, the value "2nd October 2007" can be stored in a LocalDate.

huangapple
  • 本文由 发表于 2020年5月3日 18:47:21
  • 转载请务必保留本文链接:https://go.coder-hub.com/61573177.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定