Ho bisogno di memorizzare data/ora nella zona UTC nel database MySQL (di una colonna di tipo DATETIME). Quando un utente immette una data, viene prima convertito in org.joda.time.DateTime
da un convertitore JSF.Come inserire data/ora nella zona UTC in MySQL tramite EclipseLink usando Joda-Time?
Prima di inserire questa data nel database MySQL, deve essere nuovamente convertita in java.util.Date
- grazie a EclipseLink.
Quanto segue è il convertitore che convertitori di nuovo da org.joda.time.DateTime
a java.util.Date
sebbene non sia realmente necessario per vedere questo convertitore.
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);
}
}
Nel metodo convertObjectValueToDataValue()
(il primo), il valore del primo parametro - objectValue
ricevuto è la corretta UTC data/ora convertito da Joda-Time in un convertitore JSF.
Ad esempio, se si immette una data - 02-Oct-2013 11:34:26 AM
, il valore di objectValue
sarà - 2013-10-02T06:04:26.000Z
. Questa data/ora dovrebbe essere inserita nel database.
Ma quando questo valore viene convertito da questa espressione - (DateTime) objectValue).withZone(DateTimeZone.UTC).toDate()
, viene nuovamente valutata a 2013-10-02 11:34:26.0
e questo valore viene fornito al database che non è corretto.
In ogni caso, come impostare la zona UTC su (DateTime) objectValue).withZone(DateTimeZone.UTC).toDate()
?
Una proprietà di tipo org.joda.time.DateTime
è designata in una classe modello come segue.
@Column(name = "discount_start_date", columnDefinition = "DATETIME")
@Converter(name = "dateTimeConverter", converterClass = JodaDateTimeConverter.class)
@Convert("dateTimeConverter")
private DateTime discountStartDate;
EDIT:(Il seguente convertitore JSF funziona come previsto con il convertitore EclipseLink di sopra del quale rimane intatta - dall'unico answer fino ad ora da BalusC)
Questo è il mio Convertitore 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? forse UTC, il timestamp è di solito già in UTC, quindi il problema è solo durante la conversione da millis a string, per questo controllo http://stackoverflow.com/questions/7670355/convert-date-time-for-given-timezone-java , inoltre, controlla l'impostazione corretta del fuso orario del database –
Scusa è UTC - digitazione insonnia. – Tiny
Non riesco a restituire un oggetto 'Calendar'. Dovrebbe restituire 'java.sql.Timestamp', quando i dati vengono forniti al database. Ecco come funzionano i mapping JPA. – Tiny