You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Room数据库中转换yyyy-mm-dd字符串日期为Long并执行范围查询?

解决Room中yyyy-MM-dd字符串日期无法比较的问题

核心思路

把手动输入的yyyy-MM-dd格式字符串转换为**时间戳(Long类型)**存储,利用Long的数值特性实现日期范围查询。下面是具体的TypeConverter实现和使用步骤:

1. 实现TypeConverter类

Java版本

import androidx.room.TypeConverter;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;

public class DateConverter {
    // 固定匹配输入的日期格式
    private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd", Locale.ENGLISH);

    // 将yyyy-MM-dd字符串转为当天0点的时间戳
    @TypeConverter
    public static Long stringToLong(String dateStr) {
        if (dateStr == null || dateStr.isEmpty()) {
            return null;
        }
        try {
            Date date = DATE_FORMAT.parse(dateStr);
            return date != null ? date.getTime() : null;
        } catch (ParseException e) {
            // 格式错误时抛出异常,也可根据业务需求返回默认值
            throw new IllegalArgumentException("Invalid date format: " + dateStr, e);
        }
    }

    // 将时间戳转回yyyy-MM-dd字符串
    @TypeConverter
    public static String longToString(Long timestamp) {
        if (timestamp == null) {
            return null;
        }
        Date date = new Date(timestamp);
        return DATE_FORMAT.format(date);
    }
}

Kotlin版本

import androidx.room.TypeConverter
import java.text.ParseException
import java.text.SimpleDateFormat
import java.util.*

class DateConverter {
    private val dateFormat = SimpleDateFormat("yyyy-MM-dd", Locale.ENGLISH)

    @TypeConverter
    fun stringToLong(dateStr: String?): Long? {
        dateStr ?: return null
        return try {
            val date = dateFormat.parse(dateStr)
            date?.time
        } catch (e: ParseException) {
            throw IllegalArgumentException("Invalid date format: $dateStr", e)
        }
    }

    @TypeConverter
    fun longToString(timestamp: Long?): String? {
        timestamp ?: return null
        val date = Date(timestamp)
        return dateFormat.format(date)
    }
}

若使用Java 8+或Android API 26+,推荐用线程安全的DateTimeFormatter替代SimpleDateFormat:

import java.time.LocalDate;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.time.Instant;

// 字符串转时间戳
LocalDate localDate = LocalDate.parse(dateStr, DateTimeFormatter.ISO_LOCAL_DATE);
return localDate.atStartOfDay(ZoneId.systemDefault()).toInstant().toEpochMilli();

// 时间戳转字符串
LocalDate localDate = Instant.ofEpochMilli(timestamp).atZone(ZoneId.systemDefault()).toLocalDate();
return localDate.format(DateTimeFormatter.ISO_LOCAL_DATE);

2. 在Room数据库类中注册转换器

在你的Room Database类上添加注解,让Room识别并使用该转换器:

import androidx.room.Database;
import androidx.room.RoomDatabase;
import androidx.room.TypeConverters;

@Database(entities = {YourEntity.class}, version = 1)
@TypeConverters(DateConverter.class)
public abstract class AppDatabase extends RoomDatabase {
    public abstract YourDao yourDao();
}

3. 修改实体类字段类型

把原来的String类型日期字段改为Long类型:

@Entity(tableName = "your_table")
public class YourEntity {
    @PrimaryKey(autoGenerate = true)
    public int id;
    // 替换原String类型为Long
    public Long date;
    // 其他字段...
}

4. 执行日期范围查询

直接通过Long的数值比较实现起止日期筛选:

// DAO中的查询方法
@Query("SELECT * FROM your_table WHERE date BETWEEN :startTimestamp AND :endTimestamp")
List<YourEntity> getEntitiesBetweenDates(Long startTimestamp, Long endTimestamp);

调用时,先将用户输入的yyyy-MM-dd字符串通过DateConverter.stringToLong()转成时间戳,再传入DAO方法即可。

内容的提问来源于stack exchange,提问作者jakeprog123

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 07:26:05