android - 如何使用 Room 库正确使用 strftime 和 datetime?

标签 android sqlite android-sqlite android-room

我有一个实体 Memo 类。我使用 @TypeConverterGregorianCalendar 转换为 Long

备忘录.java

@Entity
public class Memo {
    @Ignore
    public static final int TYPE_EXPENSE = 0;
    @Ignore
    public static final int TYPE_INCOME = 1;

    @PrimaryKey(autoGenerate = true)
    public int id;

    public int type;
    @ColumnInfo(name = "item_name")
    public String itemName;
    @ColumnInfo(name = "category_name")
    public String categoryName;
    public String note;
    public double dollar;
    public GregorianCalendar date;
    public String photoPath;

    @Ignore
    public Memo(int type) {
        this.type = type;
        itemName = "";
        categoryName = "";
        note = "";
        dollar = 0d;
        date = new GregorianCalendar();
        photoPath = "";
    }

    public Memo() {
        this(TYPE_EXPENSE);
    }

    @Ignore
    @Override
    public String toString() {
        StringBuilder builder = new StringBuilder();
        builder.append("id = " + id);
        builder.append(", itemName = " + itemName);
        builder.append(", type = " + type);
        builder.append(", categoryName = " + categoryName);
        builder.append(", note = " + note);
        builder.append(", date = " + date.getTimeInMillis());
        return builder.toString();
    }
}

转换器.java

public class Converters {
    @TypeConverter
    public static GregorianCalendar fromTimestamp(Long value) {
        if (value == null)
            return new GregorianCalendar();
        else {
            GregorianCalendar calendar = new GregorianCalendar();
            calendar.setTimeInMillis(value);
            return calendar;
        }
    }

    @TypeConverter
    public static Long millisToTimestamp(GregorianCalendar calendar) {
        return calendar == null ? null : calendar.getTimeInMillis();
    }
}

我想获取数据库中的第一条和最后一条记录,并作为结果获取 MemosWithTimestamp 对象。

public class MemoWithTimestamp {
    public int year;
    public int month;
    @Embedded
    public Memo memo;

    @Ignore
    @Override
    public String toString() {
        StringBuilder builder = new StringBuilder();
        builder.append("year=" + year);
        builder.append(", month=" + month);
        builder.append(", memo=[ "+memo.toString()+"]");
        return builder.toString();
    }
}

查询方式:

    @Query("SELECT *, CAST(strftime('%Y', datetime(date)) AS int) AS year, CAST(strftime('%m', datetime(date)) AS int) AS month FROM memo ORDER BY date DESC LIMIT 1")
    MemoWithTimestamp getTheLastMemo();

    @Query("SELECT *, CAST(strftime('%Y', datetime(date)) AS int) AS year, CAST(strftime('%m', datetime(date)) AS int) AS month FROM memo ORDER BY date ASC LIMIT 1")
    MemoWithTimestamp getTheFirstMemo();

Logcat中数据库中的数据:

id = 1, itemName = memo-2015-1-0, type = 0, categoryName = , note = , date = 1422634536401 <=first
....
id = 197, itemName = memo-2017-12-9, type = 0, categoryName = , note = , date = 1515428136414 <=last

Logcat中查询后的结果:

firstMemo= year=0, month=0, memo=[ id = 1, itemName = memo-2015-1-0, type = 0, categoryName = , note = , date = 1422634536401]

lastMemo= year=0, month=0, memo=[ id = 197, itemName = memo-2017-12-9, type = 0, categoryName = , note = , date = 1515428136414]

但是无论有没有 CAST,年和月字段始终为 0。

如何解决这个问题?

最佳答案

你在这里错过了两件事:

1) datetime() 函数获得秒数,而您正在传递毫秒数。将值除以 1000。

2) 您应该将第二个参数作为 'unixepoch' 传递给 datetime() 函数。

因此,您的查询是这样固定的:

CAST(strftime('%Y', datetime(date/1000, 'unixepoch')) AS int) AS year

月份也一样:

CAST(strftime('%m', datetime(date/1000, 'unixepoch')) AS int) AS month 

关于android - 如何使用 Room 库正确使用 strftime 和 datetime?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48134403/

相关文章:

ios - 批量 NSArray 写入 SQLite

php - 无法从 PHP 页面更新 sqlite3 数据库

Android SQLite 泄漏问题

android - 如何使用日期字段过滤 ActiveAndroid Delete 语句

android - 从图像或 <LinearLayout>/<GridView> 等创建平铺背景

android - 在 Android 中获取位图的 RGB 值

java - Android WiFi 状态未知

java - android.database.CursorIndexOutOfBoundsException : Index -1 requested, 大小为 7

android - 查询不同格式的 SQLite 日期

java - Gstreamer 还是 VLC?对于桌面和移动平台?