【问题标题】:Android Room get all times of todays insertAndroid Room 获取今天插入的所有时间
【发布时间】:2020-11-18 07:26:07
【问题描述】:

我正在尝试在用户开始特定活动和结束活动时保存数据,我想计算用户在这一天/一周/一个月花费了多少小时

我在提取此信息时遇到问题。

这是我的桌子:

    @Entity(tableName = "daily_activity_time_table")
     data class TimeTrack(


        @PrimaryKey(autoGenerate = true)
        var activityId: Long = 0L,

        @ColumnInfo(name = "start_time")     
        val startTimeMilli: Date = Date(System.currentTimeMillis()),  //i didnt find a better way to save date and time

        @ColumnInfo(name = "end_time")
        var endTimeMilli: Date = startTimeMilli,

        @ColumnInfo(name = "quality_rating")
        var sleepQuality: Int = -1
)

例如,我需要一个查询来获取今天小时数的总和,我尝试做这样的事情:

@Query("SELECT SUM(end_time-start_time) from daily_activity_time_table where start_time = date('now') ")
        fun getTodayTime(): Long

我可以使用这个转换器将日期和时间打印到屏幕上:

@SuppressLint("SimpleDateFormat")
fun convertLongToDateString(systemTime: Long): String {
    return SimpleDateFormat("EEEE MMM-dd-yyyy' Time: 'HH:mm")
        .format(systemTime).toString()
}

但无法找到打印用户使用活动的所有时间的方法今天

【问题讨论】:

  • 好吧,因为你的开始时间包含分钟和秒,它永远不会等于现在。您必须将其转换为 yyyy-mm-dd 格式以忽略时间而只保留日期。此外,开始日期只有一个时间,而不是您刚刚运行getMillis 的日期。请提供您想要的数据结构和插入新条目的代码
  • @Raghunandan 我添加了转换器,但我不知道它们如何帮助我提取今天的所有活动
  • @AviadHitner 通过编写适当的 sql 查询。转换器用于将日期转换为 long 和 long back to date,当您将它与数据类一起使用时。

标签: android date kotlin android-sqlite android-room


【解决方案1】:

我做了一个小型且非常简化的项目,展示了如何从Room 中提取数据,按日期范围(表示为自纪元以来的毫秒数)

https://github.com/or-dvir/RoomDate

请注意,这不是设置Room 数据库的正确方法,并且此方法有其局限性(例如,它不考虑时区)。

【讨论】:

    【解决方案2】:

    就我个人而言,我只会保留用于存储和检索持久数据的空间,并将整个计算部分放在不同的地方(即您的 ActivityViewModel 或存储库)

    类似

    @Entity
    class TimeTrack(
        @PrimaryKey
        val id: Int,
        val startTime: Long,
        val endTime: Long,
        val sleepQuality: Int = -1
    ){
        val totalTime: Long
            get() = endTime - startTime
        
        // maybe this as well, gets the Local Date as LocalDate in case you want to filter by that
        val startDate: LocalDate
            get() = LocalDate.ofInstant(Instant.ofEpochSecond(startTime), ZonedDateTime.now().offset)
    }
    
    @Dao
    interface TimeTrackDao {
        @Query("SELECT * FROM TimeTrack")
        suspend fun getTimeTracks(): List<TimeTrack>
    
        @Query("SELECT MAX(id) FROM TimeTrack ")
        suspend fun highestID(): Int
    
        @Insert(onConflict = OnConflictStrategy.REPLACE)
        suspend fun save(vararg consensus: TimeTrack)
    }
    

    然后在获得活动的开始和停止时间后:

        // this gives a nice unambiguous timestamp
        val startTime = Instant.now().epochSecond
        val stopTime = Instant.now().epochSecond
        val tt = TimeTrack(timeTrackDao.highestID()+1,
                           startTime,
                           stopTime,
                           sleepQuality = -1)
        timeTrackDao.save(tt)
    
        fun totalTimeSpentAt(timeTrackList: List<TimeTrack>): Duration = Duration.ofSeconds(timeTrackList.map{it.totalTime}.sum())
    
    

    【讨论】:

    • 我遇到了 .toLocalDate 的问题,它不允许我将其用作“ofEpochSecond”的方法
    • 对不起,我把它作为扩展功能。在我滥用快速测试的项目上。 LocalDate.ofInstant(Instant.ofEpochSecond(startTime), ZonedDateTime.now().offset) 应该可以工作
    猜你喜欢
    • 1970-01-01
    • 2018-02-05
    • 1970-01-01
    • 1970-01-01
    • 2016-04-03
    • 2017-02-18
    • 1970-01-01
    • 2020-09-28
    • 2012-10-19
    相关资源
    最近更新 更多