在 SQLite 中使用日期时间获取本月和上个月的值
Using datetime in SQLite for getting values this month and last month
我有一个可以跟踪花钱的应用程序。我有一个函数可以获取本月和上个月花费的所有钱。这是一个或另一个,而不是两者。它基于下面称为 lastMonth
.
的参数
每笔交易金额都进入我的 table,并附有交易日期。我使用 SQL 查询来计算总和。像这样:
if (!lastMonth) {
query += "WHERE ("
+ "CAST(" + MySQLiteHelper.COLUMN_GAS_UNIX_TIMESTAMP + " AS INT)/1000 >= CAST(strftime('%s', date('now','start of month')) AS INT) "
+ "AND "
+ " CAST(" + MySQLiteHelper.COLUMN_GAS_UNIX_TIMESTAMP + " AS INT)/1000 < CAST(strftime('%s', date('now','start of month','+1 month')) AS INT) ); ";
} else {
query += "WHERE ("
+ "CAST(" + MySQLiteHelper.COLUMN_GAS_UNIX_TIMESTAMP + " AS INT)/1000 BETWEEN CAST(strftime('%s', datetime('now','start of month', '-1 month')) AS INT) "
+ "AND CAST(strftime('%s', date('now','start of month')) AS INT) ); ";
}
这大部分 有效。但是在这个月的最后一天似乎遇到了麻烦。例如,这个问题是在八月份发布的。因此,应用仪表板当前会显示 8 月和 7 月花费的所有金额。
问题:所有 7 月 31 日的交易(或上个月的最后一天)都在 8 月的总数中。 7 月总数不包括 7 月 31 日。
编辑
我想知道 SQL 是否正确,但我把数据库中的日期放错了。这是相关代码:
Calendar cal = Calendar.getInstance();
timestamp = cal.getTimeInMillis();
使用 BETWEEN 使您的 LastMonth where 语句包含超过 1 个月。 BETWEEN 与 >= AND <= 相同。所以你说的问题。
COLUMN_GAS_UNIX_TIMESTAMP >= [Start of Last Month]
AND COLUMN_GAS_UNIX_TIMESTAMP <= [Start of This Month]
是否返回超过 1 个月的日期。上个月和本月第一天的所有时间。
关于您当前月份查询的另一个想法,您可以假设 COLUMN_GAS_UNIX_TIMESTAMP
永远不会大于 NOW
吗?如果是这样,您不需要做任何事情,只需检查 COLUMN_GAS_UNIX_TIMESTAMP is >= Start of Month.
您可以尝试如下操作:
if (!lastMonth) {
query += "WHERE ("
+ "CAST(" + MySQLiteHelper.COLUMN_GAS_UNIX_TIMESTAMP + " AS INT)/1000 >= CAST(strftime('%s', date('now','start of month')) AS INT) ";
} else {
query += "WHERE ("
+ "CAST(" + MySQLiteHelper.COLUMN_GAS_UNIX_TIMESTAMP + " AS INT)/1000 >= CAST(strftime('%s', datetime('now','start of month', '-1 month')) AS INT) "
+ "AND "
+ " CAST(" + MySQLiteHelper.COLUMN_GAS_UNIX_TIMESTAMP + " AS INT)/1000 < CAST(strftime('%s', date('now','start of month')) AS INT) ); ";
}
计算当前月份的最后一天。
SELECT日期('now','start of month','+1个月','-1天');
如果 select...
你会得到什么结果
- MySQLiteHelper.COLUMN_GAS_UNIX_TIMESTAMP
- CAST(" + MySQLiteHelper.COLUMN_GAS_UNIX_TIMESTAMP + " AS INT)/1000
- CAST(strftime('%s', date('now','start of month')) AS INT)
- CAST(strftime('%s', date('now','start of month','+1 month')) AS INT)
- CAST(strftime('%s', datetime('now','start of month','-1 月')) AS
智力)
...7 月 30 日和 31 日以及 8 月 1 日和 2 日的交易?
转换为 INT 然后除以 1000 通常会截断您的结果,因为除法将作用于整数(例如,整数 14680 除以 1000 将得出答案 14)。这是您想要的行为吗?如果您将 CAST(strftime) 部分乘以 1000 而不是将 TIMESTAMP 除以 1000,结果是否相同?
为了保持一致性以帮助您进行调试,您可能还需要考虑在 if/else 的两边使用相同的语法(例如,对两个 WHERE 子句使用 BETWEEN)并且您还可以在使用 date() 之间切换和 datetime() 在您的查询中,这也可能会产生计划外的结果。
计算月份的最后一天通常不是 date/datetime 值的唯一问题。
如果您有一个在中午发布的月份最后一天的值。不带日期时间只比较日期不计入。
您应该像这样计算,其中 >= '01/01/2015 00:00:00 并且日期 < 02/01/2015 00:00:00。这样一来,所有 1/31/2015 的记录都会被计算在内,无论它们的时间戳是什么时候。或者您可以删除月份、日期和年份,忽略时间 '20150101' 和 '20150131' 作为比较字符串。
我有一个可以跟踪花钱的应用程序。我有一个函数可以获取本月和上个月花费的所有钱。这是一个或另一个,而不是两者。它基于下面称为 lastMonth
.
每笔交易金额都进入我的 table,并附有交易日期。我使用 SQL 查询来计算总和。像这样:
if (!lastMonth) {
query += "WHERE ("
+ "CAST(" + MySQLiteHelper.COLUMN_GAS_UNIX_TIMESTAMP + " AS INT)/1000 >= CAST(strftime('%s', date('now','start of month')) AS INT) "
+ "AND "
+ " CAST(" + MySQLiteHelper.COLUMN_GAS_UNIX_TIMESTAMP + " AS INT)/1000 < CAST(strftime('%s', date('now','start of month','+1 month')) AS INT) ); ";
} else {
query += "WHERE ("
+ "CAST(" + MySQLiteHelper.COLUMN_GAS_UNIX_TIMESTAMP + " AS INT)/1000 BETWEEN CAST(strftime('%s', datetime('now','start of month', '-1 month')) AS INT) "
+ "AND CAST(strftime('%s', date('now','start of month')) AS INT) ); ";
}
这大部分 有效。但是在这个月的最后一天似乎遇到了麻烦。例如,这个问题是在八月份发布的。因此,应用仪表板当前会显示 8 月和 7 月花费的所有金额。
问题:所有 7 月 31 日的交易(或上个月的最后一天)都在 8 月的总数中。 7 月总数不包括 7 月 31 日。
编辑
我想知道 SQL 是否正确,但我把数据库中的日期放错了。这是相关代码:
Calendar cal = Calendar.getInstance();
timestamp = cal.getTimeInMillis();
使用 BETWEEN 使您的 LastMonth where 语句包含超过 1 个月。 BETWEEN 与 >= AND <= 相同。所以你说的问题。
COLUMN_GAS_UNIX_TIMESTAMP >= [Start of Last Month]
AND COLUMN_GAS_UNIX_TIMESTAMP <= [Start of This Month]
是否返回超过 1 个月的日期。上个月和本月第一天的所有时间。
关于您当前月份查询的另一个想法,您可以假设 COLUMN_GAS_UNIX_TIMESTAMP
永远不会大于 NOW
吗?如果是这样,您不需要做任何事情,只需检查 COLUMN_GAS_UNIX_TIMESTAMP is >= Start of Month.
您可以尝试如下操作:
if (!lastMonth) {
query += "WHERE ("
+ "CAST(" + MySQLiteHelper.COLUMN_GAS_UNIX_TIMESTAMP + " AS INT)/1000 >= CAST(strftime('%s', date('now','start of month')) AS INT) ";
} else {
query += "WHERE ("
+ "CAST(" + MySQLiteHelper.COLUMN_GAS_UNIX_TIMESTAMP + " AS INT)/1000 >= CAST(strftime('%s', datetime('now','start of month', '-1 month')) AS INT) "
+ "AND "
+ " CAST(" + MySQLiteHelper.COLUMN_GAS_UNIX_TIMESTAMP + " AS INT)/1000 < CAST(strftime('%s', date('now','start of month')) AS INT) ); ";
}
计算当前月份的最后一天。 SELECT日期('now','start of month','+1个月','-1天');
如果 select...
你会得到什么结果- MySQLiteHelper.COLUMN_GAS_UNIX_TIMESTAMP
- CAST(" + MySQLiteHelper.COLUMN_GAS_UNIX_TIMESTAMP + " AS INT)/1000
- CAST(strftime('%s', date('now','start of month')) AS INT)
- CAST(strftime('%s', date('now','start of month','+1 month')) AS INT)
- CAST(strftime('%s', datetime('now','start of month','-1 月')) AS 智力)
...7 月 30 日和 31 日以及 8 月 1 日和 2 日的交易?
转换为 INT 然后除以 1000 通常会截断您的结果,因为除法将作用于整数(例如,整数 14680 除以 1000 将得出答案 14)。这是您想要的行为吗?如果您将 CAST(strftime) 部分乘以 1000 而不是将 TIMESTAMP 除以 1000,结果是否相同?
为了保持一致性以帮助您进行调试,您可能还需要考虑在 if/else 的两边使用相同的语法(例如,对两个 WHERE 子句使用 BETWEEN)并且您还可以在使用 date() 之间切换和 datetime() 在您的查询中,这也可能会产生计划外的结果。
计算月份的最后一天通常不是 date/datetime 值的唯一问题。
如果您有一个在中午发布的月份最后一天的值。不带日期时间只比较日期不计入。
您应该像这样计算,其中 >= '01/01/2015 00:00:00 并且日期 < 02/01/2015 00:00:00。这样一来,所有 1/31/2015 的记录都会被计算在内,无论它们的时间戳是什么时候。或者您可以删除月份、日期和年份,忽略时间 '20150101' 和 '20150131' 作为比较字符串。