win32comでExcelにアクセスした実験です.
Excelファイルのセルから日付を取得してpythonのdatetime.dateインスタンスにしたい.
とりあえずValueをゲット.(初期化とかは省略)
>>> tmp = xlApp.Workbooks(u"example.xls").Worksheets(u"hoge").Range("A1").Value >>> print tmp 04/29/06 00:00:00
確かに日付を取得できるけど,この文字列を利用すると2100年問題を抱えてしまう(笑)
Excelの日付は内部的にエポックからの整数値で表されるとのこと.つまり
>>> tmp = xlApp.Workbooks(u"example.xls").Worksheets(u"hoge").Range("A1").formula >>> print tmp u'38836'
これで取得できました.問題ないか確かめてみよう.確か1900年1月1日から数えてるんだから,
>>> import datetime >>> exceldef = datetime.date(1900,1,1) >>> exceldef+datetime.timedelta(38836) datetime.date(2006, 5, 1)
日付がずれています.Excelのデータは1900/1/1が「1」になって,datetime.timedeltaは差を表してるわけだから,1を引かなければいけないようです.
>>> exceldef+datetime.timedelta(38836-1) datetime.date(2006, 4, 30)
まだ,1日ずれている.セルに入力して確かめたところpythonのdatetime.dateでは1900/2/29が無い*1がExcelでは1900/2/29が表現できてしまうようだ.*2.なんでこんなになってるのかと思って検索してみるとJoelのエッセイが引っかかった.今年の6月のだから新しいな…最近全然エッセイWatchしてないな…
はじめてのBillGレビューのこと - The Joel on Software Translation Project
なるほど…1900年.しかしコードで-2なんてマジックナンバー使うのもいやで.
このオブジェクトにはFormatというメソッドが一つだけあります.http://www.python.jp/doc/2.4/lib/module-time.html#l2h-1915に日付時刻表現のdirectiveがあるのでこれを当てはめてみると,
>>> tmp.Format("%Y") '2006' >>> isinstance(tmp, datetime.time) False
という風にstrftimeメソッドのdirectiveがほぼ通用することがわかりました.結局Excelのセルの値をpythonのdatetime.data型に入れるには,
tmp = xlApp.Workbooks(u"example.xls").Worksheets(u"hoge").Range("A1").Value date = datetime.date(int(tmp.Format("%Y")),int(tmp.Format("%m")),int(tmp.Format("%d")))
というふうに使えばいいかもしれません.IDLEでセルから取得したオブジェクトをそのまま表示すると