【问题标题】:Using JodaTime (DateTime, Duration) with ORMLite on Android在 Android 上将 JodaTime (DateTime, Duration) 与 ORMLite 一起使用
【发布时间】:2016-03-26 09:42:01
【问题描述】:

我正在寻找一种方法来将 DateTime 对象和 Duration 作为我的值对象的一部分。

这是我的价值对象:

@DatabaseTable(tableName = DrivingRecord.TableName)
public class DrivingRecord {
    public final static String TableName = "drivingRecord";
    public final static String DRIVING_TASK_COLUMN_NAME = "drivingTask";

    @DatabaseField(foreign = true, columnName = DRIVING_TASK_COLUMN_NAME)
    private DrivingTask drivingTask;

    @DatabaseField(generatedId = true)
    private int id;

    @DatabaseField(dataType = DataType.LONG)
    private DateTime startTime;

    @DatabaseField
    private Duration durationOfDriving;
}

我得到以下异常:

java.lang.IllegalArgumentException: Field class org.joda.time.Duration for field FieldType:name=durationOfDriving,class=DrivingRecord is not valid for type com.j256.ormlite.field.types.LongType@41223060, maybe should be long

在尝试为 DateTime 创建条目时,我也遇到了同样的异常

【问题讨论】:

    标签: android jodatime ormlite


    【解决方案1】:
    java.lang.IllegalArgumentException: Field class org.joda.time.Duration for
        field FieldType:name=durationOfDriving,class=DrivingRecord is not valid for
        type com.j256.ormlite.field.types.LongType@41223060, maybe should be long
    

    此消息试图告诉您Duration 字段durationOfDriving 与日期类型DataType.LONG 不兼容。我不确定您发布的代码是否不正确,但我原以为您会尝试这样做:

    @DatabaseField(dataType = DataType.LONG)
    private Duration durationOfDriving;
    

    ORMLite 原生支持DateTime,但不支持持久化Duration。只是试图强迫它长是行不通的。您将不得不为Duration 定义一个客户持久化器。

    查看documentation on custom persisters 了解如何启动您自己的持久化器。

    您还可以查看此答案以获取另一个示例:Is there any way to disable ORMLite's check that a field declared with DataType.SERIALIZABLE implements Serializable?

    【讨论】:

    • LocalDateTime 怎么样?我必须为此编写一个自定义持久化器吗?
    • @simonides LocalDateTime 不受支持并引发错误。如果您想将 Jodatime 与 ORMLite 一起使用,请改用 DateTime
    【解决方案2】:

    这里显示我能够解决问题。使时间戳变长,并保存时区。现在我可以根据需要搜索时间戳。

    @DatabaseTable(tableName = DrivingRecord.TableName)
    public class DrivingRecord {
        public final static String TableName = "drivingRecord";
        public final static String DRIVING_TASK_COLUMN_NAME = "drivingTask";
    
        @DatabaseField(foreign = true, columnName = DRIVING_TASK_COLUMN_NAME)
        private DrivingTask drivingTask;
    
        @DatabaseField(generatedId = true)
        private int id;
    
        @DatabaseField(dataType = DataType.LONG)
        private long startTime;
    
        @DatabaseField
        private Duration durationOfDriving;
    
        @DatabaseField(canBeNull = false, dataType= DataType.SERIALIZABLE)
        private DateTimeZone timeZone;
    
        public void setDateTime(DateTime dateTime){
            this.startTime = startTime.getMillis();
            this.timeZone = startTime.getZone();
        }
    
        public DateTime getDateTime(){
            return new DateTime(startTime, timeZone);
        }
    
    }
    

    【讨论】:

      【解决方案3】:

      虽然 JodaTime 不适用于 ORMLite,但您可以使用适用于 ORMLite 的 Java Date。 您还可以通过多种方式在 JodaTime 和 Date 之间进行转换。

      @DatabaseField
      protected Date createdAt;
      
      public static String formatDateTime(DateTime dateTime1) {
          if (dateTime1 == null || dateTime1.getYear() == 0) {
              return "";
          }
          DateFormat df = DateFormat.getDateInstance(DateFormat.SHORT, ApplicationBase.AppContext.getResources().getConfiguration().locale);
          Calendar calendar02 = new GregorianCalendar(dateTime1.getYear(), dateTime1.getMonthOfYear() - 1, dateTime1.getDayOfMonth());
          Date date3 = calendar02.getTime();
          String date3str = DataItemBase.formatDate(date3);
          return date3str;
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-11-18
        • 2013-02-24
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多