[PHP]第53週の週番号が「01」になる件に対応する関数を書いた

※下書き段階で投稿してしまったので、再投稿

PHPのdate(‘W’)が返す週番号は、第53週では’01′を返します。strftime(‘%W’)も同様です。

この仕様は、ISO規格に基づいています。

http://ja.wikipedia.org/wiki/ISO_8601#.E5.B9.B4.E3.81.A8.E9.80.B1.E3.81.A8.E6.9B.9C.E6.97.A5

以下、上記Wikipedia記事より引用

この挙動は、PHPのバグではありません。しかし、PHPアプリケーションにおいてバグを作りこみがちな挙動の1つだと思います(実際、私も2014年最初に修正したバグは、この挙動に起因するバグでした)。

以下は、上記条件の場合には、’01′ではなく’53′を返す関数です。

「53」を返す処理については、仕様通りに「月日」+「曜日」で判定を行っています。ただ、この関数が必要な場合というのは、「01」が返されて困る場合に「53」を返すことだと思います。したがって、処理方法(2)でも、実用上は問題無いでしょう。

以下は、テスト付きのバージョンです。phpコマンドで実行して、結果が「ok」ならテストに合格したことになります。また、TAPに基づいたテストなので、proveコマンドでもテストできます(proveで実行するため、1行目にシバンを付けています)。

『Head First C』第5章 構造体、共用体、ビットフィールド

構造体

  • structは、一連の他のデータ型から作成したデータ型である
  • structは固定長である
  • structフィールドは、.<field_name>という構文を使って名前でアクセスする
  • structフィールドは、コードの順序と同じ順序でメモリに格納される
  • structは入れ子にできる
  • typedefはデータ型のエイリアスを作成する
  • structでtypedefを使う場合は、structの名前を省略できる

構造体とポインタ

  • 関数を呼び出すと、値はパラメータ変数にコピーされる
  • 他の型と同様に、structへのポインタを作成できる
  • pointer->fieldは(*pointer).fieldと同じである

共用体とビットフィールド

  • unionは、同じメモリ位置に異なるデータ型を格納できる
  • 指示付き初期化子は名前でフィールド値を設定する
  • 指示付き初期化子はC99で使える。Objective-Cでは使えるが、C++ではサポートされていない。
  • 中括弧({})で値を指定してunionを宣言すると、その値を最初のフィールドの型で格納する
  • unionのあるフィールドに書き込んだ値を別のフィールドとして読みだす場合、コンパイラは警告を出さない
  • enumはシンボルを格納する
  • ビットフィールドは任意のビット数でフィールドを格納できる
  • ビットフィールドはunsigned intとして宣言すべきである

『Head First C』第4章 複数のソースファイルの利用

Cのデータ型

char:文字コードの数値
int:整数(少なくとも15ビット)
short:整数(intの半分)
long:整数(少なくとも32ビット)
float:浮動小数点数
double:倍精度浮動小数点数

関数宣言

  • コンパイラは未知の関数への呼び出しがあると、その関数がintを返すとみなす
  • そのため、関数を定義する前に呼び出すと、問題となる場合がある
  • 関数宣言は、関数を定義する前に関数の概要をコンパイラに知らせる
  • 関数宣言をソースコードの先頭に記述すると、コンパイラが戻り値の型で混乱することはない
  • 関数宣言は、多くの場合、ヘッダファイルに入れる
  • #include を使って、コンパイラにヘッダファイルの内容を読み込むよう指示できる
  • #include <ファイル名>とすると、コンパイラは標準ヘッダファイルのディレクトリからファイルを探す
  • #include “ファイル名”とすると、コンパイラは現在のディレクトリからファイルを探す

コードの共有

  • コードを共有するには、そのコードを別のCファイルに入れる
  • 関数宣言は別の.hヘッダファイルに入れる
  • 共有コードを使いたいCファイルで、そのヘッダファイルをインクルードする
  • コンパイラコマンドでは、必要となる全てのCファイルを列挙する

例:hide_massage.cで、共有コードencrypt.cを使う場合
(1) encrypt.cの冒頭で #include “encrypt.h”
(2) hide_message.cの冒頭で、 #include “encrypt.h”
(3) コンパイラコマンドで、必要となる全てのCファイルを列挙:gcc hide_message.c encrypt.c -o hide_message

コンパイル時間の短縮(オブジェクトコードのキャッシュとmakeによる自動化)

  • 大量のファイルをコンパイルする場合、長い時間がかかることもある
  • オブジェクトコードを*.oファイルに格納すると、コンパイル時間を短縮できる
  • gccは、ソースファイルだけでなくオブジェクトファイルからもプログラムをコンパイルできる
  • makeツールはビルドの自動化に利用できる
  • makeはファイル間の依存関係を知っているので、変更したファイルだけをコンパイルできる
  • makeには、makefileを使ってビルドについて知らせる必要がある
  • makefileでは、行のインデントには空白ではなくタブを使う