【问题标题】:Convert String to Date with null safety将字符串转换为具有空安全性的日期
【发布时间】:2021-11-05 11:38:09
【问题描述】:

我在 Room 中使用@TypeConverter 将字符串转换为日期(日期时间)。这是代码

public class DateTimeConverter {

    @TypeConverter
    public static Date stringToDate(String value) {
        DateFormat df = new SimpleDateFormat(Constants.SQLITE_DATE_TIMEFORMAT, Locale.US);
        if (value != null) {
            try {
                return df.parse(value);
            } catch (ParseException e) {
                e.printStackTrace();
            }
        }
        return null;
    }

    @TypeConverter
    public static String dateToString(Date value) {
        DateFormat df = new SimpleDateFormat(Constants.SQLITE_DATE_TIMEFORMAT, Locale.US);
        if (value != null) {
            return df.format(value);
        } else {
            return null;
        }
    }
}
@Entity
@TypeConverters(DateTimeConverter::class)
data class Entity(
    var writeDate: Date = Date() // java.util.Date
)

我目前的问题是

  1. stringtoDate 接收 value = null 导致 Entity.writeDate 为空,这是一个运行时异常

问题

  1. 如何将字符串转换为具有空安全性的日期?表中writeDate 的值永远不会为空,但stringToDate 仍会收到value = null

注意:

  1. 使用 SDK > 23. 所以不能使用DateTimeFormatter.ofPattern

【问题讨论】:

  • "表中 writeDate 的值永远不会为空,但 stringToDate 仍然收到 value = null" 那么 this 是问题所在,而不是“如何将字符串转换为日期与零安全”。
  • @Sweeper 是的。这就是问题。但我不知道为什么会这样。我尝试在 Android Studio 中运行 SQL 查询以识别带有 null 的 writeDate,但没有找到任何

标签: kotlin android-room


【解决方案1】:

表中writeDate的值永远不会为null,但是stringToDate仍然收到value = null。

您的问题是确定为什么 writeDate 被提取为 null 并且这将在使用 @Dao 注释的类中的函数中。

但是,您可以使用以下方法来确保永远不会返回空值:-

public class DateTimeConverter {

    @TypeConverter
    public static Date stringToDate(String value) {
        Date defaultDate = new Date(0); //1970-01-01 00:00:00
        DateFormat df = new SimpleDateFormat(Constants.SQLITE_DATE_TIMEFORMAT, Locale.US);
        if (value != null) {
            try {
                return df.parse(value);
            } catch (ParseException e) {
                e.printStackTrace();
            }
        }
        return defaultDate;
    }

    @TypeConverter
    public static String dateToString(Date value) {
        DateFormat df = new SimpleDateFormat(Constants.SQLITE_DATE_TIMEFORMAT, Locale.US);
        if (value != null) {
            return df.format(value);
        } else {
            return "1970-01-01 00:00:00";
        }
    }
}

这是一个将上述内容与以下内容结合使用的演示:-

@Dao 类 AllDao :-

@Dao
abstract class AllDao {

    @Insert(onConflict = IGNORE)
    abstract fun insert(entity: Entity)

    /* Delete all rows */
    @Query("DELETE FROM entity")
    abstract fun clear()

    /* get inserted data */
    @Query("SELECT * FROM entity")
    abstract fun getAllFromEntity(): List<Entity>

    /* purposefully get 2 invalid dates (1 rubbish date, 1 NULL) */
    @Query("SELECT -999 AS id,'invaliddate' AS writeDate UNION SELECT -123 AS id, NULL as writeDate")
    abstract fun getMessedUpDate(): List<Entity>

}
  • getMessedUpDate 旨在按照它所说的去做,并获取将导致问题中的 TypeConverters 为空但答案中修改后的 TypeConverters 为空的日期。

然后使用 :-

    db = TheDatabase.getInstance(this)
    dao = db.getAllDao()
    dao.clear()

    dao.insert(Entity())
    var dateInt = (System.currentTimeMillis()) 
    dao.insert(Entity(writeDate = Date(dateInt)))
    dao.insert(Entity(1000,Date((System.currentTimeMillis()) - (100 /*days*/ * 24 /*hours*/ * 60 /*mins*/ * 60 /*secs*/ * 1000))))

    for (e: Entity in dao.getAllFromEntity()) {
        Log.d("DBINFO","Date is ${e.writeDate} ID is ${e.id}")
    }
    for (e: Entity in dao.getMessedUpDate()) {
        Log.d("DBINFO","Date is ${e.writeDate} ID is ${e.id}")
    }

日志包括:-

2021-11-06 07:40:38.063 D/DBINFO: Date is Sat Nov 06 07:40:38 GMT+11:00 2021 ID is 1
2021-11-06 07:40:38.064 D/DBINFO: Date is Sat Nov 06 07:40:38 GMT+11:00 2021 ID is 2
2021-11-06 07:40:38.064 D/DBINFO: Date is Fri Nov 05 17:46:12 GMT+11:00 2021 ID is 1000
2021-11-06 07:40:38.069 D/DBINFO: Date is Thu Jan 01 10:00:00 GMT+10:00 1970 ID is -999
2021-11-06 07:40:38.069 D/DBINFO: Date is Thu Jan 01 10:00:00 GMT+10:00 1970 ID is -123
  • 即第 4 行和第 5 行返回了“默认日期”而不是 null。

【讨论】:

  • 知道了。我已经在代码中进行了此更改(默认日期),但这并不能解决我从数据库读取的空日期问题。我将探讨为什么会发生这种情况,并在需要时提出不同的问题。感谢您的帮助。
猜你喜欢
  • 2011-09-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-12-06
  • 2020-09-16
  • 2015-04-27
相关资源
最近更新 更多