Tin*_*iny 6 jsf timezone converter jodatime eclipselink
我需要将UTC区域中的日期/时间存储到MySQL数据库(DATETIME类型列)中.当用户输入日期时,它首先org.joda.time.DateTime由JSF转换器转换为.
在将此日期插入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);
}
}
Run Code Online (Sandbox Code Playgroud)
在convertObjectValueToDataValue()方法(第一个)中,第一个参数的值 - objectValue接收的是JUD-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;
Run Code Online (Sandbox Code Playgroud)
编辑:( 以下JSF转换器按预期工作,上面的EclipseLink转换器保持不变 - 从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;
}
}
Run Code Online (Sandbox Code Playgroud)
您的具体问题是因为DateTime#toDate()在转换期间不使用时区而引起的java.util.Date. 它基本上返回new Date(millis)其中millis是内部存储的实例纪元时间,与javadoc所描述的和构造函数DateTime所要求的完全一样。DateTimejava.util.Date
换句话说,该withZone(DateTimeZone.UTC)部分在这里完全没有作用。该代码的行为与该部分不存在时完全相同。这就解释了为什么您最终会得到最初输入的时间。
从技术上讲,问题出在您的自定义 JSF 转换器中,该转换器String将DateTime. 该转换器显然没有考虑时区,并假设输入已经在 GMT 时区(默认情况下)。必须指示转换器输入处于 IST 时区。如果您在标准 JSF 中使用标准java.util.Date属性<f:convertDateTime>,那么您可以通过将其timeZone属性设置为来解决这个问题IST。
<h:inputText value="#{bean.date}">
<f:convertDateTime pattern="dd-MMM-yyyy hh:mm:ss a" locale="en" timeZone="IST" />
</h:inputText>
Run Code Online (Sandbox Code Playgroud)
您的自定义 JSF 转换器应该在幕后执行完全相同的操作:告诉 API 所提供的内容String位于 IST 时区,而不是让它假设它已经位于 GMT 时区。您没有在任何地方显示自定义 JSF 转换器,因此很难提供准确的答案,但它应该归结为以下启动示例:
String inputDateString = "02-Oct-2013 11:34:26 AM";
String inputDatePattern = "dd-MMM-yyyy hh:mm:ss a";
TimeZone inputTimeZone = TimeZone.getTimeZone("IST");
DateTime dateTime = DateTimeFormat
.forPattern(inputDatePattern)
.withZone(DateTimeZone.forTimeZone(inputTimeZone))
.parseDateTime(inputDateString);
Run Code Online (Sandbox Code Playgroud)
生成的DateTime实例最终将具有正确的内部纪元时间(以毫秒为单位)。
| 归档时间: |
|
| 查看次数: |
2706 次 |
| 最近记录: |