使用UCanAccess JDBC驱动程序格式化日期

5
在Java中使用UCanAccess驱动程序时,我发现很难将日期输出到特定格式。目前,我正在使用PreparedStatement.setDate() 方法,该方法要求日期格式为[yyyy-MM-dd HH:mm:ss]。当用户打开文件时,输出的结果也是这种格式。
编辑* - 我没有使用setDate() 方法来设置格式化后的日期,该方法仅接受没有格式的Java Date对象。我的意思是在处理格式化日期时使用setString() 方法,但UCanAccess要求该日期字符串的格式为[yyyy-MM-dd HH:mm:ss]。我真正想知道的是如何在调用setString() 后更改其格式或提供不同的格式。
到目前为止这一切都还好,但现在我需要以各种格式(例如[MM-dd])交付日期文件。我已经可以通过使结果Access字段类型成为Memo或Text来实现这一点,但问题在于当我需要日期以那种格式呈现并且结果Access字段类型仍为日期/时间时就会出现问题。
我注意到在 UCanAccess首页 上面提到了支持Access日期格式,但我在Google上搜索了好几次,也找不到任何示例。有人知道如何使用这个驱动程序格式化日期并保持正确的日期/时间类型吗?
提前感谢!

2
PreparedStatement.setDate() 需要一个 java.sql.Date 参数,该参数没有格式(也不用于执行“输出”)。 - user330315
@a_horse_with_no_name,您说得非常正确。在使用Java日期时(只是一个长整型,没有格式),我正在使用setDate()方法,然后在设置带格式的日期时使用setString()方法。这需要格式[yyyy-MM-dd HH:mm:ss]。我试图使它能够接受任何格式或在调用setString()后以编程方式更改格式。 - ksmark
不要使用 setString() 来处理日期,应该使用 setDate()。日期的格式化应该在前端显示(读取)数据时处理,而不是在保存数据时处理。 - user330315
问题在于我得到的日期是以字符串格式呈现的,而我需要稍微调整一下格式以允许其他样式。此外,我希望能够提供一个“完成”的Access文件,其中日期以所需的方式进行格式化,而不必手动打开文件并进行更改。 - ksmark
1个回答

5
当您通过UCanAccess检索日期/时间字段值时,您会获得一个java.sql.Timestamp对象。它包含了日期/时间的值,但它本身并没有一个格式。
如果您想以特定的方式表示该日期/时间值,只需将其格式化为您喜欢的方式即可。最简单的方法可能是使用java.text.SimpleDateFormat。例如:
try (ResultSet rs = s.executeQuery("SELECT DateJoined FROM Members WHERE MemberID=1")) {
    rs.next();
    System.out.printf(
            "         \"raw\" value (via .toString()): %s%n", 
            rs.getTimestamp(1).toString());
    SimpleDateFormat mmddFormat = new SimpleDateFormat("MM-dd");
    System.out.printf(
            "formatted value (via SimpleDateFormat): %s%n", 
            mmddFormat.format(rs.getTimestamp(1)));
}

给我们
         "raw" value (via .toString()): 2014-01-23 00:00:00.0
formatted value (via SimpleDateFormat): 01-23

请注意,当UCanAccess页面谈到“访问日期格式”时,它是指用井号括起来的日期/时间文字,如:#11/22/2003 10:42:58 PM#。然而,几乎永远不需要在查询中包含日期文字,因为您应该使用带有适当.setTimestamp()参数的PreparedStatement附言 同样地,向访问数据库插入日期/时间值时,Java中日期/时间值的格式对于访问中存储的日期/时间值没有影响(只要它被正确解释),而它在访问中显示的方式是一个反映在访问设置中的函数。例如,如果我们运行以下Java代码:
try (Statement s = conn.createStatement()) {
    s.executeUpdate(
            "INSERT INTO tblDates " +
            "(ID, mmddyyyy) " +
            "VALUES " +
            "('literal', #12/25/2014#)"
            );
}

SimpleDateFormat mmddyyyyFormat = new SimpleDateFormat("MM/dd/yyyy");
Timestamp mmddyyyyXmas = 
        new Timestamp(mmddyyyyFormat.parse("12/25/2014").getTime());

SimpleDateFormat ddmmyyyyFormat = new SimpleDateFormat("dd/MM/yyyy");
Timestamp ddmmyyyyXmas = 
        new Timestamp(ddmmyyyyFormat.parse("25/12/2014").getTime());

SimpleDateFormat yyyymmddFormat = new SimpleDateFormat("yyyy/MM/dd");
Timestamp yyyymmddXmas = 
        new Timestamp(yyyymmddFormat.parse("2014/12/25").getTime());

try (PreparedStatement ps = conn.prepareStatement(
        "INSERT INTO tblDates " +
        "(ID, mmddyyyy, ddmmyyyy, yyyymmdd) " +
        "VALUES " +
        "('parameters', ?, ?, ?)"
        )) {
    ps.setTimestamp(1, mmddyyyyXmas);
    ps.setTimestamp(2, ddmmyyyyXmas);
    ps.setTimestamp(3, yyyymmddXmas);
    ps.executeUpdate();
}

然后使用 Windows 默认的 "英语(美国)" 格式打开 Access 数据库,我们可以看到: en_us.png 如果我们在 Windows 中更改格式设置为 "英国英语",则会看到: en_gb.png 如果我们想要为一个或多个字段使用特定的格式,则需要在 Access 中使用特定的格式设置,例如像这样: DesignView.png 我们可以看到: DatasheetView.png

谢谢回复,我实际上不是在尝试从Access数据库中查询数据,而是在尝试将数据插入其中。当打开文件本身时,我需要以特定格式向用户显示日期。 - ksmark
@ksmark 你所说的“打开文件本身”,是指在Access中打开它吗?如果是这样,那么Access将默认使用“常规”日期/时间格式,该格式是根据Windows控制面板(区域设置)中定义的“短日期”和“长时间”设置组合而成的(参考:此处)。如果您想在Access中看到特定的格式,则需要在Access中指定它,例如,在表字段或特定表单/报告控件的.Format属性中。 - Gord Thompson
哇,非常感谢您在这里提供如此详细的回复。那太糟糕了,没有办法以编程方式设置Access .Format属性吗?这必须在生成文件后进行吗? - ksmark
@ksmark 我不认为Jackcess(以及UCanAccess)有办法在创建新表时指定字段的.Format。但是,您可以使用Access创建一个具有所需格式的数据库文件(用于表格、表单、报表),将表格保留为空,并使用UCanAccess将数据推送到该“骨架”文件的副本中,而不是从头开始创建新的空.accdb/.mdb文件。 - Gord Thompson
嗯,这个解决方案可能有一些曙光。无论如何,感谢您对此的所有帮助! - ksmark

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接