週番号の仕組みと普及
スピーカー 3
はい、じゃあ前回に引き続いて、カレンダー開発の怖い話、TimeTreeTechTalkでお送りしていきます。
スピーカー 1
また例によって、シオンとスコットに話を聞いていきたいと思ってますが、よろしくお願いします。
スピーカー 3
今日は、週番号の、前回も話出ましたけど、週番号、あと繰り返し予定ですね。
スピーカー 1
はい、まず週番号って、あまり馴染みがないと思うんですけど。
スピーカー 3
ないですね。
スピーカー 1
はい、どういうものかっていうと、1年の最初の週から投資番号を振ってあって、
大体1年に52週か53週あるので、その番号で週を特定するっていうやり方です。
日本だと大体、月曜日の日付とかで、何月何日の週とかっていう言い方をすると思うんですけど、
ヨーロッパとかでは、週番号っていうのが普及してて、日付のやり取りをするときに、第何週の何曜日みたいな言い方を使ったりするらしいんですね。
カレンダーにも普通にその週番号書いてあるし、プリの機能としても必須のものとなっているらしくて、
タイムツリー当初は、リリース当初は対応してなかったんですけど、結構ドイツとかのユーザーが多くなってきて、
ご要望が非常に多く上がってきたので、対応したっていう経緯があります。
スピーカー 3
なるほど、全く馴染みないですね。でもこれは日本人の僕らからすると。
スピーカー 2
そうですね、そういう意味で言うと文化が知れて面白いなって僕は結構思った事例だったんですけど、
第何週って言われてもピンとこないなっていうのは未だにありますね。
スピーカー 1
何が怖いのっていう話なんですけど。
そこですね、本題ですよ、本題。
国による週の決め方の違い
スピーカー 1
第1週目がどの週なんだっていう問題があるんですよ。
なるほど。
そうですね、1年の始まりの曜日って毎年違うじゃないですか。
なので、ある基準でこの週を第1週とするって決めないといけないんですよね。
この決め方が実は国によって違うっていう話なんですけど。
スピーカー 3
怖いですね。
スピーカー 1
いろいろあるけど、アメリカ式とヨーロッパ式に大きく2つに分かれているらしくて。
アメリカ式は、まず週の始めを日曜日にしますと。
1月1日が含まれる週が第1週っていうルールです。
スピーカー 3
なるほど。
スピーカー 1
で、もう一方のヨーロッパ式なんですけど。
ヨーロッパは週の始めは月曜日です。
その年の最初の木曜日が含まれる週が第1週っていう。
スピーカー 3
木曜日、なんか決めくれてるな。
スピーカー 1
月曜始まりだと木曜が真ん中なんですよね。
その真ん中の週が含まれるのがその年の第1週だっていう決め方で。
わかるっちゃわかる。
スピーカー 3
なるほど。なんか今僕、官平を読んでて地面で読むとすごい複雑に見えるけど。
確かに木曜日真ん中なの。
スピーカー 2
月曜始まりだと月火水と金土日があって木曜日が真ん中になるってわけですね。
スピーカー 1
なるほど。
そうですね。
なので、例えばアメリカ式だと1月1日が土曜日とかだと、
その週土曜日しかないのに1週間まるまる第1週ってカウントするみたいなことになるんですよね。
スピーカー 3
確かに。
スピーカー 1
という意味だとヨーロッパ式だと、
多く含まれてる方がその年の週、第1週になるっていう形なんで、
スピーカー 2
それはそれでわかるなっていう。
これ言ったら語弊があるかもしれないですけど、やっぱりアメリカンな決め方ですね。
わかりやすい。
スピーカー 1
そうです、確かに。
スピーカー 2
語弊があるかもしれないけど非常に大雑把。
スピーカー 3
こういうのででも文化の違いが出るのかな。
なるほど、面白い。
面白いけど怖い。
スピーカー 1
怖くなってきました。
日本は使われてないんですけど、一応その終盤後表示はできて、
iOSの標準カレンダーで表示ってやるとアメリカ式で表示されるようになってます。
お気づきかと思うんですけど、
年によってこの2つの方式で終盤後がずれるってことが起きるんですよね。
スピーカー 2
2023年これずれてないですか?
スピーカー 1
2023年ずれてますね。
あと2022年もずれてるんですけど、
これが多分わかりやすくて、
2022年の1月は1月1日が土曜日なんですよね。
なのでアメリカ式になると1月1日の週が第1週になるんですけど、
そうすると12月26日の日曜日から1月1日の土曜日が第1週っていう決めになります。
対してヨーロッパ式にすると最初の木曜日が1月6日になるので、
1月3日から1月9日までが第1週になるっていう形で、
1週間ずれるっていう。
スピーカー 2
嘘だった。ごめんなさい。2023年ずれなかった。
1月1日日曜日だからずれないんだ。
日曜のアメリカ式。
確かにそうですね。
もうその時点で怖い。
怖くなってきただんだん。
スピーカー 1
で、これタイムツリーもちゃんと対応はしてて、
タイムツリー設定に終盤号の表示非表示の設定があるので、
ヨーロッパのユーザーはデフォルトでオンになってるんですけど、
日本のユーザーだとデフォルトはオフなので、
これをオンにしてもらうと基本的にアメリカ式で終盤号が表示できます。
これはただiPhoneの本体側の設定に地域設定っていうのがあるんですけど、
そこで国を日本にしてればアメリカ式になるんだけど、
それをヨーロッパの国に変えるとヨーロッパ式になります。
これRubyの実装だとどうなってるんだろう?
わかんない。
スピーカー 2
終盤号って一応あるにはあるんで。
スピーカー 1
バックエンド側でも使う場所ってあります?
スピーカー 2
使ってはいないんですけど、
これ知らずに普通に扱ってたらなんか怖いなと思って。
サーバーとかだと基本的にデータはUTCで扱うから、
ひょっとしたらヨーロッパ式になるのかなとか思ったりしてたんですけど、
タイムゾーンとかによって変わるのかな。
収録中なのにちょっとタイミングを起動して確かめたけど。
今スコットがめちゃくちゃそばそばしだしてる。
スピーカー 3
怖い怖い怖い怖い。
1週間のズレって結構カレンダー上ではかなりデカいズレですよね。
スピーカー 1
グローバルの企業で困ることあるんじゃないかって思うんですけど、
スピーカー 3
確かに。
スピーカー 1
どっちの基準に合わせるって決めで運用してるのか。
スピーカー 3
どうなんですかね。
例えば47週に請求書出すわみたいなので、
47週が全然違うってことですよね。
そうですね。
ヨーロッパとアメリカで。
怖いなあ。
これ実装上も結構怖いんですか。
スピーカー 1
終盤号自体は、
iOSの標準のフレームワークに終盤号を取得する仕組みがあるので、
それを正しく使ってる限りは大丈夫ですね。
ユーザーさんの設定した地域をちゃんと反映して表示させるっていうところができていれば、
大丈夫っていう感じになります。
もう一個怖い話が関連してありまして、
日付を文字として画面に表示するっていうことがあるんですけど、
その時にどういう文字にするかっていう指定するためのフォーマットがあって、
その記述ルールが決まってるんですね。
年の指定方法による表示のズレ
スピーカー 1
例えばこのY年M月D日みたいなフォーマットを指定すると、
2023年8月24日みたいな文字になるっていうこういうフォーマットがあって、
このYが年に対応するよっていうのがルールとして決まってるんですけど、
年を指定するのに小文字のYと大文字のYがあって、
実はこれ意味が違うんです。
スピーカー 3
なんと。
スピーカー 1
これ実際にコードで小文字のYと大文字のYをプリントしたときに何が出るかっていうと、
2023年12月31日のYを取得したときに、
小文字のYは2023って出るんですけど、
大文字のYにすると2024って出るんですよ。
スピーカー 3
めっちゃ確かにこの怖さすごいわかる。
なるほど。
スピーカー 2
知らないと理解できないやつですね。
スピーカー 1
そうですよね。
この大文字のYは実は終盤号基準の年になるので、
2023年12月31日は2024年の第一週になるから、
このYで出力すると2024っていう数字が出てしまうと。
これ実際に不具合を出したことがあります。
スピーカー 3
懺悔。
スピーカー 1
多味があるな。
これ多分結構あると思います。他の会社でも。
これ大文字のYでやって普通に1年のほぼほぼ大体は同じ正しい数字が出るので気づけないんですよ。
年末になってあれってなるって。
スピーカー 3
やばい。年末になるとだから1年ずれちゃうってことですね。
スピーカー 1
そうですね。
スピーカー 3
ミスると。これすごいですね。
スピーカー 2
今ちなみにRubyで確かめてみたんですけど、Rubyはヨーロッパ式でした。
ひょっとしたらシステムのタイムゾーン使われてるのかもしれないんですけど、
タイムゾーンのあれがないクラスでも出るのでちょっと怖いですね。
スピーカー 1
逆にアメリカ式で出す方法とかないんですかね。
スピーカー 2
ないんですかね。
スピーカー 3
深みにはまりそうだぞ。
スピーカー 1
あー怖い。
スピーカー 2
あー怖い怖い怖い。
スピーカー 3
タイムツリーはこれリリースしてからしばらくしてドイツの方からのお問い合わせとか要望で対応した。
スピーカー 1
そうですね。
スピーカー 3
カルチャライズっていうらしいですね。前スタッドが言ってたけど。
その国とかの文化に合わせて。
スピーカー 2
昔ドイツにユーザーインタビューしに行った時に、みんなドイツの壁掛けカレンダーじゃないけど、
ドイツのカレンダー買って帰ってきた。そこが要はその国の日常のはずだから。
スピーカー 1
日本では土曜日が青いっていうのは普通じゃないですか。
あれでも多分日本独自っぽいんですよね。
スピーカー 3
そうらしいですね。
スピーカー 1
韓国とかもそうかもしれないですけど。
一回そのデザイン変えて土曜日を普通に黒くしてたら結構お問い合わせあって、青に戻してくださいっていう。
今は設定で土曜青にするっていうオンオフがあって、日本はデフォルトで青いんだけど海外とかは黒くなってるとか。
スピーカー 3
それ覚えてますね。
それ僕入社してからだな。すごい覚えてる。
確かに土曜が青で日曜が赤。祝日も赤みたいなのは僕らからすると慣れ親しんだ感じですかね。
もう怖い話終盤後編はこんなとこですか怖い話は。
大丈夫ですか。もうないですか。びっくりしてるんですけど。
スピーカー 1
はい。一旦大丈夫です。
スピーカー 3
もうラスボスがあるんですね。ラスボス。
スピーカー 1
もう1個じゃあ繰り返し予定っていうやつに入っていきたいと思うんですけど。
これは結構タイムツリーのエンジニアみんなが意味嫌う言葉。
そうなんだ。
繰り返し予定のルールと実装
スピーカー 1
何かっていうと普通に毎週月曜日とか毎年何月何日みたいな繰り返し予定を
登録するのって当たり前に使ってると思うんですけど。
これあの実装するのは結構大変だっていう話ですね。
予定をシステム上でどのように表現するかっていう標準仕様があって
iカレンダーっていうものなんですけど
でその一部としてこの繰り返しルールを表現するための
Rルールっていう書式があります。
インカレンスルールっていうものなんですけど
これは毎週月曜日みたいなやつを決められた文字列で表現するっていうルールなんですけど
タイムツリーに予定登録した時に繰り返し予定はデータとしては1つしかないです。
なんですけどその一つの予定の中にRルールっていう項目があって
そこにこの予定は毎週月曜日の繰り返しですよみたいな情報が書き込まれているっていうイメージですね。
でまぁここまではふーんっていう感じじゃないですか。
はい非常に安定して聞けてますまた。
でこれをじゃあカレンダーに予定を表示しますってなった時に
その何月何日の何月のカレンダー表示するときは何月何日から何月何日までの予定を
どういう予定があるかデータから引っ張ってきて
それを一個ずつ画面に表示していくっていうことになるんですけれども
ある日付の期間この日からこの日までの予定の中に
その繰り返し予定が入っているのかどうかっていうのを確認しないといけないんですね。
それが実はやろうと思うとすごい難しいんですけど
例えば毎週月曜日とかだったら
普通に月曜日に一個ずつ入れていけばいいじゃんって思うかもしれないんですけど
繰り返しのルールってものすごい膨大なパターンがあって
例えば何週起きとか2週起きの月曜日とか
3週起きの月曜日みたいなものがあったりするんですよね。
そうするとその範囲にその予定どこに入るのっていうのパッとわからないと思うんですよ。
なのでそのRルールに従ってその予定が実際に何月何日に入ってくるのかっていうのを
バーッと全部展開していって
そこからその範囲に入っている予定だけをピックアップして表示するみたいなことをする必要があると。
なのでここがちょっと技術的に難しいポイントですね。
確かに。
スピーカー 2
毎週月曜日とかだったらまだいいんですけど
繰り返し何回100回とかは本当に難しくて
スピーカー 3
うーん。
スピーカー 2
全部展開しないとわからない。
スピーカー 3
それって裏側でバーッと展開されたデータを読みに行って
で表示に反映させてっていう
なんかその長いサイクルが裏側で常に回っているってことですね。
スピーカー 2
そうですね。
スピーカー 1
そうですね。
iOSアプリの仕様と問題点
スピーカー 1
でこれが実はそのiOSアプリの側で
結構長年にわたって付載になっていた部分に関連しているんですけど
当初のTimeZのiOSアプリは
サーバーから取ってきた予定のデータを
一旦その繰り返しを展開した形で
ローカルに保存するっていう方法を取ってたんですね。
なので毎週月曜日のやつは毎週月曜日の予定を
全部バーッと展開して
展開したものをローカルに保存するっていうことをやって
そうすると表示するときは
すでに展開されたものを表示するので
表示のパフォーマンスはいいっていう
メリットはあるんですけど
要は繰り返しって無限に繰り返せるんで
どっかで上限を決めないといけないんですよね
そうすると5年分までしか繰り返せないみたいな
制限がかかってしまう
そこの辺がAndroidとかWeb版とかと
仕様のズレが起きちゃって
これ何とかしないとねっていう話になり
AndroidとかWebとかはもともと
データ自体はそのままワークエンドから持ってきて
表示するときに繰り返しの展開をした上で
表示するっていう方法を取っていて
iOSの方もそのやり方に合わせるっていう
対応したんですけど
とにかく予定の表示に関するところなので
アプリのあらゆる場所に影響するので
ものすごく直すのは大変だったっていう
スピーカー 3
なるほど
iOSの場合はローカルにデータが溜まる
だから要するに挙動がちょっと重くなるとか
そういう話ですか
スピーカー 1
そうですね
繰り返し予定が多ければ多いほど
予定をダウンロードしてきたときに
その展開の処理もものすごいたくさん入ることになるので
その予定の動機により時間がかかっちゃったりとか
なるほど
スピーカー 3
してました
iOSだけ仕様が違ったのは何でだったんですか
スピーカー 1
ちょっとそこの経緯わかんないんですけど
最初にこの機能繰り返し予定の機能自体は本当に
最初のバージョンからあったので
最初に作った人の判断でそうなっていて
フラットフォンでズレが生じていたっていう感じですね
スピーカー 2
タイムツリーは予定にコメントとか付けられるんで
コメントするとコメントってその日だけなので
繰り返し予定が外れたりとか
余計に処理が複雑になったり
普通のカレンダーアプリと違って
繰り返し予定にもコメントを付けると
その週だけコメントが表示されるとか
その辺がちょっと何か特殊な処理を
いろいろやってる
スピーカー 1
そうですね
例えば繰り返し予定の中で
この予定だけちょっとスキップされて
消すみたいなこともすると思うんですけど
そうすると元の繰り返し予定の
この日は除外するみたいなデータを差し込んで
見えなくするみたいなことをやってたりとか
さっき言ってたように
コメントしたりとか
いいねしたりとか
参加したりってすると
それは元々の繰り返し予定と
別の予定になるので
データが新しく加わるんですね
その予定が繰り返し予定の一部から
単体の予定に昇格して
予定が一個新しくできるってイメージですね
元の繰り返し予定からは
その日だけ除外されるみたいな
スピーカー 3
目が回ってきました
スピーカー 1
なるほどね
外部カレンダーの対応と不正データ処理
スピーカー 1
これでも結構スコットが一時期
すごい苦労してた
スピーカー 2
そうですね
僕はでもちょっと苦労してたのは
Rルールって標準化されたルールなんで
そのルールに従ってると
大丈夫だよっていう感じなんですけど
タイムツリーのデータには
そこから外れた変なデータが
いっぱい入ってるっていうことがあって
ちゃんとマリネーションしてなかった
っていうのがあるんですけど
その変なデータがなぜかうまく表示されてしまう
っていうこともあったんで
それをサーバーでどうやって取り扱うか
あとタイムツリーって
外部のサービスからインポートする
っていう機能があるんですけど
それによってちょっとなんか不思議な
Rルールが書かれてたりとか
標準にないRルールがいっぱい
データとして存在して
一時期すごい困るっていうのがありましたね
その一部の不正なデータが残ってるんで
後からバリデーション追加しようとすると
アプリケーションの挙動によるんですけど
その不正なデータがいきなり壊れてしまうように見える
ちょっと困るのでまだバリデーションかけられないとか
そういう困ったところがありますね
スピーカー 3
でもカレンダーには欠かせない機能だし
タイムツリーだとめちゃくちゃ使われてるんじゃないですかね
この機能って
スピーカー 2
そうですよね
スピーカー 3
お誕生日とか何かの記念日とか
何か定期的に来る家事の予定とか
スピーカー 1
僕も不念ごみって入れてますもん
スピーカー 2
結構だから普通に使われるんですけど
タイムツリーにないデータだけでもそうだったりするんですけど
外部のカレンダーからそういうデータをインポートしてくれると
カレンダーその外部のカレンダー独自の仕様とかの
何これみたいなことになって
スピーカー 3
やばいですね
スピーカー 2
パルプンって食らったことがありますね
多分その普通のサービス
アイカレンダーRルール
インターネットの世界で標準化されてるものなんですけど
旧歴サポートしないんですね
外部のカレンダーでちょっとどういう経緯で入ってきたかとか
全然定かではないんですけど
1年に1回みたいな予定で
旧歴で1年に1回みたいな感じの
その謎データが入ってたりして
スピーカー 1
ん?ん?みたいな
スピーカー 2
旧歴?
旧歴わかるけどみたいな
タイムツリーも一応旧歴の
旧歴で1年に1回みたいな
確かサポートしてるはいるんですけど
Rルールに従うような形で
強引に解釈して書いてるところがあるんで
ちょっとデータ量として多くなったりとか
そういうのがあったりはするんですけど
Rルールを独自解釈した何かを
インポートされてくると動かないっていうやつが
ちょっと困りますね
プログラミング言語にRルールに従って
データを展開するようなライブラリーとか
存在してるんですけど
カレンダー開発の怖い話
スピーカー 2
壊れてるデータだといきなりエラーになるんで
そういうライブラリーが使えないっていうか
使うと壊れる
使うとそのデータがある人だけ
なんかよくわからないけど予定が壊れるみたいな
ちょっと謎現象も起こったりして
どうしたのかなって思ったことがありましたね
スピーカー 1
iOSは当初Rルール解釈するのに
なんかオープンソースのコードを持ってきて
それを独自にこちら側で書き換えた
独自のパーサを使ってたんですよ
怖いですよね
スピーカー 2
それ怖いですね
多分それの影響だと思うんですけど
Rルールの中に何月何日
繰り返し予定何月何日までっていうデータが入ってるんですよね
例えば2023年8月24日までみたいなデータがあるんですけど
表現としてはアラビア数字で
20、23、08、24って書かれてるんですけど
アラビア語の右読みの数字が書かれてることがあって
やばー
言語の変換が効いちゃって
数字がその
なんかうん?みたいな
そういう数字になってることもあるんですけど
アラビア数字じゃない
普通の数字って何?
スピーカー 1
アラビア数字は普通なんですけど
アラビア語の数字みたいなのかな
スピーカー 3
そうですね
見えますね
スピーカー 2
そうそうアラビア語の数字
判別できない
見すぎてだんだん読めるようになってきましたから
スピーカー 1
それってどういう経路で入ってきたのか謎なんですか
スピーカー 2
確かiOSの独自パーサーを使ってたから
使ってる人の言語によって
数字のデータがその言語で入っちゃう
そういうこと?
そうそれでアラビア語数字になっちゃって
サーバーにはそれで投稿されてきて
当然パーサーで読むと壊れる
他の言語のパーサーで読むと壊れるっていう
いいですね今シオンのいい渋い顔が見れましたよ僕
スピーカー 3
画面の向こうでこういう顔してんだろうなーみたいな
開発が大変なとき
スピーカー 1
本当だから独自パーサー使ってるときは
無限ループになる不具合とかあったりして
いろいろ大変だったんですけど
今はLibAicalっていう
繰り返し予定の問題と改善
スピーカー 1
C言語で書かれたライブラリを利用しているので
あんまり変なことは起きないはずなんですけど
外部のカレンダーからインポートできる機能があるので
それによってなんかよくわからない
繰り返し情報が入ってきて
なんかおかしいんですってお問い合わせが来て
データの中を見ると
このRルールはどうやって入力するんだみたいな
謎のものがいっぱいありますね
スピーカー 2
カレンダーサービスによって本当にオリジナルで定義している
標準をオリジナルで定義しないでくれって思いはいっぱいあるんですけど
スピーカー 3
ルールは守りましょう
スピーカー 2
それこそサーバーを最初そのバリデーション入れてなかったのもあって
そこら辺が全部すずおりしてたんですけど
バリデーションを厳しくすると突然予定がインポートできなくなった
ってお問い合わせが増えて
なんでか調べたらRルールのバリデーションが厳しすぎて落ちちゃったっていうのがあって
そのRルールを緩くするかどうかっていうのを一時期考えたことがあるんです
緩くすると逆にRルール全部消した
こっちのタイムツリーのやつで動かないので
どっちにしても繰り返し予定が繰り返し予定として表示されないんで
おかしいっていうふうになるはなるんですけど
スピーカー 3
結構最後に書いてありますけど
iOSのリポジトリでもイシュー件数が結構あるんですね
スピーカー 1
そうですね繰り返し予定に検索したら100件ぐらい出てきたんで
スピーカー 3
めちゃくちゃある
この繰り返し予定改善は未だに戦っているところなんですか
それとも結構技術不細は
スピーカー 1
これはもう一旦
めでたしめでたしっていうことになります
繰り返し予定を設定するUIも
いろんなパターンに対応しなきゃいけないので
UI関連の風が結構あったと思います
スピーカー 3
まあでも余談を許さない案件ってことですねこれは
スピーカー 2
そうですねどこまでそうやるかっていうところはありますね
ちゃんとしたいとか
スピーカー 1
そういうところもありますね
スピーカー 2
標準に従いたいなっていうのが
サーバーサイドのエンジニアとしては気持ちとしてはある
スピーカー 1
なるほど
スピーカー 3
2回にわたってお送りしましたけど
僕も最後が一番怖かったし
スピーカー 2
現在進行形の問題ですからね
スピーカー 3
かなり脳みそに混乱をきたしましたねこれは
スピーカー 2
繰り返し予定タイムゾーンの指定とかもあるんですけど
それもまた怖い話がちょっといつかあります
スピーカー 3
これって繰り返し予定と
何か前回の放送で出てきた
例えばサマータイムとか複合的に
スピーカー 1
複合的に絡んで
そう
より怖くなりますね
スピーカー 2
繰り返すと例えばその時間ないとかっていうのがあるじゃないですか
サマータイムを止めつける時間とか
どうなってんの
スピーカー 1
正直ちゃんと理解できてないです
スピーカー 2
どうなるのかわからないですね
多分人類にはちょっと早すぎる
面白い
繰り返しっていうのは
スピーカー 3
シオンで理解できてなかったらもうちょっと
誰もわからないみたいな
じゃあ2回に渡ってやりました怖い話ですが
今後も怖い話は定期的にしていきましょうね
スピーカー 2
夏だけにしましょうよ
スピーカー 3
毎夏だけね
暖まる話しましょうよ
そうですね
スピーカー 1
暖かくなる話もちょっとシオン待ってます
スピーカー 3
思いついたら
ありがとうございます
ありがとうございました
ありがとうございました