从java中将日期时间插入sqlite的正确方法是什么?
问题描述:
当我尝试使用sqlite3查询通过JDBC插入的日期时,我看到意外的结果。这java代码:从java中将日期时间插入sqlite的正确方法是什么?
try (Connection conn = DriverManager.getConnection("jdbc:sqlite:test.db")) {
conn.setAutoCommit(true);
try (Statement statement = conn.createStatement()) {
statement.executeUpdate("create table dates (date DATETIME);");
}
try (PreparedStatement insert = conn
.prepareStatement("insert into dates values (?)")) {
insert.setTimestamp(1, Timestamp.valueOf(LocalDateTime.now()));
insert.executeUpdate();
}
}
似乎没有插入正确的日期时间 - 当我通过sqlite3的查询它,我不能让人类可读的值:
sqlite3 test.db "select date, datetime(date, 'unixepoch') from dates;"
1507819362296|
这是有道理的,因为sqlite文档说有效的unix时代范围是“-62167219200到106751991167”(https://sqlite.org/lang_datefunc.html)。
我该如何使用JDBC和Sqlite的日期?
答
SQLite中没有正式的日期或时间戳类型,而是由字符串表示。所以,如果你想为当前的时间戳插入到你的表,你可以尝试以下方法:
try (Connection conn = DriverManager.getConnection("jdbc:sqlite:test.db")) {
conn.setAutoCommit(true);
try (Statement statement = conn.createStatement()) {
statement.executeUpdate("CREATE TABLE dates (date TEXT);");
}
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Timestamp timestamp = new Timestamp(System.currentTimeMillis());
String ts = sdf.format(timestamp);
try (PreparedStatement ps = conn
.prepareStatement("INSERT INTO dates (date) VALUES (?)")) {
ps.setString(1, ts);
ps.executeUpdate();
}
}
答
@马克W¯¯我们一直把日期在sqlite的DB为字符串,但是他们不是很期待这样的字符串10 18-2017他们进来像这样10182017和是的他们都是8个字符长。但是当你把它们拉出来时,他们都会穿上衣服并转换回这个10-18-2017。我们已经测试了我们的搜索和所有似乎与SELECT *所需FROM TABLE_NAME工作WHERE Col_Date> =“再从” Col_Date < =“到”下面是制作日期不那么漂亮的代码
public void findByDate(View view){
use= false;
// custom dialog /* THIS R.style.DatePickerThem is mandatory to use res/values/styles */
final Dialog dialog = new Dialog(MainActivity.this,R.style.DatePickerTheme);
dialog.setContentView(R.layout.datepickerview);
dialog.setTitle("");
DatePicker picker = dialog.findViewById(R.id.datePicker);
final Calendar c = Calendar.getInstance();
mYear = c.get(Calendar.YEAR);
mMonth = c.get(Calendar.MONTH);
mDay = c.get(Calendar.DAY_OF_MONTH);
//picker.updateDate(2017, 10, 13);//year month day
picker.updateDate(mYear, mMonth, mDay);// Keeps Calendar initial view what ever today is!
System.out.println("Month " + mMonth+1);
picker.init(c.get(Calendar.YEAR), c.get(Calendar.MONTH), c.get(Calendar.DAY_OF_MONTH), new DatePicker.OnDateChangedListener() {
//picker.init(Integer.valueOf(mMonth),Integer.valueOf(mDay),Integer.valueOf(mYear), new DatePicker.OnDateChangedListener() {
@Override
public void onDateChanged(DatePicker picker, int year, int monthOfYear, int dayOfMonth) {
if (etFromDate.getText().toString().isEmpty()) {
System.out.println("I am Not Empty");
//etFromDate.setText(String.valueOf(monthOfYear+1) + String.valueOf(dayOfMonth) + String.valueOf(year));
//v1 = Long.valueOf(etFromDate.getText().toString());
//etFromDate.setText(String.valueOf(v1));
//String theDATE = (monthOfYear+1) + "-" + (dayOfMonth) + "-" + (year);
String searchFrom = (String.valueOf(monthOfYear+1))+(String.valueOf(dayOfMonth))+String.valueOf(year);
if(searchFrom.length()==7){
StringBuilder str = new StringBuilder(searchFrom);
str.insert(2, '0');
etFromDate.setText(str);
}else if (searchFrom.length() == 6){
StringBuilder str = new StringBuilder(searchFrom);
str.insert(0,'0');
str.insert(2,'0');
etFromDate.setText(str);
}else {
etFromDate.setText(searchFrom);
}
//setDATE = etFromDate.getText().toString();
dialog.dismiss();
然后这里是一个方式来看待相同的字符串10182017的高级时装日期
helper = new DBHelper(this);
dbList = new ArrayList<>();
dbList = helper.getDataFromDB();
if (dbList.size() > 0 && tORf.equalsIgnoreCase("false")) {
btnSave.setVisibility(View.INVISIBLE);
String NVrowid = String.valueOf(dbList.get(position).getRowid());
String NVstation = dbList.get(position).getStation_Name();
String NVpurchasedate = dbList.get(position).getDate_of_Purchase();
String s = NVpurchasedate;
String month = s.substring(0, 2);
String day = s.substring(2, 4);
String year = s.substring(4, 8);
String date3 = month + "-" + day + "-" + year;
String NVcost = dbList.get(position).getGas_Cost();
etStation.setText(NVstation);
etPurchaseDate.setText(date3);
//etPurchaseDate.setText(NVpurchasedate);
etCost.setText(NVcost);
}
我能做到这一点,但它意味着我的应用程序现在包含逻辑来解决SQLite中日期的内部表示。并使我的代码特定于sqlite。 似乎应该有一个更好的方法来将sqlite实现细节留给JDBC驱动程序。 –
@MarkW您正在使用哪种驱动程序,并且可以编辑您的问题以包含该驱动程序文档的链接? –
@MarkW [见这里](https://stackoverflow.com/questions/5425557/sqlite-jdbc-rs-getdate-gettimestamp-etc-all-return-wrong-values),其讨论了一种非常类似的问题到你的,并其结论是日期需要在SQLite和Java中作为字符串处理。 –