【问题标题】:How do I format an ISObasic date using DateFormat and LocalDate packages [duplicate]如何使用 DateFormat 和 LocalDate 包格式化 ISObasic 日期 [重复]
【发布时间】:2019-06-17 05:23:50
【问题描述】:

我正在寻找一种解决方案,可让我将包含 iso 基本日期格式(例如 20190330)的字符串转换为格式化日期,例如 2019-03-30(欧洲格式)或 30/03/2019(英国格式)或 @ 987654324@(美国格式)。格式取决于用户选择的格式。 java.time.LocalDate 和 java.time.format.DateTimeFormatter 库似乎提供了解决方案的可能性,但我发现这些库的文档不连贯且令人困惑,我不确定是否可以从这些来源获得解决方案。

我已经尝试了代码中显示的返回语句中包含的四种解决方案。

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;

public class DateFormatter {
  private static final String EU_PATTERN = "yyyy-MM-dd";
  private static final String UK_PATTERN= "dd/MM/yyyy";
  private static final String US_PATTERN= "MM/dd/yyyy";
  private static final int EU = 1;
  private static final int UK = 2;
  private static final int US = 3;

  private static String formattedDate(int fmt, String isobasic){
    String pattern = null;
    switch(fmt) {
      case EU: {pattern = EU_PATTERN; break;} 
      case UK: {pattern = UK_PATTERN; break;}
      case US: {pattern = US_PATTERN; break;}
    }
    DateTimeFormatter dateFormatter =     DateTimeFormatter.ofPattern(pattern);
        //    return dateFormatter.format(isobasic); // String cannot be         converted to Temporal Accessor
//    return (String)dateFormatter.format(isobasic); // String cannot be     converted to Temporal Accessor
//    return LocalDate.parse(isobasic, dateFormatter); // LocalDate     cannot be converted to String
      return (String)LocalDate.parse(isobasic, dateFormatter); //     LocalDate cannot be converted to String
  }

  /**
   * @param args the command line arguments
   */
  public static void main(String[] args) {
    System.out.println(formattedDate(EU, "20180927"));
    System.out.println(formattedDate(UK, "20190131"));
    System.out.println(formattedDate(US,  "20171225"));
  }

根据所选格式,预期结果将是三个格式化日期: 2018-09-27 2019 年 1 月 31 日 2017 年 12 月 25 日 实际结果是case语句后面的返回码后面显示的语法错误。

我的解决方法是重写 case 语句并使用如下笨拙的语句(对于 EU 格式):

case EU: { return isobasic.substring(0,4) + "-" + isobasic.substring(4,6) +     "-" + isobasic.substring(6,8);}

如果这是我将接受的唯一解决方案,但我想首先查看 formatter/localdate 库中的哪一个提供了更优雅的方法。

【问题讨论】:

  • 最好单独发布您获得的异常。也不要只是将结果转换为 (String),调用 .toString(foo) 或 String.valueOf(foo) 因为你不确定它实际上是一个 String
  • 您尝试从字符串中获取字符串,因此您首先必须使用正确的格式(“yyyyMMdd”)解析您的输入,然后使用您的模式之一格式化结果。
  • 从一种字符串格式转换为另一种字符串格式通常需要两 (2) 个格式化程序,一个指定源格式(用于解析),一个用于指定所需格式(用于格式化)。
  • 我知道很多链接原始问题的答案都使用了麻烦且过时的SimpleDateFormat类。不要那样做。像您自己一样使用 java.time 寻找答案。使用起来要好得多(尽管您似乎遇到了初学者的麻烦)。
  • 补充建议:考虑DateTimeFormatter.ofLocalizedDate 为每个国家(和语言)提供适当的日期格式。如果您确实只想处理欧洲、英国和美国,请对这三个使用 enum 而不是 int 常量。还有一个 EnumMap 用于保存您的格式模式字符串。

标签: java localdate dateformatter


【解决方案1】:

按照我的评论,您应该尝试使用您的 iso 格式从您的字符串中获取一个 TemporalAccessor,然后将其格式化为所需的模式。

我只是对你的代码做了一些小改动就达到了效果,你可以试试

public class DateFormatter {
    private static final String ISO = "yyyyMMdd";
    private static final String EU_PATTERN = "yyyy-MM-dd";
    private static final String UK_PATTERN = "dd/MM/yyyy";
    private static final String US_PATTERN = "MM/dd/yyyy";
    private static final int EU = 1;
    private static final int UK = 2;
    private static final int US = 3;

    private static String formattedDate(int fmt, String isobasic) {
        String pattern = null;
        switch (fmt) {
            case EU: {
                pattern = EU_PATTERN;
                break;
            }
            case UK: {
                pattern = UK_PATTERN;
                break;
            }
            case US: {
                pattern = US_PATTERN;
                break;
            }
        }
        DateTimeFormatter parser = DateTimeFormatter.ofPattern(ISO);
        TemporalAccessor parsedDate = parser.parse(isobasic);
        return DateTimeFormatter.ofPattern(pattern).format(parsedDate);
    }

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        System.out.println(formattedDate(EU, "20180927"));
        System.out.println(formattedDate(UK, "20190131"));
        System.out.println(formattedDate(US, "20171225"));
    }
}

【讨论】:

  • 非常感谢您指向 TemporalAssessor 类,它提供了我正在寻找的解决方案。此类的使用通常不会在示例和教程中描述,因此您的解决方案会提供有价值的附加信息。
  • 还有其他库可以在没有 TemporalAccessor 的情况下实现相同的结果,但是当您要将日期从字符串转换为另一种格式的字符串时,它们中的大多数的行为相同,您首先必须解析它并指定一个模式然后用目标模式格式化结果。如果您的问题已通过我的回答解决,您能否将其标记为已接受,以便有相同问题的人可以更轻松地找到回复,如果未解决,请随时添加有关不工作的信息。
  • 我真的认为没有理由使用TemporalAccessor 而不是LocalDate。我宁愿推荐后者。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-10-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多