2020/01/03

日付処理(1) - 日付・カレンダー処理の基礎知識

はじめに

アプリケーションエンジニアにとって、日付・カレンダーに関する業務ロジックを組み立てる機会はとても多いことと思います。最近の言語処理系はカレンダー管理系の標準ライブラリを持っていることが多いと思うので、正しく使いこなせればそれほど難しいことでは無くなってきています。

この記事では、日付・カレンダーに関する業務ロジックの典型的なものを Java, Python のコードスニペットとして紹介したいと思います。Java, Python における標準ライブラリを活用した実用的な例に加えて、日付・カレンダー処理に関する基礎知識とアルゴリズムも解説します。原理を把握したい方、便利なカレンダーライブラリの無い環境でどうしても実現しないといけない方などの参考にもなるかと思います。

日付・カレンダー処理の基礎知識

ちょっと回り道に感じるかもしれませんが、まずは基礎知識から説明しておきます。後述のロジック解説の前提知識になってきますので、初めに説明させてください。

現代の暦法はグレゴリオ暦

現代社会で主に使われているカレンダーは、グレゴリオ暦と呼ばれています。平均的に地球が太陽の周りを1周するのにかかる日数は、およそ365.2422日です。これに極力近づけるため、閏年を使って1年の平均日数を365.2425日にしたのが、グレゴリオ暦です。グレゴリオ暦は1582年10月15日からカトリック世界で使われはじめ、徐々に世界中に浸透していきました。日本では1873年1月1日から使われています。なお、グレゴリオ暦の前はユリウス暦が使われていました。ユリウス暦の1582年10月4日の翌日がグレゴリオ暦の1582年10月15日となっています。歴史上の日付は、1582年10月4日まではユリウス暦、1582年10月5日〜14日は存在せず、1582年10月15日以降はグレゴリオ暦として取り扱われることが通例となっています。

グレゴリオ暦を特徴付ける性質は、閏年のルールです。

  1. 西暦年が4で割り切れる年は閏年
  2. ただし、西暦年が100で割り切れる年は閏年としない
  3. でも、西暦年が400で割り切れる年はやっぱり閏年
となっています。これにより、400年に97回閏年が設定されることになり、平均すると1年当たり97÷400=0.2425日が追加されます。従って1年の平均日数が365.2425日となるわけです。ユリウス暦の閏年ルールは1番だけなので、1年の平均日数は365.25日でした。365.2422日との誤差を考えると、ユリウス暦では0.0078日なのに対し、グレゴリオ暦では0.0003日ですから、26分の1の誤差ということですね。

曜日はユリウス暦とグレゴリオ暦で連続している

ユリウス暦最後の日である1582年10月4日は木曜日で、グレゴリオ暦最初の日である1582年10月15日は金曜日でした。これは、曜日の連続性を保つため、意図的にそう定められました。そのため、ユリウス暦、グレゴリオ暦を通じて、通算日数を7で割った余りから、曜日を算出できます。通算日数として、ユリウス通日と呼ばれる紀元前4713年1月1日の正午を起点とした通算日数や、そこから2400000.5を引いた修正ユリウス日がよく用いられます。日付をユリウス通日や修正ユリウス日に変換することで、曜日計算や日数計算が容易にできます。

紀元1年の前年は紀元前1年

業務プログラミングで紀元前の日付を取り扱う機会はあまり無いと思いますが、紀元1年と紀元前1年の間に紀元0年のような年は存在しません。そのため、紀元前の年代をシステム的に表現する場合、紀元前1年を西暦0年、紀元前2年を西暦マイナス1年、…、紀元前x年を西暦1-x年のように表現するのが計算上都合が良いものとなります。

(2)へ続く

MacOSX の Python 環境構築

MacOSX の Python 環境を作ったので、メモ程度ですが記録しておきます。

とりあえずビール (Homebrew)

brew を使いますので、インストールしていない方は入れましょう。

pyenv の導入

pyenv を入れることで、複数の python バージョンを同時にインストールした状態で、切り替えて使うことができるようになります。

インストールと初期設定

brew install pyenv
~/.bashrc に以下のように追記しましょう。
eval "$(pyenv init -)"

python を pyenv の管理下にインストール

pyenv 管理下にインストールできるものは、
pyenv install --list
で確認できます。バージョンナンバーだけのものがプレーンな python です。2系と3系の最新を探すなら、
pyenv install --list |grep -v -- '-dev' |grep ' 2.' |tail -1
pyenv install --list |grep -v -- '-dev' |grep ' 3.' |tail -1
とすれば見付かると思います。インストールは
pyenv install 2.7.17
pyenv install 3.8.0
のように実行します。

使用する python バージョンを設定

pyenv global 3.8.0
とすれば、python コマンドは python-3.8.0 に紐付くようになります。

pipenv の導入

pipenv を入れると、python バージョンや pip モジュールの集まりを1つの環境として捉えて、それを切り替えて使うことができるようになります。

インストール

pip install --upgrade pip
pip install pipenv
ここまで手順通りに進めている方は pip が古い状態になっていることが多いと思いますので、先立って upgrade をしています。不要なこともあるかと思います。

ここまでで導入は完了です。

pipenv の使い方


pipenv 環境の作り方

環境用のディレクトリを1つ作り、そのディレクトリに対して pipenv コマンドで設定することで、環境が作れます。
mkdir ~/projects/hogeenv
cd ~/projects/hogeenv
pipenv --python 3.8.0

pipenv 環境の切り替え

cd ~/projects/hogeenv
pipenv shell
とすることで、当該環境を使う形でサブシェルが起動します (環境名がプロンプトで識別できます)。exit で離脱できます。

pipenv 環境への pip モジュールのインストール

pipenv shell 内で例えば
pipenv install mock
とすれば、mock モジュールが当該環境にインストールされます。
環境内と環境外で pip list を見てみると、隔離されていることが確認できます。

2020/01/01

明けましておめでとうございます

本年もよろしくお願いいたします。

初詣はまだ行っていないのですが、年末に故あって東京大神宮にお参りしておりました。東京大神宮は伊勢神宮の遥拝殿です。すなわち東京大神宮にお参りすれば、伊勢参りと同じ、ということです。私と妻は伊勢神宮のファンなので、東京大神宮はとてもありがたい神社です。結婚式もここで挙げました。

初詣はどこへ行けばいいのだろうと考えていました。神宮大麻、東京大神宮神符は授かりたいので、東京大神宮へは改めて行くつもりなのですが、やはり氏神様にお参りしないといけませんよね。番町の氏神様はどこなのか、調べてみたところ、実は山王日枝神社だそうなのです。なるほど、今年はお参りさせていただきます。

2019/11/25

Google Code Prettify を使う

Google Code Prettify は、HTML 文書上で様々なプログラミング言語のコード断片を綺麗に表示するための JavaScript ライブラリです。

Google Code Prettify の組み込み方

HTML 文書のヘッダに
<script src="https://cdn.jsdelivr.net/gh/google/code-prettify@master/loader/run_prettify.js"></script>
のように入れてあげるだけで、CDN 経由で Google Code Prettify が読み込まれます。

コード断片の書き方

コード断片の箇所では、
<pre class="prettyprint">
public static void main(final String[] args) {
  System.out.println("Hello, World!");
}
</pre>
のように <pre> ブロックを作ってあげれば、OKです。以下のような表示になります。
public static void main(final String[] args) {
  System.out.println("Hello, World!");
}
言語は自動判別されますが、うまく判別されないなどの理由で直接指定したい場合は class="prettyprint lang-lisp" のように指定できます。
また、class="prettyprint linenums" とすると、行番号が表示されます。

見た目のカスタマイズ

行番号は標準では5行ごとにしか表示されませんが、毎行表示したい場合は以下のように CSS 定義を上書きします。
<style>
.prettyprint ol.linenums > li {
  list-style-type: decimal; 
}
</style>
このブログのスタイルでは、1行が長いときに横に突き抜けてしまったので、横スクロールバーが出るように、以下のスタイルも加えました。
<style>
pre.prettyprint {
  white-space: pre;
  overflow: auto;
}
</style>

2019/11/15

Serverless Web のクライアントサイドは Vuetify.js が良さそうに見える

最近、Serverless Web システムを構築したいとしばしば考えています。
Server-side (Serverless なのに Server-side でいいのか?) は、AWS で Cognito, API Gateway, Lambda, DynamoDB とかでいいのかなと思うのですが、Client-side で悩んでいます。

Serverless Web の Client-side は、Vue.js なんかを使うのがおそらく一般的なんでしょう。Vue.js なら使ったことがあるので、私もそうしたいです。
しかし私は Web デザインのセンスが無いので、デザインテンプレート (テーマ) が使える仕組みが欲しいんです。従来のサーバー型の Web であれば、Drupal みたいな CMS を使えばいいわけですが、Serverless だとどうするのかな、と。

で、ちょっと調べてみたんですが、Vue Material とか Vuetify.js なんてフレームワークがあるんですね。どちらも Google の Material Design 仕様に沿ったフレームワークで、テーマ機構があり、有償・無償のテーマが配布されているようです。

ちょっと情勢を見てみると、Vuetify.js が優勢なようです。

一旦、Vuetify.js に狙いを定めて、キャッチアップしてみようかと思います。続報を待て。

2019/11/11

Blogger と Adsense

このブログは Blogger を使っています。

最初、Google sites で考えていたのですが、Adsense 広告が載せられないということで、断念しました。
次に考えたのが Drupal で、AWS 上に EC2 + RDS Aurora で Drupal 8 環境を作ってみたのですが、あまりに高コストで、やはり断念。

結局、Blogger に落ち着きました。

で、Blogger で Adsense を使う場合、管理画面の収益メニューから、Adsense に申し込めるようになったら申し込む、という手筈らしいので、がんばって記事を書きつつ、申し込めるようになるのを待ってました。
でもなかなかならない。

でも、ちょっと変わった手順で、Adsense が有効になりました。


  1. Adsense のガジェットが標準で埋め込まれているテーマを選択する
    (普通は、Blogger から Adsense を有効化するまで Adsense ガジェットが配置できない)
  2. Adsense 管理画面のサイトメニューの方で、このブログのドメインを登録する
  3. 審査が通ると、広告が有効化する
    (でも Blogger は Adsense が有効になっているとは認識していない模様)


果たしてこれで収益入るんでしょうか。ちょっと様子見ます。


2019/10/29

MacOSX + GIMP + HGP教科書体で困ったこと

当社の名刺は、プリントライさんから購入しています。
プリントライさんは、PNG ファイル等で入稿することができて、作成するための各種ツールのテンプレートも配布しています。
私は GIMP で作成して、PNG で入稿しています。

今日、ちょっと困ったことがありました。
新社員用の名刺を作ろうと思って、過去に作った名刺原稿 (GIMP の XCF ファイル) を開き、テキストレイヤーを編集しようとしてポイントした瞬間、フォントが何やら変わってしまいました。
フォントはHGP教科書体を指定しているレイヤーなのですが、半角英数記号が何やら似て非なる、しかも等幅のフォントに変わってしまったのです。もしかしたら幅が等幅になってしまったHGP教科書体なのかもしれませんが、私には字形がちょっと違う気がしました。

いつもと違うことは、元のファイルは普段 Windows の GIMP で触っていて、今回は初めて MacOSX の GIMP で開きました。MacOSX の方にもHGP教科書体はちゃんと入っていて、Font Book から参照できますし、Font Book 上はちゃんとプロポーショナルでした。

他のフォントをいろいろ指定してみたところ、リコーのHG系フォントだけが、HGP や HGS を使ってもプロポーショナルにならなくなっていて、他のフォントは大丈夫なようでした。
今のところ、リコーフォントの問題なのか、GIMP の問題なのか、MacOSX の問題なのか、さっぱり分かりませんが、ちょっとこの線でもう少し調べてみようかと思います。

2019/10/25

Jakarta EE 8 リリース

少し前の話ですが、9/10 に Jakarta EE 8 が Eclipse Foundation からリリースされました。Oracle によって策定されていた Java EE が Oracle を離れ、Eclipse Foundation の元で再出発したものが Jakarta EE であり、その初めての正式リリースということになります。

Jakarta EE に至る経緯

事の発端は2016年、JAVA EE GUARDIANS というコミュニティの立ち上げでした。

Java EE 8 Specification の策定は2014年9月に JCP で JSR 366 として始まりました。当初は2016年秋頃までに仕様を決定し、2017年後半頃には対応製品が市場に出回るようなスケジュール感でした。
Java EE は Oracle にオーナーシップがあるわけですから、然るべく Oracle を中心として仕様策定が推進されるべきなのですが、Oracle のコミットメントが低下し、仕様策定が遅延していました。そこに、JAVA EE GUARDIANS が現れます。JAVA EE GUARDIANS は、Oracle の Java EE に対するコミットメントの低さを突き付け、対応を迫りました。
その結果 Oracle は、Java EE 8 は2017年には仕様を決定してリリースすること、そして Java EE をオープンソース化して Eclipse Foundation へ引き渡すことを決めました。Java の商標は Oracle が持っているので、Java EE 改め Jakarta EE とすることになりました。

Jakarta EE 8、そして 9 へ

Eclipse Foundation は、まず名称とライセンスの切り替えを行い、Java EE 8 の完全互換である Jakarta EE 8 をリリースすることにしました。それがこの 9/10 にリリースされたものです。これにより、Java EE と Jakarta EE は連続的につながりました。Java EE 8 互換製品は Jakarta EE 8 互換製品でもあることになります。ここから、Jakarta EE 9
に向けて本当のスタートが切られることになるはずです。

2019/10/24

マネージャになりたくない若手テック系へ

ソフトウェア開発の現場では、「プロジェクトマネジメントとかやりたくない。ずっと現場でコード書いていたい。」という若者が割といます (あるいはおじさんもいます)。

今から8年くらい前だったか、後輩社員からこんな相談をされました。
「僕は、マネジメントとかあまり興味が無くて、出来ればずっとテック系でやっていきたいんです。先輩のようにテック系で出世したいです。どうしたら、そんなに幅広いテクニカルスキルを身に付けて、出世していけるんでしょうか?」

この人は、私のことを少し思い違いしているようでした。
「うちの会社は確かに、テック系で出世していくことが可能な会社だけど、僕は決してテック系で評価されてこの地位にいるわけではないよ。」

「Microsoft や amazon、facebook のような会社のコアチームに入れるような技術は僕には全然無いし、そういう指向でも無いよ。僕は、テックと同時にマネジメントやセールスの力を伸ばしていく方が出世できると思っているし、さらに言えば、最大限テックで活躍しようと思ったら、マネジメント力やセールス力を身に付けるのが近道だと思っている。僕は学生のときソフトウェア開発会社でバイトしていたんだけど、そのときのボスとこんな話をしたんだ。」

さらに遡るほど十数年……

仕事終わりでボスとサシ飲みしてました。かねてから思っていたことを聞いてみました。
私「なぜボスは、自分で営業に出て、自分でPMもやってるんですか? テクニカルなことが好きそうに見えるので、営業やPMってあまりやりたくないんじゃないですか?」

この会社は、200人くらいの中堅ソフトウェアハウスで、パッケージ製品もあるし、受託開発もやっている会社です。ボスはそこの課長で、自分で案件を獲得して、自分でプロジェクトを回して、時にはコードも書いたりしています。新しい技術情報に常に目を光らせていて、日々調査したり検証したりしています。とてもテクニカルが好きな人に見えていたので、そんな質問をしてみたのです。

ボス「だって自分で仕事取ってきて、自分でそのプロジェクト回すのが、一番自由に好きな技術を使えるじゃん?」

目から鱗でした。テクニカルエンジニアは、技術で問題解決することが最大の喜びですから、そのシチュエーションを自分で作り出すことができれば、それがベストです。
もちろん、エンジニアのひとりよがりにならないためには、お客様の問題解決に寄与する最適な技術を選定しなければならないので、エンジニアとしての技術の引き出しはたくさん持っていなければなりません。でもバリバリのテクニカルエンジニアなら、それこそ Welcome!
この日を境に私は、PMも営業もやってみようと思うようになったのです。

さて話は後輩君に戻って……

後輩「先輩ほどの技術力があっても、テック系とは言えないというのは衝撃です。でも技術力を最大限行使するにはPMという立場はとても良いというのは納得しました。機会があればチャレンジしたいと思います。」

彼はその後しばらくして一度退職したのですが、さらに数年して舞い戻ってきました。そして、例によってこんな話をしたことを忘れている私に、また思い出させてくれたのです。
彼は今、技術力に裏付けられたマネージメントのできる、優秀はプロジェクトマネージャとして、大活躍中です。


2019/10/23

それって本当にモチベーションの問題?

昔々、今から13年ほど前のことだったか。
後輩社員と、当人の人事評価面談をしていたときのこと。

「最近、仕事のモチベーションが上がらないんです。」と言うのです。

それに対する私の応答はこうでした。
「仕事をするのにモチベーションは要らない。」

モチベーションって何だっけ?

私はこう続けました。
「給料分の仕事をするのは勤め人の義務であって、仕事をするということについてモチベーションは関係ない。モチベーションというのは、自分を給料分以上に、より高めるために必要なものだ。」

こんな話をしたことを私はすっかり忘れていたのですが、数年前に当人が退職することになり、その挨拶でこの話を思い出させてくれました。この話をいつも胸に留めてくれていたそうです。

モチベーションとは、日本語で言うと「動機付け」。何かに取り組むときに、理由や目的を明確にして、やる気を出すことです。この理由や目的は、個人に帰属するものです。これをやると出世できるとか、新しいスキルを身に付けることで市場価値が上がるとか、特別ボーナスがもらえるとか、そういったものです。

モチベーションでなければ何なんだ?

では、通常の仕事をこなすのに必要な「やる気」って、モチベーションでないのなら、何と呼べばいいのでしょう?
ちょっと考えてみたのですが、おそらく「モラール」、すなわち「士気」かなと思いました。モラールというのは、組織における義務を果たすという意味でのやる気です。戦争で兵隊が敵に果敢に向かっていく原動力がモラールです。

モチベーションとモラールを対比している人が居るのではないかと思って、ちょっと検索してみたら、こんな記事がありました。

この記事を見ていても思いますが、どうも近年、モチベーションモチベーション言いすぎて、モラールのことを蔑ろにしてきた感があります。
給料分の仕事をこなすモラールと、個々人が自分のために成長していくモチベーションをそれぞれ高めてあげるのが、先輩社員の役割かなと思います。モラールとモチベーションの両輪によって、社員個人と会社はWin-Winの関係が作れると思うのです。