java - GSON 默认日期序列化器是特定于语言环境的

标签 java json date gson utc

在我的 java 应用程序中,我使用 REST API 以 JSON 格式返回数据,并注意到这个特定的 API 以一种特殊的方式格式化它的日期: “2019 年 11 月 1 日”,但问题是服务器上的实际日期是“2019-11-02”。这意味着我正在将日期最小化为之前的日期。我的服务器位于另一个国家。下面是完整的 json我格式化后得到的。

jsonAccts [{"id":8,"userId":2,"departmentId":45,"effectiveFrom":"Jun 9, 2019","endsOn":"Nov 1, 2019","createdBy":2,"createdOn":"2019-11-02 05:34:11"}]

所有日期字段都有这个问题。我有什么解决方案。我需要根据 REST API 请求在数据库上获取相同的日期。 下面是我用于 gson 格式化的代码。

    Gson gson;
    GsonBuilder builder;
    SimpleDateFormat dtf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.ENGLISH);
    SimpleDateFormat dtfDate=new SimpleDateFormat("yyyy-MM-dd", Locale.ENGLISH);
    String jsonAccts = null;
    try{
        builder = new GsonBuilder();
        builder.registerTypeAdapter(Timestamp.class, new JsonSerializer<Timestamp>() {
            @Override
            public JsonElement serialize(Timestamp src, Type typeOfSrc, JsonSerializationContext context) {
                dtf.setTimeZone(TimeZone.getTimeZone("UTC"));
                String jsDate = dtf.format(src);
                return new JsonPrimitive(jsDate);
            }
        });
        gson = builder.create();
        List<ClassTeacher> allActPgmMap = new ArrayList<ClassTeacher>();
        allActPgmMap = springDao.getClassTeacherList(Integer.parseInt(deptId));
        Type listType = new TypeToken<List<ClassTeacher>>() {}.getType();
        jsonAccts = gson.toJson(allActPgmMap, listType);
    }catch(Exception e){
        e.printStackTrace();
    }
    return jsonAccts;

下面是 ClassTeacher 类。

import javax.persistence.*;
    import java.io.Serializable;
    import java.sql.Timestamp;
    import java.util.Date;

    @Entity
    @Table(name = "class_teacher")
    public class ClassTeacher implements Serializable,Comparable {

        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        @Column(name = "id")
        private long id;

        @Column(name = "user_id")
        private long userId;

        @Column(name = "department_id")
        private long departmentId;

        @Column(name = "effective_from")
        @Temporal(TemporalType.DATE)     
        private Date effectiveFrom;

        @Column(name = "ends_on")
        @Temporal(TemporalType.DATE)     
        private Date endsOn;

        @Column(name="created_by")
        private long createdBy;

        @Column(name="created_on")
        private Timestamp createdOn;

        public ClassTeacher() {

        }

        public ClassTeacher(long id, long departmentId, long userId, Date effectiveFrom, Date endsOn, long createdBy, Timestamp createdOn) {
            this.id = id;
            this.departmentId = departmentId;
            this.userId = userId;
            this.effectiveFrom = effectiveFrom;
            this.endsOn = endsOn;
            this.createdBy = createdBy;
            this.createdOn = createdOn;
        }

        public long getId() {
            return id;
        }

        public void setId(long id) {
            this.id = id;
        }

        public long getUserId() {
            return userId;
        }

        public void setUserId(long userId) {
            this.userId = userId;
        }

        public long getDepartmentId() {
            return departmentId;
        }

        public void setDepartmentId(long departmentId) {
            this.departmentId = departmentId;
        }

        public Date getEffectiveFrom() {
            return effectiveFrom;
        }

        public void setEffectiveFrom(Date effectiveFrom) {
            this.effectiveFrom = effectiveFrom;
        }

        public Date getEndsOn() {
            return endsOn;
        }

        public void setEndsOn(Date endsOn) {
            this.endsOn = endsOn;
        }

        public long getCreatedBy() {
            return createdBy;
        }

        public void setCreatedBy(long createdBy) {
            this.createdBy = createdBy;
        }

        public Timestamp getCreatedOn() {
            return createdOn;
        }

        public void setCreatedOn(Timestamp createdOn) {
            this.createdOn = createdOn;
        }

        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;

            ClassTeacher that = (ClassTeacher) o;

            if (id != that.id) return false;
            if (createdBy != that.createdBy) return false;
            if (userId != null ? !userId.equals(that.userId) : that.userId != null) return false;
            if (departmentId != null ? !departmentId.equals(that.departmentId) : that.departmentId != null) return false;
            if (effectiveFrom != null ? !effectiveFrom.equals(that.effectiveFrom) : that.effectiveFrom != null)
                return false;
            if (endsOn != null ? !endsOn.equals(that.endsOn) : that.endsOn != null) return false;
            if (createdOn != null ? !createdOn.equals(that.createdOn) : that.createdOn != null) return false;
        }

        @Override
        public int hashCode() {
            int result = (int) (id ^ (id >>> 32));
            result = 31 * result + (userId != null ? userId.hashCode() : 0);
            result = 31 * result + (departmentId != null ? departmentId.hashCode() : 0);
            result = 31 * result + (effectiveFrom != null ? effectiveFrom.hashCode() : 0);
            result = 31 * result + (endsOn != null ? endsOn.hashCode() : 0);
            result = 31 * result + (int) (createdBy ^ (createdBy >>> 32));
            result = 31 * result + (createdOn != null ? createdOn.hashCode() : 0);
            return result;
        }

        @Override
        public int compareTo(Object comparestu) {
            return this.getEffectiveFrom().compareTo(((ClassTeacher)comparestu).getEffectiveFrom());
        }
    }

最佳答案

问题是服务器返回的日期为“2019 年 11 月 1 日”。在这种格式中,您没有时间和时区,因此无法正确设置日期格式。如果您无法更改服务器端,我看不到任何解决方案,否则几乎没有解决方案:

1) 当您调用电话时,将区域设置发送到服务器,服务器将返回正确的日期。

2) 更改服务器的日期格式,返回以毫秒为单位的时间或 ISO 8061 格式的时间格式 - 然后当您解析日期时,您可以设置您的区域设置。

关于java - GSON 默认日期序列化器是特定于语言环境的,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58669019/

相关文章:

javascript - 将 JSON 对象转换为数组以在不丢失键/索引的情况下进行排序

MYSQL 选择特定日期之后的行(行类型为 varchar)

php - 使用 PHP 获取第二天和前一天

java - 在开始 Android 开发之前我应该​​学习哪些设计模式

json - Mongodb - 为现有集合添加架构

java - iload_1、iload_2、iload_3 和 iload #index 字节码有什么区别?

javascript - 如何在ajax成功函数中仅访问由json发送的一个对象而不是整个数组?

javascript - 将日期从带有偏移量的字符串转换为不同时区

java - 为什么在泛型类(Java)的构造函数中提供类型参数是错误的?

java - future.isDone 即使任务完成也会返回 false