【发布时间】:2014-08-26 21:33:50
【问题描述】:
在我的 SQLite 数据库表中有一个时间戳 (毫秒) 列。这个表真的很大,我想要一种有效的方法来查询时间戳列引用特定日期的所有行(在这种情况下,我想获取属于 TODAY 的所有条目)。
我想出了这个,但它不起作用而且速度很慢。任何想法都会被应用。 (不,我不能在数据库中进行任何更改,例如添加 DATETIME 列...我必须使用时间戳)。
public boolean isTimestampInToday(long timestamp){
//get a timestamp from today
long todayStamp = System.currentTimeMillis();
Calendar c = Calendar.getInstance();
c.setTimeInMillis(todayStamp);
c.setTimeZone(TimeZone.getDefault());
c.set(Calendar.HOUR_OF_DAY, 0);
c.set(Calendar.MINUTE, 0);
c.set(Calendar.SECOND, 0);
c.set(Calendar.MILLISECOND, 0);
Date startDate = c.getTime(); //START OF DAY
c.set(Calendar.HOUR_OF_DAY, 23);
c.set(Calendar.MINUTE, 59);
c.set(Calendar.SECOND, 59);
c.set(Calendar.MILLISECOND, 999);
Date endDate = c.getTime(); //END OF DAY
Long startStamp = startDate.getTime();
Long endStamp = endDate.getTime();
if(timestamp >= startStamp && timestamp < endStamp) {
return true;
} else {
return false;
}
}
我感谢有经验的人的所有答案,但老实说,我能理解的是@iaune 的答案。现在我已经在查询本身内部完成了这项工作:
Calendar gc = new GregorianCalendar();
gc.setTimeZone(TimeZone.getDefault());
long toBeg = gc.getTimeInMillis();
toBeg -= toBeg % (24*60*60*1000);
long toEnd = toBeg + 24*60*60*1000;
Cursor cursor = mDb.rawQuery(
"SELECT * FROM "
+ DbHelper.TABLE_PA_DATA
+ " WHERE "
+ DbHelper.COLUMN_TIMESTAMP
+ " BETWEEN "
+ toBeg
+ " AND "
+ toEnd
, null);
这种方法有什么问题还是可以进一步改进?
更新
我意识到使用INTEGER 作为时间戳列类型是错误的。我添加了一个DATETIME 列...我现在应该使用直接 SQLite 查询函数。有什么想法吗?
这是我转储表格时得到的结果:
ID DATETIME TIMESTAMP STEPS CALORIES
1 2014-07-06 07:18:55 169629539 3 0
2 2014-07-06 07:19:10 169644509 4 0
3 2014-07-06 08:15:36 173030229 1 0
4 2014-07-06 08:16:04 173058397 4 0
5 2014-07-06 08:31:39 173993598 2 0
6 2014-07-06 08:33:20 174094714 5 0
7 2014-07-06 09:31:54 177609142 1 0
8 2014-07-06 09:42:24 178238517 1 0
9 2014-07-06 10:37:37 181551849 1 0
10 2014-07-06 11:00:31 182925950 1 0
11 2014-07-06 12:17:42 187557035 1 0
12 2014-07-06 14:14:39 194573993 2 0
好的,我设法在@laune 解决方案中添加了一些内容:
Calendar cal = Calendar.getInstance();
// offset to add since we're not UTC
long offset = cal.get(Calendar.ZONE_OFFSET) +
cal.get(Calendar.DST_OFFSET);
long toBeg = cal.getTimeInMillis();
toBeg -= (toBeg + offset) % (24*60*60*1000);
long toEnd = (toBeg) + 24*60*60*1000;
使用这个查询:
Cursor cursor = mDb.rawQuery(
"SELECT * FROM "
+ Database.TABLE_PA_DATA
+ " WHERE "
+ Database.COLUMN_TIMESTAMP
+ " BETWEEN "
+ toBeg
+ " AND "
+ toEnd, null
);
【问题讨论】:
-
你的 SQL 代码在哪里?你不是要查询你的数据库吗?
-
SQLite 不提供 Timestamp milliseconds-since-epoch 数据类型。那么究竟是什么data type of your column?
-
@BasilBourque 它只是一个
integer专栏 -
那么你存储的是秒还是毫秒?你的问题说毫秒,但SQLite doc 说秒。
-
@BasilBourque 我将
TIMESTAMP列创建为INTEGER,并将System.currenttimemili存储在其中,所以我猜它的毫秒数
标签: java android sql sqlite datetime