【问题标题】:how to convert String to java.sql.Date?如何将字符串转换为 java.sql.Date?
【发布时间】:2021-04-29 09:03:47
【问题描述】:

我需要将格式为“jan 25,2021”的字符串转换为格式为“2021-01-25”的 java.sql.date。 我尝试使用此代码:

String date = "jan 25,2021";
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
java.sql.Date booking_date=null;
try{
java.util.Date util_date = format.parse(date);
booking_date = new Date(util_date.getTime());
}
catch(ParseException e){
            System.out.println(e);
        }

但总是抛出 ParseException。 哪里错了?

【问题讨论】:

标签: java date jdbc


【解决方案1】:

您提供的格式不像您的格式化程序期望的文本那样采用年-月-日的形式(即“2021-01-25),因此请改用:

SimpleDateFormat format = new SimpleDateFormat("MMM dd,yyyy");

您将能够以您的格式正确解析日期。 否则更改参数本身以匹配预期的模式(即传递“2021-01-25”作为字符串)。

编辑:这里严格指手头的代码和格式不匹配。查看其他更完整的答案,了解如何使用更新(更好)的 API 来解决与旧时间相关的库的问题。

【讨论】:

  • 不是一个坏主意,但带有MMM 的格式取决于区域设置。 OP 需要确保应用程序或服务器级别的区域设置正确(国家/地区/方言)。如果 DevOps 更改服务器区域设置,整个应用程序可能会停止工作。
  • SDF = 大部分损坏,并且缺少区域设置。
【解决方案2】:

我需要将格式为“jan 25,2021”的字符串转换为 java.sql.date 格式为“2021-01-25”。

日期时间对象应该存储有关日期、时间、时区等的信息,而不是格式。您可以使用日期时间格式化 API 使用您选择的模式将日期时间对象格式化为 String

  • 现代日期时间类型的日期时间格式化 API 在包中,java.time.format 例如java.time.format.DateTimeFormatterjava.time.format.DateTimeFormatterBuilder
  • 旧日期时间类型的日期时间格式化 API 在包中,java.text 例如java.text.SimpleDateFormatjava.text.DateFormat

切换到现代日期时间 API

java.util 的日期时间 API 及其格式化 API SimpleDateFormat 已过时且容易出错。 java.sql.Date 扩展了 java.util.Date 并因此继承了相同的问题。建议完全停止使用,转用modern date-time API

使用现代日期时间 API:

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder;
import java.util.Locale;

public class Main {
    public static void main(String[] args) {
        String strDate = "jan 25,2021";
        DateTimeFormatter dtf = new DateTimeFormatterBuilder()
                                    .parseCaseInsensitive() //For case-insensitive parsing
                                    .appendPattern("MMM d,uuuu")
                                    .toFormatter(Locale.ENGLISH);

        LocalDate date = LocalDate.parse(strDate, dtf);
        System.out.println(date);
    }
}

输出:

2021-01-25

一旦解析成LocalDate,就可以在JDBC 4.2以后使用它,如下(假设列类型为DATE):

LocalDate localDate = LocalDate.now();
PreparedStatement st = conn.prepareStatement("INSERT INTO mytable (columnfoo) VALUES (?)");
st.setObject(1, localDate);
st.executeUpdate();
st.close();

Trail: Date Time 了解现代日期时间 API。

【讨论】:

    【解决方案3】:

    我需要将格式为“jan 25,2021”的字符串转换为格式为“2021-01-25”的 java.sql.date。我尝试使用此代码:

    这就像问:“我如何将绘画转换为音频文件”——这两个概念是不相关的。它们听起来相关(2021 年 1 月 25 日是一个日期,而且,java.sql.Date,它就在名称中,不是吗),但它们不是:java.sql.Date 是一个用词不当 - 它根本不代表日期;它代表了一个瞬间。哪个不是日期:如果我拍手问全世界的每个人我这样做的日期是什么时候,你会得到至少 2 个不同的答案,从而证明这 2 个不一样。

    正确的解决方案是使用不会出现此类错误的较新 API:

    DateTimeFormatter FORMAT = DateTimeFormatter.ofPattern("MMM dd,uuuu", Locale.ENGLISH);
    LocalDate ld = LocalDate.parse("jan 25,2021", FORMAT);
    

    我希望.setObject(x, someLocalDate) 可以用作日期值,但如果不是(而且它可能不是——众所周知,mysql 很糟糕,而且它的 JDBC 驱动程序也很可疑),至少要从正确的表示形式转换(LocalDate) 到损坏的 (java.sql.Date) 尽可能晚 - 不要让那个错误感染你的 java 代码。反之亦然:检索日期时,使用.getObject(idx, LocalDate.class),如果不起作用,请立即从损坏的java.sql.Date 转换为正确的java.time.LocalDate,尽可能防止该错误感染您的java 代码。

    【讨论】:

    • 一个包含很多好信息的答案。详细说明: (1) 月份名称以英文大写字母开头。要接受带有小写 jjan,我们需要一个 DateTimeFormatterBuilder 及其 parseCaseInsensitive 方法。 (2) 不清楚是否也需要接受带有 1 位数日期的 feb 5。如果是,请在格式模式字符串中仅使用一个d。它仍然会接受两位数的25
    猜你喜欢
    • 2014-05-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-16
    • 2021-10-06
    • 2011-08-29
    相关资源
    最近更新 更多