如何使用EclipseLink和Joda-Time将UTC中的日期时间存储到数据库中? [英] How to store date-time in UTC into a database using EclipseLink and Joda-Time?

查看:92
本文介绍了如何使用EclipseLink和Joda-Time将UTC中的日期时间存储到数据库中?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

很长时间以来,我一直在使用以下EclipseLink Joda-Time 转换器,将日期时间存储在 UTC 到MySQL数据库中完全没有成功.

I have been fumbling with the following EclipseLink Joda-Time converter for a long time to store date-time in UTC into MySQL database with no success at all.

import java.util.Date;
import org.eclipse.persistence.mappings.DatabaseMapping;
import org.eclipse.persistence.mappings.converters.Converter;
import org.eclipse.persistence.sessions.Session;
import org.joda.time.DateTime;

public final class JodaDateTimeConverter implements Converter {

    private static final long serialVersionUID = 1L;

    @Override
    public Object convertObjectValueToDataValue(Object objectValue, Session session) {
        //Code to convert org.joda.time.DateTime to java.util.Date in UTC.
        //Currently dealing with the following line
        //that always uses the system local time zone which is incorrect.
        //It should be in the UTC zone.
        return objectValue instanceof DateTime ? ((DateTime) objectValue).toDate() : null;
    }

    @Override
    public Object convertDataValueToObjectValue(Object dataValue, Session session) {
        return dataValue instanceof Date ? new DateTime((Date) dataValue) : null;
    }

    @Override
    public boolean isMutable() {
        return true;
    }

    @Override
    public void initialize(DatabaseMapping databaseMapping, Session session) {
        databaseMapping.getField().setType(java.util.Date.class);
    }
}

convertObjectValueToDataValue()方法的objectValue参数是instanceOf DateTime,该参数已经根据UTC区域设置.因此,我避免使用.withZone(DateTimeZone.UTC).

The objectValue parameter of the convertObjectValueToDataValue() method is an instanceOf DateTime which is already according to UTC zone. Therefore, I have avoided .withZone(DateTimeZone.UTC).

客户端上已经存在一个单独的转换器,该转换器将日期时间的String表示形式转换为UTC中的org.joda.time.DateTime,然后再将其发送到EJB.)

There is already a separate converter on the client that converts a String representation of date-time to org.joda.time.DateTime in UTC before sending it to EJBs).

convertObjectValueToDataValue()方法的return语句中的此((DateTime) objectValue).toDate()始终采用应位于UTC区域中的系统本地时区.

This ((DateTime) objectValue).toDate() in the return statement of the convertObjectValueToDataValue() method always takes the system local time zone that should be in the UTC zone.

应该根据UTC区域将任何日期时间插入MySQL.

Anyway date-time should be inserted into MySQL according to the UTC zone.

最好/理想的解决方案是,如果它处理Joda的日期时间类似于休眠

在模型类中,如下指定类型为org.joda.time.DateTime的属性.

A property of type org.joda.time.DateTime as an example is designated in a model class as follows.

@Column(name = "discount_start_date", columnDefinition = "DATETIME")
@Converter(name = "dateTimeConverter", converterClass = JodaDateTimeConverter.class)
@Convert("dateTimeConverter")
private DateTime discountStartDate; //Getter and setter.    

推荐答案

我没有得到这个问题,尤其是关于转换为java.util.Date将使用系统时区的声明.以下测试显示了另一种正确的行为:

I don't get the question and especially the statement that conversion to java.util.Date would use the system time zone. Following test shows a different and correct behaviour:

DateTime joda = new DateTime(2014, 3, 14, 0, 0, DateTimeZone.UTC);
Date d = joda.toDate();
System.out.println(joda.getMillis()); // 1394755200000
System.out.println(d.getTime()); // 1394755200000

当然,如果您打印Date变量d,则其toString()方法使用系统时区,但是对象jodad都表示相同的时刻,就像在表示形式中看到的一样.从UNIX时代UTC区域以来的毫秒数.

Of course, if you print the Date-variable d, then its toString()-method uses the system time zone, but the objects joda and d both represent the same instant as you can see in the representation of milliseconds since UNIX epoch in UTC-zone.

例如System.out.println(d);在我的时区生成此字符串:

For example System.out.println(d); produces this string in my time zone:

2014年3月14日星期五欧洲中部时间

Fri Mar 14 01:00:00 CET 2014

但这不是结果的内部状态,不会存储在数据库中,因此请不要感到困惑或担心.顺便说一句,您将需要根据数据库中的列类型将结果转换为java.sql.Date或java.sql.Timestamp.

But that is not the internal state of the result and will not be stored in database, so don`t be confused or worry about. By the way, you will need to convert the result to either java.sql.Date or java.sql.Timestamp depending on the column type in your database.

要确定UTC,您应该更改其他方法convertDataValueToObjectValue()并使用类似以下的显式转换:

To be sure about UTC you should change your other method convertDataValueToObjectValue() and use an explicit conversion like:

new DateTime((Date) dataValue, DateTimeZone.UTC)

否则(假设反向方法如您所说一直在UTC中始终具有DateTime对象),您可能会出现不对称现象(目前我不知道在没有DateTimeZone参数的情况下构造函数中JodaTime在这里做了什么-文献记载不充分?).

Otherwise (assuming that the reverse method has always DateTime-objects in UTC as you said) you might get an asymmetry (I don't know at this moment what JodaTime does here in constructor without DateTimeZone-argument - not so well documented?).

EDIT-2:

测试代码

DateTime reverse = new DateTime(d);
System.out.println(reverse); // 2014-03-14T01:00:00.000+01:00
System.out.println(reverse.getZone()); // Europe/Berlin

清楚地表明,没有第二个DateTimeZone参数的DateTime构造函数隐式使用系统时区(我不喜欢Joda或java.util.*中的此类隐式值).如果往返于UTC-DateTime对象的整个转换不起作用,那么我认为您输入的DateTime对象可能不是真正的UTC.我建议对此进行明确检查.否则,我们没有足够的信息说明为什么您的转换代码不起作用.

clearly shows that the DateTime-constructor without a second DateTimeZone-argument implicitly uses the system time zone (I don't like such implicits equal in Joda or in java.util.*). If the whole conversion forth and back from and to UTC-DateTime-objects does not work then I assume your input of DateTime-objects is maybe not really in UTC. I recommend to check this explicitly. Otherwise we have not enough informations about why your conversion code does not work.

这篇关于如何使用EclipseLink和Joda-Time将UTC中的日期时间存储到数据库中?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆