将 DATETIME 从 SQLite 解析为 java.SQL.Timestamp 时出错

Posted

技术标签:

【中文标题】将 DATETIME 从 SQLite 解析为 java.SQL.Timestamp 时出错【英文标题】:Error when parsing DATETIME from SQLite to java.SQL.Timestamp 【发布时间】:2020-05-21 10:20:08 【问题描述】:

我正在使用 java 11 和 SQLite 3.30.1 制作桌面 windows pc 应用程序。在我的 sql 表“警报”中,我有一个日期 (DATETIME) 列,我尝试使用 jdbc resultset.getTimestamp() 检索它。但我收到以下错误:“java.sql.SQLException:解析时间戳时出错”。 由于这是一个警报管理器,我想存储日期+时间。我还希望能够从另一个中减去 2 个日期。 这是我的闹钟:

CREATE TABLE "alarms" (
"id"    INTEGER NOT NULL,
"date"  DATETIME NOT NULL,
"name"  TEXT,
"text"  TEXT NOT NULL,
PRIMARY KEY("id")
);

这是我的警报 java 类:

import java.io.Serializable;
import java.sql.Timestamp;

public class Alarms implements Serializable 

private int id;

private Timestamp date;

private String name;

private String text;

public Alarms() 


public Alarms(int id, Timestamp date, String name, String text) 
    this.id = id;
    this.date = date;
    this.name = name;
    this.text = text;


public int getId() 
    return id;


public void setId(int id) 
    this.id = id;


public Timestamp getDate() 
    return date;


public void setDate(Timestamp date) 
    this.date = date;


public String getText() 
    return text;


public void setText(String text) 
    this.text = text;


public String getName() 
    return name;


public void setName(String name) 
    this.name = name;


@Override
public String toString() 
    return name;


这是我的 java jdbc 方法:

    public ObservableList<Alarms> getAlarms() 

    alarmsList.clear();
    try 
            s = "SELECT * FROM alarms";

        statement = connection.createStatement();
        resultSet = statement.executeQuery(s);
        while (resultSet.next()) 

            Alarms al = new Alarms();
            al.setId(resultSet.getInt(1));
            al.setDate(resultSet.getTimestamp(2)); 
            al.setName(resultSet.getString(3));
            al.setText(resultSet.getString(4));

            alarmsList.add(al);

        
        return alarmsList;

     catch (SQLException throwables) 
        throwables.printStackTrace();
    
    return null;

所以问题是,我如何使用 jdbc 在 SQLite 中存储、插入和检索日期+时间?我做错了什么?

【问题讨论】:

【参考方案1】:

根据spec,SQLite中没有DATETIME类型。

它将被转换为NUMERIC。您可以在请求中使用各种功能来获得您想要的:date & time functions

【讨论】:

即使没有 DATETIME 类型,如果您在表中输入 DATETIME 作为类型,它也可以工作。它返回一个字符串。事实上,我已经使用 DATE 类型很长时间了,而且效果很好。并且没有 DATE 类型。在内部,SQLite 将其转换为另一种工作类型。问题是使用日期,更简单,并且有很多文档。但是对于存储日期+时间,几乎没有任何信息。【参考方案2】:

经过一整天的搜索,我找到了解决方案。在您的 SQLite 表中,您可以完美地使用 DATETIME 来存储日期+时间。SQLite 会将其存储为字符串。我的表格如下:

CREATE TABLE "alarms" (
"id"    INTEGER NOT NULL,
"date"  DATETIME NOT NULL,
"name"  TEXT,
"text"  TEXT NOT NULL,
PRIMARY KEY("id")
);

由于 SQLite 返回一个字符串,因此您必须在 java 中的结果集上使用“getString()”。该字符串是一个 Long 数字,例如 1588370406005 。 所以我不得不在我的 Alarms java 类中添加一些额外的 getter 和 setter。 这是我的警报 java 类:

import java.io.Serializable;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZoneOffset;


public class Alarms implements Serializable 

private int id;

private LocalDateTime date;

private String name;

private String text;

public Alarms() 


public Alarms(int id, LocalDateTime date, String name, String text) 
    this.id = id;
    this.date = date;
    this.name = name;
    this.text = text;


public int getId() 
    return id;


public void setId(int id) 
    this.id = id;


public LocalDateTime getDate() 
    return date;


public String getDateStringFormat()

    return Long.toString(date.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli());



public void setDate(LocalDateTime date) 
    this.date = date;


public void setDate(String stringDate)

    date= Instant.ofEpochMilli(Long.parseLong(stringDate)).atZone(ZoneId.systemDefault()).toLocalDateTime();



public String getText() 
    return text;


public void setText(String text) 
    this.text = text;


public String getName() 
    return name;


public void setName(String name) 
    this.name = name;


@Override
public String toString() 
    return name;


我的 JDBC 方法是:

public ObservableList<Alarms> getAlarms() 

    alarmsList.clear();
    try 
            s = "SELECT * FROM alarms";

        statement = connection.createStatement();
        resultSet = statement.executeQuery(s);
        while (resultSet.next()) 

            Alarms al = new Alarms();
            al.setId(resultSet.getInt(1));
            al.setDate(resultSet.getString(2));
            al.setName(resultSet.getString(3));
            al.setText(resultSet.getString(4));

            alarmsList.add(al);

        
        return alarmsList;

     catch (SQLException throwables) 
        throwables.printStackTrace();
    
    return null;

希望这对某人有所帮助。

【讨论】:

以上是关于将 DATETIME 从 SQLite 解析为 java.SQL.Timestamp 时出错的主要内容,如果未能解决你的问题,请参考以下文章

从 SQL 数据库导入表并按日期过滤行时,将 Pandas 列解析为 Datetime

将克罗地亚日期字符串解析为 DateTime

MVC 控制器接收从 CurrentThread.CurrentCulture 解析为不同文化的 DateTime

将 XML 解析为 sql 参数、datetime2 和位问题

如何从 Sqlite ( android ) 中的 datetime 字段获取日期

为啥 C# 提前 7 小时解析 DateTime?