我在生产中有一个奇怪的问题:有一天,Java.util.Date字段被完全随机地减少了。It 很少发生,但有时出了问题,生产中的日期减少了。
试图创建自定义序列化程序和反序列化程序没有帮助。
以下是代码:
// UserData class
package mypackage;
import myotherpackage.DataDefaultPatternDeserializer;
import myotherpackage.DataDefaultPatternSerializer;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import lombok.Data;
import java.util.Date;
@Data
public class UserData {
//Random problems in production - date decreased by one day
@JsonSerialize(using = DataDefaultPatternSerializer.class)
@JsonDeserialize(using = DataDefaultPatternDeserializer.class)
private Date dateOfBirth;
}
// ----------------------------------------------------------------------------------------
// DataDefaultPatternSerializer class
package myotherpackage;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import java.io.IOException;
import java.util.Date;
import java.util.Locale;
import org.joda.time.DateTime;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;
public class DataDefaultPatternSerializer extends JsonSerializer<Date> {
public DataDefaultPatternSerializer() {
}
public void serialize(Date date, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
DateTimeFormatter formatter = DateTimeFormat.forPattern("yyyyMMdd").withLocale(Locale.ITALY);
jsonGenerator.writeString(formatter.print(new DateTime(date)));
}
}
// ----------------------------------------------------------------------------------------
// DataDefaultPatternDeserializer class
package myotherpackage;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import java.io.IOException;
import java.util.Date;
import java.util.Locale;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;
public class DataDefaultPatternDeserializer extends JsonDeserializer<Date> {
public DataDefaultPatternDeserializer() {
}
public Date deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException {
DateTimeFormatter formatter = DateTimeFormat.forPattern("yyyyMMdd").withLocale(Locale.ITALY);
String dateString = jsonParser.getText();
return formatter.parseDateTime(dateString).toDate();
}
}
有解决办法吗?
发布于 2022-03-18 15:03:43
错误类型
不要使用任何一个Date
类。这些可怕的类几年前被定义在JSR 310中的现代java.time类所取代。
此外,java.util.Date
代表的是一个时刻,一天中时间的日期,如UTC所见,其偏移量为零点击-分钟-秒.你试着把一个日期值(出生日期)放进一个有时间的UTC类型中.
时区
出现在您的java.util.Date
上的日期和时间发生变化的原因是,该类有许多设计缺陷,其中一个toString
方法在生成文本时动态地应用JVM当前的默认时区。当将一个时刻调整到另一个时区时,一天的时间甚至日期都可能“改变”。现在,在我写这篇文章的时候,它是“明日”在日本东京,同时也是“昨天”在美国俄亥俄州的托莱多。
日本东京,2022-03-19星期六上午05:53:08 美国俄亥俄州托莱多今天下午04:53:08在2022-03-18星期五
解决此问题的最佳解决方案是:(a)不使用遗留的java.util.Date
类;(b)不使用UTC中有时间的日期类型来表示仅日期的值。
java.time.LocalDate
对于出生日期,只使用日期类型LocalDate
。
LocalDate ld = LocalDate.parse( "1969-01-23" ) ;
若要生成标准ISO 8601格式的文本,请调用toString
。
String outputISO8601 = ld.toString() ;
串行化
将日期-时间值序列化为文本时,请使用ISO 8601格式。
Jackson支持java.time类型。
数据库
在类似SQL标准类型DATE
的类型的列中写入数据库。
myPreparedStatement.setObject( … , ld ) ;
检索。
LocalDate ld = myResultSet.getObject( … , LocalDate.class ) ;
https://stackoverflow.com/questions/71528721
复制相似问题