java.util.Date型のシリアライズ処理の不具合

305 views
Skip to first unread message

capy

unread,
Aug 3, 2010, 2:32:36 AM8/3/10
to Google Web Toolkit in Japanese (GWTJP)
gwt 2.0.3を使用している環境で不具合がありましたので、情報共有しておきます。

以下の範囲の日付をサーバーからクライアントへ送ると1時間減ってしまいます。

1948年(昭和23年) - 五月の第一土曜日の翌日(日曜)から九月の第二土曜日まで (附則第二項)
1949年(昭和24年) - 四月の第一土曜日の翌日(日曜)から九月の第二土曜日まで (本則)
1950年(昭和25年) - 五月の第一土曜日の翌日(日曜)から九月の第二土曜日まで (改正法)
1951年(昭和26年) - 五月の第一土曜日の翌日(日曜)から九月の第二土曜日まで (改正法)

参考: http://ja.wikipedia.org/wiki/夏時刻法

この現象はDepelopmentモードでは発生せずに、Productionモードの状態でのみ発生します。

事象の例:

正しい期間の日付シリアライズ処理
// サーバー側
Date date = new Date("1969/09/04"); // <- JST
System.out.println(date.toLocaleString());
// -> 1969/09/04 0:00:00

// クライアント側
Date date = getRpcFromServer();
System.out.println(date.toLocaleString());
// -> 1969/09/04 0:00:00

不具合期間の日付シリアライズ処理
// サーバー側
Date date = new Date("1949/09/04"); // <- JST
System.out.println(date.toLocaleString());
// -> 1949/09/04 0:00:00

// クライアント側
Date date = getRpcFromServer();
System.out.println(date.toLocaleString());
// -> 1949/09/03 23:00:00

ひとまずの対処法としては、gwt-user.jar, gwt-servlet.jarの中の
com.google.gwt.user.client.rpc.core.java.util.Date_CustomFieldSerializer
を以下の様に差し替える事で対応可能です。

package com.google.gwt.user.client.rpc.core.java.util;
import java.util.Date;

import com.google.gwt.user.client.rpc.SerializationException;
import com.google.gwt.user.client.rpc.SerializationStreamReader;
import com.google.gwt.user.client.rpc.SerializationStreamWriter;

/**
* Custom field serializer for {@link java.util.Date}.
*/
public final class Date_CustomFieldSerializer {
public static void deserialize(SerializationStreamReader
streamReader, Date instance) {
// No fields
}

@SuppressWarnings("deprecation")
public static Date instantiate(SerializationStreamReader
streamReader)
throws SerializationException {
// return new Date(streamReader.readLong());
return new Date(streamReader.readInt(),
streamReader.readInt(), streamReader.readInt(),
streamReader.readInt(), streamReader.readInt(),
streamReader.readInt());
}

@SuppressWarnings("deprecation")
public static void serialize(SerializationStreamWriter
streamWriter, Date instance)
throws SerializationException {
// streamWriter.writeLong(instance.getTime());
streamWriter.writeInt(instance.getYear());
streamWriter.writeInt(instance.getMonth());
streamWriter.writeInt(instance.getDate());
streamWriter.writeInt(instance.getHours());
streamWriter.writeInt(instance.getMinutes());
streamWriter.writeInt(instance.getSeconds());
}
}

生年月日などをDate型でクライアントへ送っているアプリなどは注意が必要です。


Reply all
Reply to author
Forward
0 new messages