Monthly Archives: October 2014

Yosemiteのウインドウの緑ボタンは最大化でなくフルスクリーン

Yosemiteのウインドウのタイトルバーにある左側のボタンがすっかりデザインが変わりましたが、もっと重要な違いがあります。緑のボタンをクリックすると、今までは最大化されましたが、Yosemiteではフルスクリーンモードになります。

スクリーンショット 2014-10-17 17.49.05

一方、タイトルバーをダブルクリックするか、あるいはoptionキーを押しながら緑のボタンをクリックすることで、従来の「ウインドウ最大化」と戻しができます。ただし、Chromeではタイトルバーをダブルクリックでは最大化されないので、アプリケーションの実装によりできない場合もあるかも。

緑のボタンを押してフルスクリーンにしてしまうと、メニューはでなくなります。また、タイトルバーの右端にあったフルスクリーンから戻すボタンもなくなってしまって一瞬慌てます

shot1110-1

元に戻すには、ポインタを画面上部に移動させます。すると、メニューも出ますし、緑色のボタンも出てきます。再度緑のボタンを押せば、元に戻ります。他には、「フルスクリーンを解除」のメニュー項目を探すのもいいでしょう。さらに、トラックパッドであれば、3本指スライドで、別のアプリケーションに移動するという方法もあります。もちろん、この方法は、フルスクリーンのままに、別の画面に切り替わります。

shot1111-1

ちなみにMavericksではこうでした。フルスクリーンにしたら、ウインドウの右側に戻すボタン領域が作られていましたが、Yosemiteではそれがなくなりました。

スクリーンショット 2014-07-28 2.50.37

 

Yosemiteのmanは2本指スライドでスクロールするぞ!!

Yosemiteを入れた方、ターミナルを起動して、たとえば、「man diskutil」と入れてください。長いmanをスクロールするのは、えーっとcontrlなんだっけ〜と思う前にトラックパッドで2本指でスライドさせてください。なんと、manがスクロールします。Linuxマシンにつないでもできますよ。

ということで、manというより、Terminal.appの動作がトラックパッドに最適化されたってことですが、わかりやすいタイトルをつけてみました。

[IM]ContributorとSpecial Thanksの定義

ReadmeなどにINTER-MediatorのContributorとSpecial Thanksの項目があって、ともかく英語で書いてありますが、この区分をいちおうきちんと定義しておきます。もちろん、状況に応じてルールの増減はあります。

Contributor

  • コア部分に関連するソースコードをコミットあるいは提供した
  • レポジトリにまとまったサンプルを提供した
  • 開発進行において重要な決定を下し、それを遂行した
  • Webサイトを主体的に編集した。あるいはWebサイトにまとまったページを作成した
  • 貢献順。たとえば、コードの行数など。判断はとりあえず新居が行う

Special Thanks

  • バグレポートを具体的にコミュニティに公開した
  • イベントやサイト運用などのコミュニティ活動を支えた
  • 順番は姓のアルファベット順、Contributorになればこちらのリストからは落とす
  • 通常は氏名のみ、つまり組織名は書かないが、希望があれば書きますよ

こんなところかと思いますが、ご意見ありますでしょうか?

[IM]日付時刻関数の実装

INTER-Mediatorに日付時刻関数を実装しようとしています。というか、少し実装しました。とりあえずの目標はマニュアルに書いた関数のサポートです。クライアントサイドで動かすので、JavaScriptの仕組みとうまく連動させないといけません。しかし、そのままのスペックはちょっとどうかと思い、このような仕組みを考えました。

日付や時刻は原則として整数あるいは小数点数を取るにしても、連続した数値になります。この点は問題ないのですが、JavaScriptなら1ミリ秒が「1」、Excelだと1日が「1」というように、そのルールを知らないといけませんし、処理系によっては1秒が1の場合もあります。覚えておけばいいといえばいいのですが、決まっているから書かないという状況になると、つどつど調べないといけません。これは不便です。

この1単位の問題に加えて、データベースでは、DATE、TIME、DATETIMEという3つの型を併用します。もちろん、1ms=1にまとめるメリットはあるかと思いますが、あえて、INTER-Mediatorの中では、2つのスタンダードを作ることにしました。

  • 1日=1、つまり、DATE型フィールドに対応(date関数で生成=日付データ)
  • 1秒=1、細かい点はさておいて、TIME、DATETIMEに対応(datetime関数で生成=日時データ)

とします。日付の計算は日単位、日付時刻の計算は秒単位とするわけです。つまり、

  • date(‘2014-10-8’) – date(‘2014-10-6’) → 2
  • datetime(‘2014-10-8 09:00:00’) – datetime(‘2014-10-6 21:00:00’) → 129,600(36時間)

とすることで、データベースの型と、日付時刻関数の結果の対応付けを考えました。

ちなみに、JavaScriptではなぜgetMonth関数だけが0〜11になって実際の月の数値を得るには+1しないといけないのかとか、見方を変えればgetDate関数が0スタートになっているべきなのではなど、疑問は多々わきます。日付計算のしやすさなどの理由はあるかもしれませんが、ここがけっこうJavaScriptのはまりどころだったりします。

そこで、日付時刻の要素取得(つまり月や日を数値として取り出す)関数と、特定の要素に対する計算を行う関数を用意すれば、結果的には「見える通りの数値」として扱えるのではないかと考えました。たとえば、月を得る関数がmonth()だとして、11月なら11という数字が得られ、加えて3ヶ月後などの日付を求めるaddmonth(d, x)があれば用途は足りると考えたわけです。しかし、日付と日時というダブルスタンダードを持ち込むデメリットがここで発生します。整数化された数値を見て、どちらの型なのかがわかりません。結果的に、

  • 日付データの月を返す:monthd(x)
  • 日時データの月を返す:monthdt(x)
  • 日付データに指定した月数を加えた値を返す:addmonthd(x)
  • 日時データに指定した月数を加えた値を返す:addmonthdt(x)

という手法にならざるを得ないと考えました。関数が増えるだけ面倒もあるかもしれませんが、要素取得や計算の関数の末尾が「d」なのか「dt」なのかという点を注意すればいいので、さほどややこしいルールとも考えられません。

しかし、このままだと、month関数やaddmonth関数の存在が気になります。「なし」でもいいのですが、名前的にはもったいないです。考えたのは、なんらかの設定で、日付計算するか、日時計算するのかということを、定義ファイル上のオプション指定で決められるようにするという手法です。たとえば、デフォルとは日付としても、何かの指定をすれば日時になるという具合です。キーワードなどはまだ考えていません。つまりこういう関数があるということです。

  • 月を返す(単位は設定依存):month(x)
  • 指定した月数を加えた値を返す(単位は設定依存):addmonth(x)

 

関数の数は増えますが、把握できる内容ではないかと思います。

タイムゾーンもまともに考えれば頭が痛いですが、日時の解釈の問題と考え、そしてデータベース内ではタイムゾーンは一定にする、あるいはしたいぞと思うことが普通なので、日付あるいは日時データの書式化の問題かとも考えていますが、ここはまだじっくり考えていません。

以上のような方針で実装を考えていますが、どうでしょうか?ちなみに、今現在レポジトリにあるものは、date関数とdatetime関数は実装されています。

JavaScriptの日付のパースはあまりに微妙

JavaScriptの日付や時刻の処理ははまりどころが多いのでも有名ですが、こんなはまりポイントを発見したので、まとめておきます。JavaScriptのDateクラスを使えば日付時刻を記録できるオブジェクトです。getTime()メソッドで1970年1月1日からのミリ秒経過時間(基準からの経過時間)を得て計算するのが一般的なパターンです。文字列で与えられた日付や時刻があったとき、Dateクラスのスタティックメソッドのparseにより、基準からの経過時間が得られます。MDNのドキュメントには、RFC2822 or ISO 8601に従った文字列ならOKとなっています。前者は「Oct 5, 2014」、後者は「2014-10-05」といった文字列です。

では、「2014-10-5」でも一瞬いいのじゃないかなと思って調べてみました。実は、この形式はISO 8601のルール上では間違いです。月と日は常に2桁である必要があります。まず、Chromeです。最初の2行を見れば、一見すると、2014-10-05でも、2014-10-5でもいいように見えます。しかし、Date.parse()の数値を見ると、右側の実行結果の2行目になりますが、ちょっとだけ違う数値になっています。3月3日について、月日の1ないしは2桁の全ての組み合わせてやってみたのが、引き続く4行です。最初の2行に戻ると、9時間の差があります。

shot8846

つまり、Chromeでは、ISO 8601に従った「2014-10-05」は、日本時間の10月5日のAM 9:00であり、そうでないものは標準時での10/5 0:00になるとうことですね。つまり、日本時間にすると9時間前なので、ちょっとだけ小さな数字になります。

Firefoxを見てみましょう。なんと、「2014-10-5」などのISO 8601のルールをはずれたものは、エラーとなります。正しいといえば正しい。

shot8847

Chromeで次のような式を計算したら、-1になったんですよね。0になることを期待しますが、そうではなかった。それで気づきました。それに、Firefoxでは結果がでないということもありますね。

Date.parse("2014-10-5") / (60*60*24*1000) - Date.parse("2014-10-05") /(60*60*24*1000)

ほんとにはまりどころ満載です。