【问题标题】:Android Room - Returning last 30 days (1 month) - javaAndroid Room - 最近 30 天(1 个月)返回 - java
【发布时间】:2018-08-29 12:01:25
【问题描述】:

我是 Android 开发的初学者,但遇到了一个相当简单的问题(我猜是;))。

我正在尝试从 SQLite(使用 Room)检索过去 30 天的记录。

这是我的查询,它不起作用 - 它不返回任何记录(来自 @Dao 类):

 // getting fares for one day (custom-made query)
@Query("SELECT * FROM fare WHERE createdDateDb >=datetime('now', 'now', '-30 day')")
public List<Fare> getFaresOneDay();

但是,这个检索所有没有指定日期的记录的简单查询确实有效:

 // getting all fare (via custom-made query)
@Query("SELECT * FROM fare ORDER BY createdDateDb DESC")
public List<Fare> getAllFares();

这是我的 DateTypeConverter 类:

public class DateTypeConverter {

    @TypeConverter
    public long convertDateToLong(Date date) {
        return date.getTime();
    }

    @TypeConverter
    public Date convertLongToDate(long time) {
        return new Date(time);
    }

}

这是将值分配给 createdDateDb 的方式(在将其插入数据库之前):

fare.setCreatedDateDb(new Date());

这是我的“实体”类:

@Entity(tableName = "fare")
public class Fare {
    private String fareValue;
    private String typeOfJob;

    @PrimaryKey(autoGenerate = true) @NonNull
    private Integer jobId;

    // dates used for user display
    private String createdDate;
    private String createdTime;

    // date var used for comparisons - not to be displayed for the user
    private Date createdDateDb;
}

还有 createdDateDb 的 setter 和 getter

// #6 createdDateDb getter
public Date getCreatedDateDb() {
    return createdDateDb;
}

// #6 createdDateDb setter
public void setCreatedDateDb(Date createdDateDb) {this.createdDateDb = createdDateDb; }

我真的很感激一些提示如何处理它,因为感觉就像我无处可去。 我还尝试了以下方法:

SELECT * 
FROM fare 
WHERE createdDateDb BETWEEN datetime('now', 'start of month') AND datetime('now', 'localtime')

不幸的是,它也不起作用。

谢谢!

【问题讨论】:

    标签: java android sqlite android-room


    【解决方案1】:

    我遇到了这个问题,但我试图从 1 年前开始注册,当我搜索解决方案时,我发现了这篇文章。我是这样解决的

    SELECT * FROM my_table WHERE CAST(my_date/1000 AS LONG) >= strftime('%s', 'now', '-12 month')
    

    使用 calendar.getTime() 存储数据(以毫秒为单位)

    解释:

    由于 strftime 函数返回 SECONDS 的值,我必须将我的 milisseconds 值除以 1000 并将其转换为 long,因为 sql 将除法的结果作为 INTEGER 返回,然后它才能正常工作

    【讨论】:

      【解决方案2】:

      使用DATESQLITE 函数

      @Query("SELECT * FROM fare WHERE createdDateDb >= DATE('now', '-30 day')")
      

      【讨论】:

      • 在这种情况下,您不会总是得到最后 30 天,但 dateadd 是要走的路
      • 感谢迈克尔您的意见,但正如我在回答 Mihai 帖子的其他评论中提到的那样 - 此解决方案也不起作用。当我从查询中删除 'WHERE createdDateDb >=DATE('now', '-30 day')") - 它按预期返回所有记录。这可能与日期的存储方式有关在 createdDateDb 中还是 DateTypeConverter 中的一些错误?我被困在这个 ;)。到目前为止,感谢您的帮助。
      【解决方案3】:
      datetime('now', 'now', '-30 day')
      

      上面这个返回null,正确使用

      @Query("SELECT * FROM fare WHERE createdDateDb >=datetime('now', '-30 day')")
      

      【讨论】:

      • 我也试过了,数据库没有返回结果。我再次检查了代码 - 看看是否有一些随机错误 - 没有运气,但是当我将查询更改为与我在第一篇文章中发布的相同的查询时:getAllFares() - 该方法有效。还有更多建议如何找出问题所在并解决问题吗?感谢大家迄今为止的帮助 - 我真的很感激!
      【解决方案4】:

      我发现了导致查询无法按预期工作的原因 - 存储在 createdDateDb 中的日期格式,即假设我们现在添加票价,它将以下列方式保存: 格林威治标准时间 8 月 29 日星期三 16:48:55 +01:00 2018

      当我将 Date 在 createdDateDb 中的存储方式更改为 (yyyy-MM-dd) 时 - 查询神奇地按预期工作;)。

                  Date c = Calendar.getInstance().getTime();
                  SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
                  String formattedDate = sdf.format(c);
      

      非常感谢你们的帮助 - 我真的很感激!

      【讨论】:

      • 顺便考虑一下扔掉长期过时且臭名昭著的麻烦SimpleDateFormat和朋友,并将ThreeTenABP添加到您的Android项目中,以便使用java.time,现代Java日期和时间API .使用起来感觉好多了。
      【解决方案5】:

      对于未来寻找答案的人,这是我的解决方案: (strftime('%s','now') - createdDateDb) &lt; CAST(strftime('%s','1970-01-30') AS INTEGER)WHERE 子句中

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-07-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多