发布
社区首页 >问答首页 >Java - Date减少了一天随机序列化和反序列化该日期。

Java - Date减少了一天随机序列化和反序列化该日期。
EN

Stack Overflow用户
提问于 2022-03-18 14:40:06
回答 1查看 259关注 0票数 0

我在生产中有一个奇怪的问题:有一天,Java.util.Date字段被完全随机地减少了。It 很少发生,但有时出了问题,生产中的日期减少了。

试图创建自定义序列化程序和反序列化程序没有帮助。

以下是代码:

代码语言:javascript
代码运行次数:0
复制
// 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();
    }
}

有解决办法吗?

EN

回答 1

Stack Overflow用户

发布于 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

代码语言:javascript
代码运行次数:0
复制
LocalDate ld = LocalDate.parse( "1969-01-23" ) ;

若要生成标准ISO 8601格式的文本,请调用toString

代码语言:javascript
代码运行次数:0
复制
String outputISO8601 = ld.toString() ;

串行化

将日期-时间值序列化为文本时,请使用ISO 8601格式。

Jackson支持java.time类型。

数据库

在类似SQL标准类型DATE的类型的列中写入数据库。

代码语言:javascript
代码运行次数:0
复制
myPreparedStatement.setObject( … , ld ) ; 

检索。

代码语言:javascript
代码运行次数:0
复制
LocalDate ld = myResultSet.getObject( … , LocalDate.class ) ;
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71528721

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档