【问题标题】:Date object from DAY, MONTH, YEAR来自 DAY、MONTH、YEAR 的日期对象
【发布时间】:2021-01-15 07:15:51
【问题描述】:

我正在尝试创建一个将 DAY、MONTH、YEAR 转换为 Java 中的 Date 对象的方法

我有

String DAY = "31"
String YEAR = "2012"
String MONTH = "11"

我需要一个可配置的格式作为输出。

String format = "MM/dd/yyy";

我总是只会得到从“01”到“31”的DAY字符串
我将始终只获得从“1000”到“9999”的 YEAR 字符串
我总是只会得到从“01”到“12”的MONTH字符串(永远不会得到一月、二月等)

我知道 SimpleDateFormat(format) 可以在一定程度上发挥作用。

new SimpleDateFormat("MM/dd/yyyy") 会将“02/01/2010”解析为 2010 年 2 月 1 日,但是
new SimpleDateFormat("mm/dd/yyyy") 将“02/01/2010”解析为 Jan 01 2010

是否可以在 java 中编写一个通用方法,根据可配置的模式将给定的字符串(DAY、MONTH、YEAR)转换为 Date 对象?哪个可以抛出异常是我提供了错误的 DAY、MONTH、YEAR 组合(如 DAY = "31"、MONTH = "02"、YEAR = "2010")

类似:

Date dateParser(String format){
  
  String DAY = "01";
  String YEAR = "1922";
  String MONTH = "02";
  
  
  return date;
}

【问题讨论】:

  • SimpleDateFormat 将满足您的需求。 mm/dd/yyyy 不起作用,因为小写的 mm 是几分钟而不是几个月。
  • @GriffeyDog - 请不要建议任何人使用过时的 API。您会发现数百个关于人们使用 java.util 日期时间 API 和 SimpleDateFormat 获得的不良结果的问题。
  • 我建议您既不要使用Date,也不要使用SimpleDateFormat。这些类设计不佳且过时,尤其是后者出了名的麻烦。而是使用来自java.time, the modern Java date and time API 的LocalDate 和DateTimeFormatter。
  • 仅供参考:不要再使用Date。它已经过时,有几个问题,不再推荐使用。请改用LocalDateTime API(其中还包括ZonedDateTime、LocalDate 和LocalTime)。
  • @ArvindKumarAvinash 我并不是建议 OP 应该使用过时的 Date API,只是回答所提出的问题,即 OP 似乎正在使用该 API。

标签: java date java-8 datetime-format simpledateformat


【解决方案1】:

基本上有两种方式:

  1. 将每个字符串解析为一个数字,并将这些数字组合成一个日期。
  2. 将字符串组合成一个字符串,然后解析成日期。

有些中间形式是可以想象的,但我建议你采取纯粹的立场,只使用其中一种方式。 Arvind Kumar Avinash 的答案显示了选项 1。我更喜欢选项 2。所以让我来演示一下。

我建议您使用 java.time,这是现代 Java 日期和时间 API 来处理日期工作。

    String format = "MM/dd/yyy";
    
    String day = "31";
    String year = "2012";
    String month = "11";
    
    DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern(format, Locale.US);
    
    String isoDateString = year + '-' + month + '-' + day;
    LocalDate date = LocalDate.parse(isoDateString);
    
    String formattedDate = date.format(dateFormatter);
    System.out.println(formattedDate);

由于 11 月(第 11 个月)只有 30 天,这段代码非常明智地抛出了异常:

线程“主”java.time.format.DateTimeParseException 中的异常: 无法解析文本“2012-11-31”:无效日期“NOVEMBER 31”

也就是说,我们有免费的输入验证。对于有效日期,代码将按要求解析日期和格式。

链接

Oracle tutorial: Date Time 解释如何使用 java.time。

【讨论】:

    【解决方案2】:

    我建议您从过时且容易出错的 java.util 日期时间 API 和 SimpleDateFormat 切换到 modern java.time 日期时间 API 和相应的格式化 API(包,java.time.format)。从 Trail: Date Time 了解有关现代日期时间 API 的更多信息。

    注意mm 用于minute;不适用于month。对于month,您使用MM。更多信息请查看this。

    使用现代日期时间 API:

    import java.time.LocalDate;
    
    public class Main {
        public static void main(String[] args) {
            // Test
            System.out.println(getLocalDate("2010", "02", "28"));
            System.out.println(getLocalDate("2010", "02", "31"));
        }
    
        static LocalDate getLocalDate(String year, String month, String dayOfMonth) {
            return LocalDate.of(Integer.parseInt(year), Integer.parseInt(month), Integer.parseInt(dayOfMonth));
        }
    }
    

    输出:

    2010-02-28
    Exception in thread "main" java.time.DateTimeException: Invalid date 'FEBRUARY 31'
        at java.base/java.time.LocalDate.create(LocalDate.java:459)
        at java.base/java.time.LocalDate.of(LocalDate.java:271)
        at Main.getLocalDate(Main.java:11)
        at Main.main(Main.java:7)
    

    请注意,日期时间对象应该存储有关日期、时间、时区等的信息,而不是有关格式的信息。当您打印日期时间类型的对象时,它应该打印其toString 方法返回的内容。如果您需要以不同的格式打印日期时间,则需要一个格式化类(例如DateTimeFormatter),它可以以您想要的模式返回一个字符串,例如

    import java.time.LocalDate;
    import java.time.format.DateTimeFormatter;
    
    public class Main {
        public static void main(String[] args) {
            // Test
            System.out.println(getFormattedLocalDate("2010/02/28", "yyyy/MM/dd", "EEEE dd MMMM yyyy"));
            System.out.println(getFormattedLocalDate("28/02/2010", "dd/MM/yyyy", "yyyy MMM EEE dd"));
        }
    
        static String getFormattedLocalDate(String date, String inputPattern, String outputPattern) {
            return LocalDate.parse(date, DateTimeFormatter.ofPattern(inputPattern))
                    .format(DateTimeFormatter.ofPattern(outputPattern));
        }
    }
    

    输出:

    Sunday 28 February 2010
    2010 Feb Sun 28
    

    【讨论】:

      猜你喜欢
      • 2012-03-17
      • 1970-01-01
      • 1970-01-01
      • 2021-12-12
      • 1970-01-01
      • 2022-06-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多