【问题标题】:How can I retrieve date from database and convert to Calendar?如何从数据库中检索日期并转换为日历?
【发布时间】:2026-02-13 21:35:01
【问题描述】:

我正在使用 Java Swing 和 MySQL 在 Eclipse 中编写代码。我在数据库中使用日历存储出生日期。

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
String DOB=sdf.format(db1.getDate());

如果用户想要更新,我想从数据库中检索日期并显示在 GUI 中以进行更新。

我该怎么做?

String idpop = JOptionPane.showInputDialog(null , "Enter Student ID to update record:");
int sid=Integer.parseInt(idpop);

Class.forName("com.mysql.jdbc.Driver");
Connection con=DriverManager.getConnection("jdbc:mysql://localhost:3306/schl","root","root");

String sql = "select * from stud_info where ID='"+sid+"' ";
PreparedStatement ps=con.prepareStatement(sql);
                      
ResultSet rs = ps.executeQuery();
if(rs.next()) {
                            
                String Sid=rs.getString("ID");
                id1.setText(Sid);
                String Snm=rs.getString("Name");
                nm1.setText(Snm);
                                       
                SimpleDateFormat sdf = new SimpleDateFormat("dd-M-yyyy");
                java.util.Date date = sdf.parse("DOB");
                Calendar calendar = Calendar.getInstance();
                calendar.setTime(date);
                db1.setCalendar(calender);         
                                   
                String Sem=rs.getString("Email");
                em1.setText(Sem);
                String Smb=rs.getString("MobNo");
                mb1.setText(Smb);
                String Saddr=rs.getString("Address");
                addr1.setText(Saddr);
                String Sssc=rs.getString("SSCMrks");
                ssc1.setText(Sssc);
                String Shsc=rs.getString("HSCMrks");
                hsc1.setText(Shsc);        
                       }

在那,我正在尝试更新记录,为此,我通过弹出窗口从用户那里获取 id,然后它正在从数据库中加载数据,但对于 dob,它给出了解析错误。所以我想知道如何将日期转换为日历?我已经删除了日期代码,之后它给出了当前日期和其他数据正常加载。

【问题讨论】:

  • 对于最后一个问题,您可以随时阅读文档,docs.oracle.com/en/java/javase/11/docs/api/java.base/java/text/…
  • “还有一个问题” 欢迎您就 SO 提出许多问题,只要它们经过充分研究和充分表达,但为了使网站发挥最佳作用,每个问题都应在单独的问题线程中提出。请edit 这个问题删除第二个问题,并在检查Java Docs for SimpleDateFormat 后开始一个关于它的新线程如果需要
  • Mrunal,你现在得到了什么结果?问题是您没有从数据库中获取 any 数据,DOB 字段没有返回您期望的内容,还是您在特定行出现错误? (顺便说一句,'MM' 是指定日期格式的约定,上面的文档链接更详细,但 MM -> 两位数,MMM -> 月份的短名称,MMMM -> 全名)
  • @MRUNALMUNOT 你能说出你的数据库中存储了什么吗?看起来它可能是一个字符串。您是否遇到了特定错误,例如类型错误,或者类型转换(从 String DOBTimestamp Sdb)对您的数据做了一些意想不到的事情(例如返回空白字符串或错误的日期?)
  • 我建议你不要使用SimpleDateFormatDateCalendar。这些类设计不佳且早已过时,尤其是第一个类是出了名的麻烦。而是使用来自java.time, the modern Java date and time APILocalDateDateTimeFormatter。见Insert & fetch java.time.LocalDate objects to/from an SQL database such as H2

标签: java swing jdbc java-calendar


【解决方案1】:

您的代码使您的应用程序容易受到SQL Injection 的攻击

暂时忘掉日期操作,专注于您的 JDBC 代码。您在查询中传递 sid 值的方式是 SQL 注入如何工作的经典示例。您应该使用? 作为参数的占位符并使用setter 方法传递参数。这也将帮助您摆脱明确使用的单引号。从this tutorial 了解有关使用PreparedStatement 的更多信息。

此外,当您处理某些资源(例如数据库连接、I/O 流等)时,请养成使用the try-with-resources Statement 的习惯。

你的代码应该如下:

String idpop = JOptionPane.showInputDialog(frame , "Enter Student ID to update record:");
int sid = Integer.parseInt(idpop);

Class.forName("com.mysql.jdbc.Driver");
Connection con = DriverManager.getConnection("jdbc:mysql://localhost:3306/schl","root","root");

String sql = "SELECT * FROM stud_info WHERE id =?";

try (PreparedStatement ps = con.prepareStatement(sql)) {

    ps.setString(1, sid); 
    ResultSet rs = ps.executeQuery();

    //...
} catch (SQLException e) {
    e.printStackTrace();
}

现有答案已经为您提供了与日期操作相关的修复。关于您的以下问题,我添加了一些更有用的链接:

还有一个问题。为什么MM是资本 SimpleDateFormat("yyyy-MM-dd")?

SimpleDateFormatM 计算为 一年中的月份,而 m 计算为 小时中的分钟。查看documentation of SimpleDateFormat,了解有关日期、时间、时区、时区偏移等各种符号的更多信息。

即使对于解析/格式化 API,DateTimeFormatter 对于现代日期时间类型也是如此。

【讨论】:

    【解决方案2】:

    java.time

    我建议您使用现代 Java 日期和时间 API java.time 进行日期工作。

            LocalDate date = rs.getObject("DOB", LocalDate.class);
    

    这为您提供了一个现代LocalDate 类型的实例,它比旧的CalendarDate 类更易于使用。同时它使您免于任何解析。编辑:自 JDBC 4.2(2014 年推出)以来,支持从 SQL 中的日期到 LocalDate 的转换(现在由 MySQL 实现了很长时间)。您现在已经为日期选择器更新为 java.time 或选择更现代的日期选择器的那一天做好了准备。同时,如果您需要 Calendar 来表示您当前使用的日期选择器,请按如下方式转换:

            ZonedDateTime startOfDay = date.atStartOfDay(ZoneId.systemDefault());
            Calendar calendar = GregorianCalendar.from(startOfDay);
    

    还有一个问题。为什么MM是资本 SimpleDateFormat("yyyy-MM-dd")?

    无论是使用现代的DateTimeFormatter 还是使用旧的且臭名昭著的麻烦SimpleDateFormat 或其他语言中的类似格式化程序,Java 格式模式字母都区分大小写。如果一个字母的大写和小写都可以使用,它们有不同的含义。例如:

    • 小写yyyy 表示年代,大写YYYY 表示基于周的年份(周数所属的年份,并不总是与日期所属的日历年相同)。通常小写是最常用的意思。
    • 小写 mm 表示小时的分钟,而大写 MM 表示一年中的月份(想想:一个月比一分钟长)。
    • 小写dd 表示月份中的某一天(公历中的1-31),而大写DDD 表示一年中的某一天(1-366)(想想:一年中的日期通常更大,并且再次不经常使用)。

    链接

    【讨论】:

      【解决方案3】:

      根据documentation,DATE 数据类型映射到类java.sql.Date。所以你应该在接口java.sql.ResultSet中使用方法getDate来获取DOB列的值。

      java.sql.Date dob = rs.getDate("DOB");
      

      我猜db1(在你问题的代码中)是JDateChooser,所以你需要做的就是调用方法setDate

      db1.setDate(dob);
      

      等等

      【讨论】:

      • Mrunal Munot,如果 Abra 的猜测是正确的,您可能需要寻找更新的日期选择器组件,它支持 java.time,现代 Java 日期和时间 API。 JDateChooser 真的很老了。我自己没有任何经验。例如,我所看到的LGoodDatePicker 对我来说看起来不错。搜索其他人。
      【解决方案4】:

      我认为问题在于 java.util.Date date = sdf.parse("DOB"); 试图解析 String "DOB",而不是您数据库中 DOB 的值。

      java.util.Date date = sdf.parse(rs.getString("DOB")); 可能会代替。

      您也可以尝试传入一个虚拟日期字符串(如“2020-12-09”),以查看它是否显示在您的 GUI 中,无一例外,然后努力找出如何从DB 替换虚拟日期字符串。

      Abra 的评论确实暗示了未来可能的改进:大多数数据库都有您可以使用的特定日期/时间/时间戳类型,这可能比转换为字符串、存储字符串然后再转换回 @987654325 提供更多保证@。

      【讨论】:

      • 我是你给的应用代码。现在除了日期字段保持空白之外,它不会在加载所有字段时出错。
      • @MRUNALMUNOT 你能说出 rs.getString("DOB") 中有什么吗?我不熟悉您的所有代码,但如果我 使用不熟悉的代码库,我接下来要采取的步骤是 (a) 确保如果我通过了一个固定的、虚拟的字符串到sdf.parse()(如sdf.parse("2020-01-01"))它显示在日历字段中,并且(b)将rs.getString("DOB")String值放在没有类型转换的地方,所以我可以看到什么正在传递给sdf.parse()。例如,将 rs.getString("DOB") 的值分配给表单上的文本区域,或将其记录到控制台。
      • DOB-学生的出生日期。使用该日历存储在数据库中的 java swing 中。 sdf.parse("2020-01-01")我试过了,但它显示了与它无关的其他日期。
      • 另一个日期,比如 10-jun-1 什么的
      • @MRUNALMUNOT 我认为问题在于sdf.parse() 默认情况下需要特定的日期格式(例如“01-01-2020”),但您传入的字符串没有t 匹配该格式。您传递给sdf.parse()exact 字符串显示10-jun-1