2012-02-09 6 views
3

Python 2.7のsqlite3 datetimeオブジェクトに奇妙な問題があります。この例を実行:sqlite3のPython datetimes

import sqlite3 
import datetime 

con = sqlite3.connect(":memory:", detect_types=sqlite3.PARSE_DECLTYPES|sqlite3.PARSE_COLNAMES) 
cur = con.cursor() 
cur.execute("create table test(d date, ts timestamp)") 

today = datetime.date.today() 
now = datetime.datetime.now() 

cur.execute("insert into test(d, ts) values (?, ?)", (today, now)) 
cur.execute("select d, ts from test") 
row = cur.fetchone() 
print today, "=>", row[0], type(row[0]) 
print now, "=>", row[1], type(row[1]) 

cur.execute('select current_date as "d [date]", current_timestamp as "ts [timestamp]"') 
row = cur.fetchone() 
print today, "=>", row[0], type(row[0]) 
print now, "=>", row[1], type(row[1]) 

が私にこの出力を与える:

2012-02-10 => 2012-02-10 <type 'datetime.date'> 
2012-02-10 08:17:10.222291 => 2012-02-10 08:17:10.222291 <type 'datetime.datetime'> 
2012-02-10 => 2012-02-09 <type 'datetime.date'> 
2012-02-10 08:17:10.222291 => 2012-02-09 19:17:10 <type 'datetime.datetime'> 

PARSE_COLNAMESメソッドを使用している場合retrived日時が間違っているようです。何故ですか?あなたはニュージーランドのタイムゾーン(UTC-12または夏時間とUTC-11が観察されている)であるように、この例では、あなたが示す出力からPython docs

答えて

2

からである

注意、それが見えます。問題は、PARSE_COLNAMESがPython型にコンバータを使用していることです.1つはUTCで、もう1つはローカルタイムゾーンで使用できるタイムゾーン情報を使用しています(そして、これはコンバータでバグと呼ばれます)。

は、私は一貫して私は(あなたが検出されたタイムゾーンを調整するためにいくつかのコードを、あなたのタイムゾーンと一致するように調整し、または追加することができます)知っているタイムゾーンのデータを変換するために、フィード株価データ用に使用アダプタの下を参照してください。

def adapt_datetime(dt): 
    # Get the datetime for the POSIX epoch. 
    epoch = datetime.datetime.utcfromtimestamp(0.0) 
    elapsedtime = dt - epoch 
    # Calculate the number of milliseconds. 
    seconds = float(elapsedtime.days)*24.*60.*60. + float(elapsedtime.seconds) + float(elapsedtime.microseconds)/1000000.0 
    return seconds 


def convert_datetime(tf): 
    # Note: strange math is used to account for daylight savings time and 
    # times in the Eastern (US) time zone (e.g. EDT) 
    tf = float(tf) 
    edt_adjustment = 6 * 60. * 60. 
    if time.localtime(tf).tm_isdst: 
     edt_adjustment = 5 * 60. * 60. 
    return datetime.datetime.fromtimestamp(tf+edt_adjustment) 

sqlite3.register_adapter(datetime.datetime, adapt_datetime) 
sqlite3.register_converter("datetime", convert_datetime) 

これはすべてgithubのthis bit of codeに掲載されています。

+0

これをクリアしてくれてありがとう、本当の頭の傷だった – pearpenguin