【问题标题】:strftime('%m',date) returns wrong month value only for 2 monthsstrftime('%m',date) 仅在 2 个月内返回错误的月份值
【发布时间】:2020-06-07 06:29:13
【问题描述】:

我一直在寻找一些答案,但我仍然对这个问题感到困惑。

我正在使用 Room,我有一个数据库,我在其中存储具有以下格式的日期: 'YYYY-MM-DDTHH:MM:SS.sss',因为我使用 LocalDateTime.now() 创建它们。

我正在尝试执行查询以获取日期在 start_date 和 end_date 之间的项目,两者的格式均为“YYYY-MM-DD”。我从 DatePickerDialog 获取值,所以没有附加时间。

我尝试了这两个查询,都给了我错误的结果:

@Query("SELECT strftime('%m-%Y',date) as month, COUNT(*) as total from items 
WHERE date>= :start_date AND date< :end_date GROUP BY strftime('%m-%Y',date)")

LiveData<List<Result>> getResult(String start_date, String end_date);
@Query("SELECT strftime('%m',date) as month, COUNT(*) as total from items 
WHERE date>= :start_date AND date< :end_date GROUP BY strftime('%m',date)")

LiveData<List<Result>> getResult(String start_date, String end_date);

现在,我通过两个查询(例如“02”或“02-2020”)都正确获得了月份数,但不是总数。问题是它仍然不计算 item_date=end_date 的项目。将查询部分从 AND date&lt; :end_date 更改为 AND date&lt;= :end_date 不起作用,我想确保它计算开始和结束月份的所有记录,而不管时间戳如何。

我想计算所选日期内每个月的项目数。为简单起见,我只让用户选择去年的日期(例如,从 7 月到 6 月)。我想得到的 2 个值是月份的数字 (1-12) 和当月的项目总数。

我怎样才能让这个查询工作?

提前致谢。

EDIT1:我解决了部分问题,我的错误是我使用了错误数据类型的 POJO(我使用 int 来获取 strftime("%m-%Y", date) 部分)。改成这样就解决了:

public class Tuple{

    @ColumnInfo(name="month")
    private String Date; // my mistake was here, had int instead of String
....

}

EDIT2:帖子很长,所以我正在编辑以只留下相关信息以及对我有用的信息,以防它帮助其他人:我使用了已接受答案的建议提示(用date()包装日期)并再次将结束日期限制部分更改为AND date&lt;= :end_date。

【问题讨论】:

  • 建议您使用sqlite3 来调试问题。您可以use it remotely over adb 或使用 Android Studio 设备文件资源管理器将您的数据库复制到您的开发系统并在副本上运行 sqlite3。我尝试使用您帖子中的信息重现该问题,但无法获得您的结果。您的items 表是否足够小,您可以编辑您的帖子以包含SELECT date FROM items 的输出,以便我们可以准确地看到您的数据库中的date 值是什么?
  • @BobSnyder 感谢您的快速响应。感谢您的建议,我发现我的问题是使用错误的数据类型获取带有 POJO 的日期字段,现在我的问题只是获取总数,我刚刚编辑了问题。
  • 你能发布你的表的类表示吗?
  • @VivekSasidharan 当然,在查询之后添加。 Getter 和 setter 是自动生成的,所以如果您需要更多信息,请告诉我。

标签: java android android-sqlite android-room mpandroidchart


【解决方案1】:

sqlite 没有 DateTime 数据类型。因此,您将日期存储为字符串。您还使用Date 字符串(通过与DateTime 字符串进行比较)在查询中进行过滤。对于查询日期参数,您使用YYYY-MM-DD 格式,而存储您使用YYYY-MM-DD hh:mm:ss。这是一个字符串比较,这种不一致的比较可能会产生意想不到的结果。

我会推荐:

  1. 您在 sqlite 中使用date() 遵循一致的日期格式来比较日期字符串。

或者更好

  1. 在Room 中使用TypeConverter 并以long 之类的格式存储日期并使用该格式进行比较。

【讨论】:

  • 它终于起作用了,用date()包装日期并将查询更改回AND date&lt;= :end_date添加=就可以了。在这种情况下,我无法摆脱时间戳,因为我需要它用于其他目的,所以它派上用场了,谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-03-27
  • 2012-02-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多