sqlite中的strftim()给出错误结果

时间:2019-02-19 16:12:15

标签: android sql sqlite android-room strftime

我将date字段存储在数据库中,距历时以来的

enter image description here

对于图像中的时间戳记(1550591783-表示2019-02-19 19:26:23),sqlite应该在一年中的某天返回50,但它返回40

这是PurchaseDao中的查询:

@Query("SELECT strftime('%j', date, 'unixepoch', 'localtime') AS day " +
       "FROM purchase " +
       "WHERE ...")
abstract List<Cost> getCosts();

这是日期转换器:

public class DateConverter {

    @TypeConverter
    public static Date fromTimestamp(Long value) {
        return value == null ? null : new Date(value * 1_000); // multiply by 1000 to make it milliseconds
    }

    @TypeConverter
    public static Long toTimestamp(Date date) {
        return date == null ? null : date.getTime() / 1_000; // divide by 1000 to store as seconds
    }
}

即使我将now作为参数进行查询(实际上,我什至在没有任何其他干扰的情况下也将其应用于了新方法),我仍然得到相同的错误结果:

@Query("SELECT strftime('%j', 'now', 'localtime')")

我尝试删除'localtime'参数,更改日期转换器以将日期存储为字符串(例如,格式为2019-02-19),然后在AVD中运行该应用程序,但在相同的错误结果中所有情况。

另一方面,当我使用日历(Calendar.getInstance().get(Calendar.DAY_OF_YEAR);)获得一年中的某天或使用Stetho在我的PC中运行查询时,结果是正确的。

任何帮助表示赞赏。

1 个答案:

答案 0 :(得分:5)

正如我已经解释过的here,UNIX时间的转换类似于这样:

SELECT DATE(dateColumn, 'unixepoch') AS isodate FROM tableName

,或者自纪元开始存储毫秒数后,这对于Android Java来说很常见:

SELECT DATE(ROUND(dateColumn / 1000), 'unixepoch') AS isodate FROM tableName

这不需要TypeConverter中的任何乘法或除法。而1_000中的这个乘法/除法操作数TypeConverter对我来说很奇怪。

这里的问题可能与纯SQL完全相同...在999/1000情况下,date.getTime() / 1000只能表示为float的值,而不能表示为直接的{{1} }整数值-除非将该值舍入为long整数值。 long将通过SQL阻止这种情况。不知何故,这个问题缺乏背景;请在下面评论您需要获得的特定价值-以及为什么需要获得它;那么我也许可以扩大答案-因为我不太了解在一年中的某一天进行购买的目的。我希望这是自购买以来已经过了几天。