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

Mah*_*zad 6 sql sqlite android strftime android-room

我将date字段存储为自纪元以来的秒数

在此处输入图片说明

对于图像中的时间戳记(1550591783-representing 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();
Run Code Online (Sandbox Code Playgroud)

这是日期转换器:

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
    }
}
Run Code Online (Sandbox Code Playgroud)

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

@Query("SELECT strftime('%j', 'now', 'localtime')")
Run Code Online (Sandbox Code Playgroud)

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

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

任何帮助表示赞赏。

Mar*_*ler 5

正如我在这里已经解释过的那样,UNIX时间的转换是这样的:

SELECT DATE(dateColumn, 'unixepoch') AS isodate FROM tableName
Run Code Online (Sandbox Code Playgroud)

或从新纪元开始存储毫秒数以来,这对于Android Java很常见:

SELECT DATE(ROUND(dateColumn / 1000), 'unixepoch') AS isodate FROM tableName
Run Code Online (Sandbox Code Playgroud)

这不需要在中进行任何乘法或除法TypeConverter。而这个乘法/除法操作数1_000TypeConverter我看来很奇怪。

the issue here might be exactly the same as with pure SQL ... that date.getTime() / 1000 in 999/1000 of cases could only be represented as a float value and not a straight long integer value - unless rounding that value to a long integer value. ROUND(dateColumn / 1000) would prevent this by SQL. somehow this question lacks the context; please comment below which particular value you'd need to obtain - and why you'd need to obtain it; then I might be able to extend my answer - because I don't really understand the purpose of getting the day of the year for a purchase. I'd rather would expect it to be days elapsed since a purchase.