2010年12月11日土曜日

[メモ] [Google Chrome] [Java] GoogleCromeのCookiesに保存された日付データ読む

内部データの詳細については詳しくないため、
とりあえずうまくいくぽいという感じで。


// Cookiesテーブルから取得した値

long dateValue = 12932097945757375L
// オフセットを反映します
dateValue -= 11644473600000000L;
// 精度の問題ではみ出す桁を切り捨てます
dateValue = dateValue / 1000;
// Javaの日付型に格納します
Date cookieDate = new Date(dateValue );


・Google ChromeはCookieの管理にSQLiteを使用している。
・CookieはCookiesというデータベースファイルのcookiesというテーブルで管理している。
・このcookiesというテーブルの日付と思しきフィールドの値をJavaのDateで読み込もうというネタ。
・Cookiesデータベースファイルの場所はWindowsXPの場合は
C:\Documents and Settings\${ユーザ名}\Local Settings\Application Data\Google\Chrome\User Data\Default\Cookies

・まずcookiesテーブルの定義
・テーブルとしてはCookieの対応する値を自然にイメージできるようにつくられている。
・ちなみにSQLiteのデータを閲覧するのにSQLite Database Browser というツールを使ってます。

























・日付フィールドの例としてcookiesテーブルのキーにも使用されているcreation_utcを見てみる。








・パっと見からして桁数が多い
・ちなみにJavaのDateクラスから時間(ミリ秒)を取得すると次のような感じ


import java.util.Date;

public class ChromeCookiesDate {
    public static void main(String args[]) {
        System.out.println(new Date().getTime());
    }
}

実行結果:1292033718437

並べてみると、
12932097945757375(cookies.creation_utcの値)
1292033718437(JavaのDateクラスから取得した値)

となって、先頭のほうは似ていますけど、桁数が異なります。
これは恐らく精度の問題だろうと思い、cookiesテーブルの値の
はみ出す4ケタを切り捨ててJavaのDateクラスを読み込み、
フォーマットしてみました。
はみ出す下4桁を切り捨てた1293209794575を投入してみます。



import java.util.Date;
import java.text.DateFormat;
import java.text.SimpleDateFormat;

public class ChromeCookiesDate {

    public static final String DATE_FORMAT_TEXT =
                                 "yyyy/MM/dd HH:mm:ss.SSS";
    public static final DateFormat FORMATTER =
     new SimpleDateFormat(DATE_FORMAT_TEXT);
    public static void main(String args[]) {
        System.out.println(FORMATTER.format(new Date(1293209794575L)));
      
    }
}

実行結果:2010/12/25 01:56:34.575


未来の日付になってしまいました。他の日付フィールドを試しても
どうしてもこのままでは合わないようです。

結論から先に申しますと、時間を表す値の基準日が違うということです。
JavaのDateクラスは基準が1970 年 1 月 1 日 00:00:00 GMT
ですので、そのずれをオフセットというかたちで足し算、引き算しないと
正しい値が得られません。

いろいろ試した結果、次のようなオフセットを使えば値が一致するようです。


import java.util.Date;
import java.text.DateFormat;
import java.text.SimpleDateFormat;

public class ChromeCookiesDate {

    public static final String DATE_FORMAT_TEXT =
                                 "yyyy/MM/dd HH:mm:ss.SSS";
    public static final DateFormat FORMATTER =
     new SimpleDateFormat(DATE_FORMAT_TEXT);
    public static void main(String args[]) {

        // cookiesテーブルから取得した値、このまま桁を切捨てて
        // Dateに投入しても未来の日付になってしまう
        long dateValue = 12932097945757375L;

        // オフセットを反映します
        dateValue -= 11644473600000000L;

        // 精度の問題ではみ出す桁を切り捨てます
        dateValue = dateValue / 1000;
  
        System.out.println(FORMATTER.format(new Date(dateValue)));
      
    }
}

実行結果:2010/10/21 10:25:45.757
Google Chromeで見た値:

ということで一致しました。


なぜか?と問われれば正直このへんは詳しくないのでよくわかりませんが、
Google Codeで11644473600や11644473600000000を検索すると
似たようなことをしているところが抽出されますので閲覧してみるとよいかもしれません。

0 件のコメント:

コメントを投稿