【发布时间】:2013-10-22 15:53:32
【问题描述】:
我需要将 UTC 区域中的日期/时间存储到 MySQL 数据库中(DATETIME 类型的列)。当用户输入日期时,它首先由 JSF 转换器转换为 org.joda.time.DateTime。
在将此日期插入 MySQL 数据库之前,需要再次将其转换为 java.util.Date - 感谢 EclipseLink。
以下是再次将org.joda.time.DateTime 转换为java.util.Date 的转换器,但实际上并不需要查看此转换器。
package joda.converter;
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;
import org.joda.time.DateTimeZone;
public final class JodaDateTimeConverter implements Converter
{
private static final long serialVersionUID = 1L;
@Override
public Object convertObjectValueToDataValue(Object objectValue, Session session)
{
return objectValue instanceof DateTime?((DateTime) objectValue).withZone(DateTimeZone.UTC).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收到的值是由Joda-Time在JSF转换器中转换的正确的UTC日期/时间。
例如,如果我输入了一个日期 - 02-Oct-2013 11:34:26 AM,那么 objectValue 的值将是 - 2013-10-02T06:04:26.000Z。这个日期/时间应该被插入到数据库中。
但是当这个值被这个表达式 - (DateTime) objectValue).withZone(DateTimeZone.UTC).toDate() 转换时,它再次被评估为2013-10-02 11:34:26.0 并且这个值被提供给不正确的数据库。
无论如何,如何将UTC时区设置为(DateTime) objectValue).withZone(DateTimeZone.UTC).toDate()?
org.joda.time.DateTime 类型的属性在模型类中指定如下。
@Column(name = "discount_start_date", columnDefinition = "DATETIME")
@Converter(name = "dateTimeConverter", converterClass = JodaDateTimeConverter.class)
@Convert("dateTimeConverter")
private DateTime discountStartDate;
编辑: (以下 JSF 转换器与上面保持不变的 EclipseLink 转换器按预期工作 - 从唯一的 answer 到现在由 BalusC)
这是我的 JSF 转换器。
package converter;
import java.util.TimeZone;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;
import javax.faces.convert.ConverterException;
import org.joda.time.DateTime;
import org.joda.time.DateTimeZone;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;
import util.Utility;
@ManagedBean
@RequestScoped
public final class DateTimeConverter implements Converter
{
@Override
public Object getAsObject(FacesContext context, UIComponent component, String value)
{
DateTime dateTime=null;
try
{
dateTime = DateTimeFormat.forPattern("dd-MMM-yyyy hh:mm:ss aa").withZone(DateTimeZone.forTimeZone(TimeZone.getTimeZone("IST"))).parseDateTime(value);
}
catch (IllegalArgumentException e)
{
throw new ConverterException(new FacesMessage(FacesMessage.SEVERITY_ERROR, "", Utility.getMessage("datetime.converter.error", DateTimeFormat.forPattern("dd-MMM-yyyy hh:mm:ss aa").print(DateTime.now().withZone(DateTimeZone.forID("Asia/Kolkata"))))), e);
}
catch(UnsupportedOperationException e)
{
throw new ConverterException(new FacesMessage(FacesMessage.SEVERITY_ERROR, "", Utility.getMessage("datetime.converter.error", DateTimeFormat.forPattern("dd-MMM-yyyy hh:mm:ss aa").print(DateTime.now().withZone(DateTimeZone.forID("Asia/Kolkata"))))), e);
}
return dateTime;
}
@Override
public String getAsString(FacesContext context, UIComponent component, Object value)
{
DateTimeFormatter dateTimeFormatter=DateTimeFormat.forPattern("dd-MMM-yyyy hh:mm:ss aa").withZone(DateTimeZone.forID("Asia/Kolkata")); //This zone will be tackled/handled later from the database to display.
return value instanceof DateTime?dateTimeFormatter.print((DateTime)value):null;
}
}
【问题讨论】:
-
UTF?也许UTC,时间戳通常已经在UTC,所以问题只是在从毫秒到字符串的转换过程中,为此检查stackoverflow.com/questions/7670355/…,同时检查正确的数据库时区设置
-
抱歉,它是 UTC - 困打字。
-
我无法返回
Calendar对象。当数据被提供给数据库时,它应该返回java.sql.Timestamp。这就是 JPA 映射的工作原理。 -
您在哪里看到数据库包含无效值?
-
当我通过 PrimeFaces 日历输入像
02-Oct-2013 11:34:26 AM这样的日期时,插入数据库的日期/时间与从日历中选择的日期/时间相同 -2013-10-02 11:34:26。转换为 UTC 后应该是2013-10-02T06:04:26.000Z。不应该吗?我错了吗?
标签: jsf timezone eclipselink converter jodatime