如何跨多个时区处理java.sql.Dates?

时间:2018-05-01 22:39:12

标签: java hibernate

我有一个位于美国东部时区的Oracle数据库。我在美国中部时区。我的EJB使用java.sql.Date作为日期字段。数据库中的字段是日期:

CREATE TABLE "MYSCHEMA"."TBLBURSTASSGN" 
   (    "BURSTASSGN_ID" NUMBER(*,0) NOT NULL ENABLE, 
"BURSTASSGN_TYPEVID" NUMBER(*,0), 
"BURSTASSGN_CONTACTID" NUMBER(*,0), 
"BURSTASSGN_ASSIGNMENTREF" VARCHAR2(50), 
"BURSTASSGN_STARTDATE" DATE, 
"BURSTASSGN_DUEDATE" DATE, 
"BURSTASSGN_INSTRUCTION" VARCHAR2(2048), 
"BURSTASSGN_STATUSVID" NUMBER(10,0), 
"BURSTASSGN_SUMMARYONLYYN" CHAR(1) DEFAULT 'N' NOT NULL ENABLE);

当我在Central中输入EJB的日期并将其保存到Eastern DB时,它会被正确保存,例如。我输入2018年1月31日,并存储2018-01-31 00:00:00。但是当我重新加载我的应用程序并从数据库中提取时,它会显示2018年1月30日。

应用

BurstAssignment burstAssignment = SessionHelper.getSession().getBurstAssignment(assignmentId);
System.out.println("StartDate " + burstAssignment.getStartDate());

的SessionBean

@Override
public BurstAssignment getBurstAssignment(Integer id) {
    if (id == null) { return null; }
    return em.find(BurstAssignment.class, id);
}

EntityBean的

import com.kable.newsstand.kdsejb.audit.Auditable;
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.persistence.Transient;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.EqualsBuilder;
import org.apache.commons.lang3.builder.HashCodeBuilder;
import java.sql.Date;
import javax.validation.constraints.NotNull;
import org.hibernate.annotations.Type;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.SequenceGenerator;

@Entity
@Table(name="TBLBURSTASSGN")
public class BurstAssignment extends Auditable implements Serializable {

    private static final long serialVersionUID = 1L;

    @Column(name="BURSTASSGN_DUEDATE")
    protected Date dueDate = null;
    @Column(name="BURSTASSGN_CONTACTID")
    protected Integer contactId = null;
    @Column(name="BURSTASSGN_INSTRUCTION")
    protected String instruction = null;
    @Column(name="BURSTASSGN_STARTDATE")
    protected Date startDate = null;
    @Column(name="BURSTASSGN_ASSIGNMENTREF")
    protected String assignmentRef = null;
    @Column(name="BURSTASSGN_TYPEVID")
    protected Integer typeVid = null;
    @Id
    @SequenceGenerator(name="BURSTASSIGNMENT_SEQ", sequenceName="TBLBURSTASSGN_ID_SEQ", initialValue = 1, allocationSize = 1)
    @GeneratedValue(strategy=GenerationType.SEQUENCE, generator="BURSTASSIGNMENT_SEQ")
    @Column(name="BURSTASSGN_ID", updatable=false, nullable=false)
    protected Integer id = null;
    @Column(name="BURSTASSGN_STATUSVID")
    protected Integer statusVid = null;
    @Type(type="yes_no")
    @NotNull
    @Column(name="BURSTASSGN_SUMMARYONLYYN")
    protected Boolean summaryOnlyYN = false;

    public BurstAssignment() { super(); }

    public BurstAssignment(BurstAssignment burstAssignment) {
        setDueDate(burstAssignment.getDueDate());
        setContactId(burstAssignment.getContactId());
        setInstruction(burstAssignment.getInstruction());
        setStartDate(burstAssignment.getStartDate());
        setAssignmentRef(burstAssignment.getAssignmentRef());
        setTypeVid(burstAssignment.getTypeVid());
        setId(burstAssignment.getId());
        setStatusVid(burstAssignment.getStatusVid());
        setSummaryOnlyYN(burstAssignment.getSummaryOnlyYN());
    }

    public Date getDueDate() {
        if (dueDate == null) { return null; }
        return new Date(dueDate.getTime());
    }

    public void setDueDate(Date dueDate) {
        if (dueDate == null) { this.dueDate = null; }
        else { this.dueDate = new Date(dueDate.getTime()); }
    }

    public Integer getContactId() {
        return contactId;
    }

    public void setContactId(Integer contactId) {
        this.contactId = contactId;
    }

    public String getInstruction() {
        return instruction;
    }

    public void setInstruction(String instruction) {
        this.instruction = instruction;
    }

    public Date getStartDate() {
        if (startDate == null) { return null; }
        return new Date(startDate.getTime());
    }

    public void setStartDate(Date startDate) {
        if (startDate == null) { this.startDate = null; }
        else { this.startDate = new Date(startDate.getTime()); }
    }

    public String getAssignmentRef() {
        return assignmentRef;
    }

    public void setAssignmentRef(String assignmentRef) {
        this.assignmentRef = assignmentRef;
    }

    public Integer getTypeVid() {
        return typeVid;
    }

    public void setTypeVid(Integer typeVid) {
        this.typeVid = typeVid;
    }

    public Integer getId() {
        return id;
    }

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

    public Integer getStatusVid() {
        return statusVid;
    }

    public void setStatusVid(Integer statusVid) {
        this.statusVid = statusVid;
    }

    public Boolean getSummaryOnlyYN() {
        return summaryOnlyYN;
    }

    public void setSummaryOnlyYN(Boolean summaryOnlyYN) {
        this.summaryOnlyYN = summaryOnlyYN;
    }

    @Transient
    @Override
    public String getPrimaryKeyDisplay() {
        StringBuilder sb = new StringBuilder();
        if (id == null) {
            sb.append(" id: null");
        } else {
            sb.append(" id: " + id.toString());
        }
        return sb.toString();
    }
    @Transient
    @Override
    public String toString() {
        return new ToStringBuilder(this).append("dueDate", dueDate).append("contactId", contactId).append("instruction", instruction).append("startDate", startDate).append("assignmentRef", assignmentRef).append("typeVid", typeVid).append("id", id).append("statusVid", statusVid).append("summaryOnlyYN", summaryOnlyYN).toString();
    }

    @Transient
    @Override
    public int hashCode() {
        return new HashCodeBuilder().append(dueDate).append(contactId).append(instruction).append(startDate).append(assignmentRef).append(typeVid).append(id).append(statusVid).append(summaryOnlyYN).toHashCode();
    }

    @Transient
    @Override
    public boolean equals(Object obj) {
        if (obj == null) { return false; }
        if (obj == this) { return true; }
        if (obj.getClass() != getClass()) { return false; }
        BurstAssignment that = (BurstAssignment) obj;
        return new EqualsBuilder().append(dueDate, that.dueDate).append(contactId, that.contactId).append(instruction, that.instruction).append(startDate, that.startDate).append(assignmentRef, that.assignmentRef).append(typeVid, that.typeVid).append(id, that.id).append(statusVid, that.statusVid).append(summaryOnlyYN, that.summaryOnlyYN).isEquals();
    }

}

2 个答案:

答案 0 :(得分:0)

我通过将本地VM的时区更改为东方以匹配DBTIMEZONE来修复它。

-Duser.timezone=-5:00

更新:我的应用程序部署为Web Start应用程序,我似乎无法接受jnlp或命令行中的上述行。所以我将以下内容插入到我应用的主要课程中。

{
    TimeZone.setDefault(TimeZone.getTimeZone("-5:00"));
}

答案 1 :(得分:-1)

你的问题是你的getter和setter正在调用getTime(),它将Date转换为毫秒,然后Date的构造函数删除了日期的时间组件。如果您有不同的时区,这可能会导致一小时的差异转换为一天的差异。

不要太喜欢你的吸气剂和二传手。他们应该看起来像这样。

public Date getDueDate() {
    return dueDate;
}

public void setDueDate(Date dueDate) {
    this.dueDate = dueDate;
}