時を超えた javascript の道

28
時を超えた JavaScript の道 @teppeis Shibuya.js beyond HTML5 2010/07/30

Upload: teppeis

Post on 02-Nov-2014

18 views

Category:

Technology


1 download

DESCRIPTION

at Shibuya.js beyond HTML5 (2010/07/30) http://atnd.org/events/6730

TRANSCRIPT

Page 1: 時を超えた JavaScript の道

時を超えた JavaScript の道

@teppeis

Shibuya.js beyond HTML5 2010/07/30

Page 2: 時を超えた JavaScript の道

自己紹介

Page 3: 時を超えた JavaScript の道

経緯

席が向かえの amachang と机の下で足があたったりして キャッキャウフフ ヾ(*´∀`*)ノ するリア充生活を送っていたら、いつのまにか LT することになっていました。お手柔らかにおねがいします!

Page 4: 時を超えた JavaScript の道

さて、国際化が叫ばれる昨今

社内公用語の英語化が話題です。

Page 5: 時を超えた JavaScript の道

ちょっと待って!

国際化といえば、タイムゾーンを忘れてませんか?

ということで、JavaScript のタイムゾーンの話をします。

Page 6: 時を超えた JavaScript の道

とりあえずデモ   

画面上の時刻表示を変換する Chrome 拡張ATND の microformats を読み取って、PST(太平洋標準時)に変換します。

Page 7: 時を超えた JavaScript の道

音響カプラと3Dと

顔文字アセンブラのあとに

この地味なデモ。

Page 8: 時を超えた JavaScript の道

Warningこっから

地味な話が続きます。眠たい人は

今がチャンスです。

Page 9: 時を超えた JavaScript の道

Date Object in JavaScript

new Date() はローカルタイムを生成ローカルタイムとUTCのみを扱えるローカルタイムのタイムゾーンはOS設定夏時間の計算方法は環境依存

Page 10: 時を超えた JavaScript の道

え。ということは?

UTCやOS設定以外のタイムゾーンを扱うことができない環境によって日時表示や日時計算がずれる場合がある

Page 11: 時を超えた JavaScript の道

いろんなTZを扱いたいケース

例)JST を PST に変換したい例)カレンダーに旅行の予定を登録するUI

帰りの飛行機は現地時刻(PST)で14:00「時差何時間だっけ。。」「この時期ってサマータイム?」「OSの設定変えたくないよ><」

JavaScript Date では解決できない!

Page 12: 時を超えた JavaScript の道

環境によって日時がずれるケース

// OSのタイムゾーンをPST(太平洋標準時)に設定して // 2006年4月2日 午前1時 (PST) のタイムスタンプをチェック

var dt = new Date(2006,3,2,1,0,0,0); if (1143968400000 === dt.getTime()) { alert( "OK" ); } else { alert( "NG" ); }

Page 13: 時を超えた JavaScript の道

結果

Firefox Chrome Safari Opera IE

Windows NG NG NG NG NG

Mac OK OK NG NG -

Linux OK OK - NG -

iPhone - - NG NG -

Android - OK - - -

Page 14: 時を超えた JavaScript の道

なんでズレたの?

PDT(太平洋夏時間)の期間が2006年から2007年にかけて変更されたから

夏時間の期間が約1ヶ月後ろにずれた2006-04-02 01:00:00 は歴史的には夏時間ただし、新ルールで計算し直すと標準時

Page 15: 時を超えた JavaScript の道

夏時間の対応レベル

Lv.1 ルールベース毎年同じ夏時間ルールを適用

例)毎年3月第2日曜午前2時から夏時間Windows

Lv.2 ヒストリカルデータ過去の時差情報を利用して時差計算

いわゆる zoneinfo, tz database.世界の秩序は Olson さんがローカルで管理してる!Linux, Java, Python, Ruby...

Page 16: 時を超えた JavaScript の道

ブラジルにルールなんてない!

ブラジルは夏時間期間を毎年都度発表ネパールは +5:45(1986年までは +5:40)

Page 17: 時を超えた JavaScript の道

ECMAScript ではどうなってるの?

15.9.1.8 Daylight Saving Time AdjustmentECMAScriptの実装としては、同じルールを毎年適用する。でもホスト環境が年ごとの夏時間情報を提供する場合は、それを利用してもいいよ。

つまり、環境と実装に依存

Page 18: 時を超えた JavaScript の道

ということで、

OSに依存せずタイムゾーンを選択OSに依存せず時差計算ヒストリカルデータ対応

こんなことをやりたいな。

Page 19: 時を超えた JavaScript の道

アプリ開発言語としての JS

Webサイトのクライアント側、じゃなくてHTML5 = オフラインアプリケーションサーバーアクセス無しで動きたい ECMAScript の Date では不十分

ActionScript はどうしてるんだろう

Page 20: 時を超えた JavaScript の道

あった。

Google Closure Library

Page 21: 時を超えた JavaScript の道

あれ?肝心のデータが。

URLが。。

Page 22: 時を超えた JavaScript の道

データ生成する

せっかくなので Rhino 使ってみたタイムゾーンデータは Joda Time(手抜き)JSONフォーマットに変換

tzdata['America/LosAngeles'] = { 'transitions': [ // 遷移時刻タイムスタンプ(時間)と標準からの時差(分)の配列 2770, 60, 7137, 0, 11506, 60, 16041, 0, ... 580186, 60, 585897, 0, 588922, 60, 594633, 0 ], // 標準時の短縮名、正式名、夏時間の短縮名、正式名 'names': ['PST', 'Pacific Standard Time', 'PDT', 'Pacific Daylight Time'], 'id': 'America/Los_Angeles', // ID 'std_offset': -480 // 標準時差};

Page 23: 時を超えた JavaScript の道

生成したタイムゾーンデータ

1970年 - 2038年全558地域358 KBWebアプリならアプリケーションキャッシュを使うか、ファイルを分割して遅延ローディングが良さそう。

Page 24: 時を超えた JavaScript の道

あれ?

goog.i18n.TimeZone には localToUTC なメソッドがないgoog.date.DateTime にもない。タイムゾーンの変換ができない。片手落ち。ので、いくつかの API 追加実装。

Page 25: 時を超えた JavaScript の道

goog.i18n.TimeZone.prototype.getUTCMillisFromLocal = function( opt_year, opt_month, opt_date, opt_hours, opt_minutes, opt_seconds, opt_milliseconds) { ... var localMillis = Date.UTC( opt_year, opt_month, opt_date, opt_hours, opt_minutes, opt_seconds, opt_milliseconds); var localDate = new Date(localMillis); var localOffset = this.getOffset(localDate) * 60 * 1000; var adjustedDate = new Date(localMillis + localOffset); var adjustedOffset = this.getOffset(adjustedDate) * 60 * 1000;

if ( localOffset > adjustedOffset ) { var localNext = this.nextTransitions(localMillis + localOffset); var adjustedNext = this.nextTransitions(localMillis + adjustedOffset); if ( localNext !== adjustedNext ) { return localMillis + localOffset; } } return localMillis + adjustedOffset;};

Page 26: 時を超えた JavaScript の道

ようやくデモ   

デモ画面上の時刻表示を変換する Chrome 拡張ATND の microformats を読み取って、PST(太平洋標準時)に変換します。

Page 27: 時を超えた JavaScript の道

まとめ

JS でマルチタイムゾーンを扱うには自前で実装する必要があるよ。標準でなんとかならないかなぁ。Google Closure 使うんじゃなかった。。HTML5 ってなんだっけ。

Page 28: 時を超えた JavaScript の道

以上です。ありがとうございました!