2016-03-30 15 views
0

Sorun, DAO'nun yükleme işlevinden yanlış tarih almamdır. Gözlemlenen tarih PostgreSQL veritabanında saklanır (Kullanıcı Tablosundan doğum tarihi sütunundan gelir) ve 1982-03-28'e eşittir. Bazen 1982-03-27 olarak getirilir. Daha deneyimli kullanıcılardan bazı ipuçları aldım ve bunun bir şekilde saat dilimi sorunlarıyla bağlantılı olduğunu söylüyorlar.Hazırda bekletme tarihi yanlış yükleme nasıl engellenir?

Yanlış değerler java.util.Date sınıfının örneğinden gelir. Onları Takvim sınıfının nesnesi ile alıyorum. Ben çağırdığınızda bu ufak:

calendar.getTimeZone().getDisplayName() 

döndürür

Central European Time 

BirthDate sütunun türüdür:

doğum tarihi TIMESTAMP TIME ZONE

değeri OLMADAN postgresql.conf dosyasında ayarlanan zaman dilimi değişkeni Polonya'ya eşittir.

yük yöntemin iç uygulama şuna benzer:

public T load(ID aPrimaryKey, boolean aLock) 
{ 
    if (aPrimaryKey == null) { 
     throw new IllegalArgumentException("Parameter aPrimaryKey can't be null!"); 
    } 
    preLoad(aPrimaryKey); 
    T entity; if (aLock) { 
     entity = _session.load(getEntityClass(), aPrimaryKey, LockMode.UPGRADE); 
    } else 
     entity = _session.load(getEntityClass(), aPrimaryKey); 
    postLoad(entity); 

    return entity; 
} 

Benim veritabanı sürümü

gcc tarafından derlenen

x86_64-bilinmeyen-linux-gnu üzerinde PostgreSQL 9.4.4 (Debian 4.9 olduğunu 0,2-10) 4.9.2, 64-bit

Ben

kullanmak 210

hazırda-çekirdek-3.6.0.Final.jar

bu (birkaç alan vardır) gibi Benim varlık sınıfı arar: Ben TIMESTAMPTZ için birthdate alanın türünü değiştirdi

import javax.persistence.Column; 

@javax.persistence.Entity 
@javax.persistence.Table(name="User") 
@javax.persistence.SequenceGenerator(name="userId", sequenceName="user_id_seq", allocationSize=1) 
public class User { 

    @javax.persistence.Id 
    @Column(name="Id", nullable=false) 
    @javax.persistence.GeneratedValue(strategy=javax.persistence.GenerationType.AUTO, generator="userId") 
    private long id; 

    @Column(name="Name") 
    private String firstName; 

    public User(String firstName, java.util.Date birthDate, java.util.Date registrationDate) 
    { 
     this.firstName = firstName; 
     this.birthDate = birthDate; 
     this.registrationDate = registrationDate; 
    } 

    @Column(name="BirthDate") 
    @javax.persistence.Temporal(javax.persistence.TemporalType.DATE) 
    private java.util.Date birthDate; 

    @Column(name="RegistrationDate", nullable=false) 
    @javax.persistence.Temporal(javax.persistence.TemporalType.TIMESTAMP) 
    private java.util.Date registrationDate; 

    public String toString() 
    { 
     return firstName + " should clean himself..."; 
    } 

    public User() {} 
} 

- o zaman her şey iyi görünüyor. Ancak sütunun veri türünü değiştirmeden problemi nasıl çözebilirim? Hiç ipucu var mı?

+0

Nasıl PG bir zaman damgası ve bir tarih olarak depoluyordur? Tuhaf. Sütun tanımını, tarih olarak değil, bir zaman damgası olarak saklamak için değiştirebilir misiniz? –

+0

@NeilMcGuigan Veritabanında zaten birkaç bin kullanıcım var, bu yüzden hepsinin doğum tarihlerini değiştirmek zorundayım (Tarihin PostgreSQL'deki Timestamp'tan nasıl farklı olduğunu kontrol edeceğim, çünkü nasıl emin olacağımı pek emin değilim bu iki tür arasında dönüşüm yapın). – y434y

cevap

0

Sorun şu ki, sisteminiz CET olarak ayarlanmış olabilir, ancak Polonya şu anda CEST (ve Pg onur DST). Yapabileceğiniz

birkaç nokta:

  • her oturumun başında Kullanımı SET TIME ZONE timezone; o müşterini aynı olduğundan emin olun. Değerleri seçerken veya timezone(zone, timestamp) işlevini seçerken, istemciyle eşleştirmek için AT TIME ZONE'u kullanın..

  • Değer seçildiğinde, değeri timestamptz'a aktarın, bu nedenle TZ bilgileri korunur (aslında bundan emin değil).

Ama gerçekten, hep zamanı tutmak amacıyla timestamptz kullanmak çok daha iyidir.

Sorunuzu sorudan yanıtlamak için: date türüne (birthdate::date) timestamp/tz değerleri atabilirsiniz. date s zaman bilgisi yoktur ve saat dilimi bağımlı değildir, böylece her zaman değeri olduğu gibi alırsınız.

Bu, aslında daha anlamlı olabilir - muhtemelen do do birthgru zamanlarını orijinal zaman bölgelerinde (yani, girilen kullanıcılar gibi) geçerli TZ'ye dönüştürülmez.

İlgili konular