22

データベースに日付を保存しているときに、非常に奇妙な動作が発生します。私の(Linux centOS 6.2)サーバーでは、glassfishアプリケーションサーバー(3.1.1-ビルド12)とJava(1.7.0_09)を使用し、アプリケーションはJava + GWTで開発され、PostgreSQLサーバー(9.2.1)を使用します。アプリケーション内には、データベースに保存されるいくつかの日付フィールドがあります。日付フィールドはdatepicker(http://code.google.com/p/gwt-datepicker、r30)を使用します。

dbリレーションのdate属性は、日付タイプ(タイムスタンプではありません)です。一部の日付は前日にデータベースに保存されます。この問題は、間隔の間の日付、たとえば31.03.1968と27.10.1968の間でのみ発生します。これにより、ある種の夏時間の問題が考えられます。しかし、たとえば1969年には発生しないため、問題をうまく切り分けることができません。問題が発生する他の日付間隔を見つけようとしています。たとえば、アプリケーションで19.05.1968を選択した場合、データベースに保存した後、日付は18.05.1968として保存されます。

奇妙なことに、同じアプリケーションの別のインスタンスが別のサーバーにあり、同じ日付で正しく保存されます。これにより、問題は次のいずれかに依存する可能性があると思います。

  • Glassfishの構成;
  • java(java.util.Date実装?);
  • 私が欠けているある種のサーバー構成

サーバーで可能なすべての構成をヨーロッパ/ローマ(私のタイムゾーン)に設定しようとしましたが、何もしませんでした。何か案が?この問題をどのように解決または調査できますか?

更新: 1968年はうるう年でした。この問題は1972年にも発生しますが、これもうるう年です。要約:「1日前に保存された日付」の問題は、夏の時間の日付間隔のうるう年に発生します。

日付オブジェクトが作成されるコード部分は次のとおりです。

Date d = dateField.getSelectedDate();
if (d != null) {
    txtVal = DateTimeFormat.getFormat("dd/MM/yyyy").format(d);
}

ここで、dateFieldは次のように宣言されています。

transient private DatePicker dateField;

パッケージはorg.zenika.widget.client.datePicker.DatePicker(前述のgwt-datepicker-r30)であり、DateTimeFormatはcom.google.gwt.i18n.shared.DateTimeFormat

答えを受け入れた後の更新:

この回避策を使用しました。日付を作成するときは、次のコードを使用します。

final long hours12 = 12L * 60L * 60L * 1000L;
Date d = new Date(d1.getTime() + hours12);
4

3 に答える 3

9

日付の時刻を(デフォルトの0:00ではなく)12:00に設定するだけで、問題はありません。問題は、GWTタイムゾーンライブラリに1990年より前のうるう年がすべて含まれていないため、サーバーで誤った時刻が取得されることです(値はタイムスタンプの形式で送信され、1時間オフであるため)。

ちなみに、GWTには日付ピッカーが組み込まれています。http://gwt.google.com/samples/Showcase/Showcase.html#!CwDatePickerでデモを参照してください。

于 2012-11-08T09:40:35.970 に答える
1

java.util.dateまたはjava.sqlを使用していますか。日付(後者は正しいものです)?SQL Serverでも同様の問題が発生しましたが、それが定期的であり、夏に関連していました。

基本的に、Javaの日付は特定の日の真夜中として保存します。夏の場合、日付は前日の23:00に移動し、時刻が切り捨てられます。「ランダムな」タイムスタンプで日付を送信すると、夏の間に24回に1回問題が発生します。

解決策を正確に覚えていませんが(別のDBMSを参照しているため、直接は役に立ちません)、dBには、「受け取った日付を保存する」という設定がありました。dbcolumnをtimestampに変更し、時刻がどのように格納されるかを確認することで、これが当てはまるかどうかをテストできます。

私は少し調査しました-gwt-datepickerには多くの問題があるようです!http://code.google.com/p/google-apps-script-issues/issues/detail?id=2022 http://code.google.com/p/google-apps-script-issues/issues/detail ?id = 2001

彼らの計算にうるう年のバグがあったとしても、私は驚かないでしょう。また、あなたがしていることとあなたがしていると思うことの間の単なるミスマッチである可能性は完全にあります-Datesでの作業は驚くほど難しい問題です

確認するには、次のことを試してください。

final java.util.Date ud = dateField.getSelectedDate();;
final java.sql.Date sd = new java.sql.Date(ud.getTime());
System.out.println(ud);// this is what you pick from the DatePicker
System.out.println(sd);// this is what will be stored on the database

そして、うるう年の夏の間にそれらが一致するかどうかを確認します。GWTのバグである場合は、http://code.google.com/p/google-apps-script-issues/が報告するのに適した場所です。

于 2012-11-08T01:25:00.560 に答える
0

生年月日のためにリアルタイムでこの問題に直面しました。

以下の修正を行ったので、日付を午前12時に保存する代わりに、サーバーの営業時間前の午前6時に保存します。1時間差し引かれても、dobには影響しません。

Calendar now = Calendar.getInstance();
now.setTime(YOUR_DATE);
now.set(Calendar.HOUR_OF_DAY, 6);
YOUR_DATE = now.getTime();

マイクの答えは大丈夫です。ただし、午後12時に保存すると、ユーザーが午後12時より前の営業時間内に日付を入力すると、日付の比較でエラーが発生する可能性があります。

于 2014-03-08T16:37:54.537 に答える