2012-02-09 2 views
3

У меня есть странная проблема с объектами datetime sqlite3 в Python 2.7. Запуск примера:Python datetimes в sqlite3

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'> 

DateTime retrived при использовании метода PARSE_COLNAMES кажется неправильным. Почему это?

Примечание Этот пример из Python docs

ответ

2

От выхода вы показываете, это выглядит как будто вы находитесь в Новой Зеландии часовой пояс (UTC-12 или UTC-11 с переходом на летнее время наблюдается). Проблема в том, как PARSE_COLNAMES использует конвертер для типов python - один из них находится в формате UTC, и один использует информацию о часовом поясе, доступную для вашего местного времени (и, да, я бы назвал это ошибкой в ​​конвертерах).

Смотрите ниже адаптеры, которые я использую для данных цен на акции каналы последовательно преобразовывать данные для часового пояса, что я знаю (вы можете настроить его в соответствии с часовым поясом, или добавить код для корректировки обнаруженного часового пояса):

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) 

Вы можете увидеть все это в действии в this bit of code на github.

+0

Спасибо, что поняли, что это была настоящая головная царапина – pearpenguin