Потеря информации PyQt4 PostgreSQL QSqlQuery BC
Потеря информации PyQt4 PostgreSQL QSqlQuery BC
Я программирую на PyQt4 и PostgreSQL, и у меня проблемы с чтением дат до Рождества Христова (BC). С psql все ок:
# SELECT id, born, givname FROM person WHERE id=100000;
id | born | givname
--------+---------------+---------
100000 | 0428-01-01 BC | Plato
(1 row)
Но кажется, что знак года, то есть информация BC/AD, теряется где-то на пути от сервера PostgreSQL к классу PyQt QSqlQuery.
посмотрите этот фрагмент кода Python:
from PyQt4.QtSql import QSqlQuery
sql = 'SELECT born FROM person WHERE id=100000'
query = QSqlQuery(sql)
query.next()
v = query.value(0)
print "v:", v
print "type:", type(v)
print "typename:", v.typeName()
d = v.toDate()
print "valid:", d.isValid()
print "d:", d, d.toString()
print 'dd.MM.yyyy:', d.toString('dd.MM.yyyy')
print "year:", d.year() # should be negative
print "toPyDate:", d.toPyDate()
print "toJulianDay:", d.toJulianDay()
выход:
v: <PyQt4.QtCore.QVariant object at 0xb216cd84>
type: <class 'PyQt4.QtCore.QVariant'>
typename: QDate
valid: True
d: PyQt4.QtCore.QDate(428, 1, 1) So. Jan 1 428
dd.MM.yyyy: 01.01.0428
year: 428
toPyDate: 0428-01-01
toJulianDay: 1877385
Вопрос: Где потеряна информация BC и как ее получить?
Ответы на вопросы авторов:
Какое фактическое целочисленное значение юлианского дня хранится в базе данных?
volker=# SELECT id, born, extract(julian from born), givname FROM person WHERE id=100000;
id | born | date_part | givname
--------+---------------+-----------+---------
100000 | 0428-01-01 BC | 1565102 | Plato
В PostgreSQL: (www.postgresql.org/docs/9.0/static/functions-formatting.html) Юлианский день (дни с 24 ноября, 4714 г. до н.э. в полночь) PostgreSQL возвращает 0 для SELECT EXTRACT(JULIAN FROM '4714-11-24 BC':: ДАТА);
Qt имеет другое определение для юлианского дня. От pyqt.sourceforge.net/Docs/PyQt4/qdate.html#fromJulianDay: "Диапазон допустимых дат от 2 января 4713 г. до н.э., ...". (Может быть, в этом и заключается разница между пролептическим юлианским календарем и пролептическим григорианским календарем, как в посте Эхуморо.)
Обратите внимание, что 1 января 4713 г. до н.э., кажется, не считается действительным:
>>> j1 = QDate.fromJulianDay(1)
>>> print j1.getDate()
(-4713, 1, 2)
>>> print j1.toString()
Di. Jan 2 -4713
>>> j0 = QDate.fromJulianDay(0)
>>> print j0.toString()
>>> print j0.getDate()
(-4713, 1, 1)
Но какова фактическая стоимость, хранящаяся в базе данных? Я не знаю, что сервер хранит внутри, я беру в качестве ссылки только то, что он передает клиенту psql, и это похоже на строку даты ISO, формат YYYY-MM-DD, с добавлением "BC" в течение BC лет, Кстати, читая https://en.wikipedia.org/wiki/ISO_8601 кажется, что нотация BC - это не ISO, а знак года. Это приводит к следующему вопросу: могу ли я настроить сервер так, чтобы он выдает "-0428-01-01" вместо "0428-01-01 BC"?
1 ответ
ОК, это скорее обходной путь, чем решение, но, как предположил Эхуморо, я могу получить дату в виде строки (соответственно, TEXT в PostgreSQL), просто так:
SELECT born::TEXT FROM person WHERE id=100000;
давая результат:
0428-01-01 BC
как строка, которую я могу разобрать для суффикса BC.
Использование целочисленных значений также возможно, но тогда мне приходится иметь дело с разницей между пролептическими юлианскими (Qt) и алептическими григорианскими (PostgreSQL) датами, которая кажется более сложной.