RMagic使用時のTime.to_sの挙動がおかしい

続続続まで続いたパースエラーが止まらないの問題が解決したのでタイトルも改めて書き残します。
RMagickをrequireしてTime.to_sを行うと微妙に翻訳されていて、DateTime.parseにto_sした値を渡すと
月日がおかしな値に変わってしまう。

1.upto(12) do |month|
  dt = DateTime.parse(Time.mktime(2008,month,10).to_s)
  puts "#{month}月::#{dt.strftime('%Y/%m/%d')}"
end
1月::2008/02/10
2月::2008/02/10
3月::2008/02/10
4月::2008/02/10
5月::2008/02/10
6月::2008/02/10
7月::2008/02/10
8月::2008/02/10
9月::2008/02/10
10月::2008/02/10
11月::2008/02/11
12月::2008/02/12

これは、酷い。酷すぎる。月が全て2月に変更されている挙句、11月12月に関しては日までも変わってしまっています。


ちゃんと動くのを確認する用のテストを書いてみた。

require 'RMagick'
require 'date'
require 'test/unit'
class TimeParseTest < Test::Unit::TestCase

  def test_mktime_to_s
    t = Time.mktime(2008,2,4)
    assert_equal "Mon Feb 04 00:00:00 +0900 2008", t.to_s
  end

  def test_date_time_parse
    1.upto(12) do |month|
      dt = DateTime.parse(Time.mktime(2008,month,10).to_s)
      assert_equal "2008/#{sprintf('%02d',month)}/10", dt.strftime('%Y/%m/%d')
    end
  end

end

ubuntucentOSでは動かないことを確認出来ました(MacOSは大丈夫なようです)


何が悪さをしているのかは不明なのですが、おそらくRMagickの拡張ライブラリ(RMagick.so)内で
dateを使っているんじゃ無いかなぁと。拡張ライブラリでdateを使うと環境変数をみてしまうらしいです。
で、解決方法としてはごく簡単な方法で解決が出来ます。環境変数が影響しているならば環境変数を変えてしまえと。
ものすごい乱暴な解決方法です。

echo $LANG
ja_JP,UTF-8

上述のテストが動かない環境の場合は、おそらくLANGにja_JPが設定されていると思います。
そこで、環境変数LANGをCにしてしまえば問題なかろうということで

export LANG=C

これで、テストは通るようになったかと思います。
だがしかし、サーバであればこれでも問題ないのですが、日常的にクライアントや開発機として使っている場合
環境変数LANGの値を変更してしまうのは、ちょっとというか、かなり抵抗があると思います。
そこで、環境変数LC_TIMEをCに設定することでLANGに手を加えずにテストを通すことが出きるようになると思います。

echo $LANG
C
export LANG=ja_JP,UTF8
export LC_TIME=C

LANGよりもLC_*の方が優先されるはずなので、これで、ばっちりなはず。です。
ちなみにLC_TIMEは日時出力のロケールを設定する環境変数です。


今回の件で、google先生に色々聞いてみたのだが、全くと言って良いほど関連する情報がありませんでした。
RMagickって結構使われるライブラリだと思うし皆どうしてるんだろ??と、疑問に思ってみた。
っは!Rubyやってる人は皆MacOSなのに違いないぃぃぃ(違

  • 2007.2.05 追記

環境変数コマンドラインから設定しなくても

  ENV["LC_TIME"] = 'C'

で、問題が解決される事を確認.
railsを使っている場合にはenvironment.rbで環境変数を設定する。