为什么查询日期BC在Java中更改为AD?

时间:2017-10-19 16:52:27

标签: java sql oracle date bc

我的Java程序连接到包含许多日期的数据库(Oracle XE 11g)(OracleXE的日期格式设置为syyyy / mm / dd)。

在数据库中使用负日期(在基督之前)进行查询工作正常。当我用Java编写时,它们都被改为AD(Anno Domini)。如何在Java中检索关于AD / BC的日期?

我的Java代码在这里查询数据库并将结果放在表格中。

try {
    Object item=cbPD.getSelectedItem();                                 
    String dacercare=item.toString();
    query = "SELECT DISTINCT PD.Titolo,PD.Inizio,(Select E.nome From Evento E WHERE PD.Inizio_Evento=E.CODE),
            PD.Fine, (Select E.nome From Evento E  WHERE PD.Fine_Evento=E.CODE ) FROM Periododelimitato PD WHERE PD.Titolo=?";
    PreparedStatement stAccess = Login.connessione.prepareStatement(query, ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
    stAccess.setString(1,dacercare);
    rset = stAccess.executeQuery(); 
    j = modelPD.getRowCount();
    for (i=0; i<j; i++) modelPD.removeRow(0);
    Date data;
    while (rset.next()) {
        data = rset.getDate(2);
        modelPD.addRow(new Object[]{rset.getString(1),data, rset.getString(3), rset.getString(4), rset.getString(5)});
    }       
}

这是使用特定查询的示例

try {
    query = "SELECT PD.Inizio FROM PeriodoDelimitato PD WHERE PD.CodP=?";
    String dacercare="8"; //look for record with this specific Primary key
    PreparedStatement stAccess = Login.connessione.prepareStatement(query,
            ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
    stAccess.setString(1, dacercare);
    rset = stAccess.executeQuery(); 
    while(rset.next()) {
        Date dateBC = rset.getDate(1);
        modelPD.addRow(new Object[]{null, dateBC, null, null, null});
    }
Java中的

输出是:

0509-01-01

输出在Sql开发人员中使用相同的查询(用指定的主键代替):

-0509/01/01

关于查询的注意事项:此示例中选择的列在Oracle中为DATE类型。

添加信息:DBMS是Oracle(XE 11g),DB是基于IDE(SQL开发人员)构建的。该程序是通过Netbeans 8.2用Java编写的。我连接到Netbeans中的数据库,添加了库“ojdbc6.jar”。

2 个答案:

答案 0 :(得分:1)

首先,目前还不清楚你应该如何处理历史性的,尤其是史前的日期以及你应该如何表现它们的行为。这不是我所知道的,但我怀疑今天常用的任何日历都是在公元前6世纪使用的(在共同时代之前,“BC”)。也许你已经知道了,我只是想为其他读这个答案的人提一下。

感谢Basil Bourque(现已删除)的答案,您所观察到的似乎是java.sql.Date的预期行为。我尝试从公元2年(公共时代,“公元”)和公元前2年开始印刷日期并进行比较。前2个CE:

    LocalDate ld = LocalDate.of(2, 1, 1);
    java.sql.Date sqlDate = java.sql.Date.valueOf(ld);
    System.out.println("java.sql.Date " + sqlDate + " millis " + sqlDate.getTime());
  

java.sql.Date 0002-01-01 millis -62104237200000

这是预期的。对于2 BCE,我们需要提供-1到LocalDate,因为0表示1 BCE,-1表示2 BCE。在上面的代码中插入LocalDate.of(-1, 1, 1),输出为

  

java.sql.Date 0002-01-01 millis -62198931600000

我们注意到日期打印相同。 0002很难完全不正确,但它并没有告诉我们是公元前2年还是公元前2年。我相信这解释了你观察到的行为。接下来我们注意到毫秒值是不同的,所以日期应该是不同的。差异为94694400000毫秒,如果其中一个是闰年,则相当于1096天或3年。闰年可能会令人惊讶,但我认为这是正确的。

但是,有些东西是可疑的。当我将sql日期转换回LocalDate时,时代已经消失,我总是在共同时代得到一个约会。由于您不需要这种转换,因此您可能不需要关心。

我认为好的解决方案是完全放弃过时的Date课程,并始终使用现代LocalDate课程。您应该知道这遵循所谓的proleptic Gregorian calendar,它可能并不总是提供与Date完全相同的日期。这也需要JDBC 4.2兼容的驱动程序,因此您的ojdbc6.jar不会这样做。虽然这可能意味着你被阻止了,但我让这个建议代表其他人一起阅读。我没有测试过,但我认为以下内容应该有效:

LocalDate dateBC = rset.getObject(1, LocalDate.class);

答案 1 :(得分:0)

使用旧的Date类型查询SQL日期BC和AC的解决方案是在我的类中声明一个具有下面指定格式的SimpleDataFormat

# Map static resources from the /public folder to the /assets URL path
GET     /assets/*file               controllers.Assets.versioned(path = "/public/accounts/dist", file: Asset)

# Map static resources from the /public folder to the /assets URL path
GET     /assets/*file               controllers.Assets.at(path = "/public", file)

然后我声明了一个Date dataOUT调用SimpleDataFormat的format方法,将从数据库中查询的Date BC作为输入

public SimpleDateFormat sdf= new SimpleDateFormat("yyyy-MM-dd G");

感谢大家对我的问题所花的时间!