Подтвердить что ты не робот

Есть ли способ использовать функцию strftime как даты до 1900 года в Python?

Я этого не понимал, но, по-видимому, функция Python strftime не поддерживает даты до 1900 года:

>>> from datetime import datetime
>>> d = datetime(1899, 1, 1)
>>> d.strftime('%Y-%m-%d')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: year=1899 is before 1900; the datetime strftime() methods require year >= 1900

Я уверен, что я мог сам что-то взломать, но считаю, что функция strftime существует по какой-то причине (и есть также причина, по которой она не может поддерживать даты до 1900 года). Мне нужно иметь возможность поддерживать даты до 1900 года. Я бы просто использовал str, но там было слишком много вариаций. Другими словами, он может иметь или не иметь микросекунды, или может иметь или не иметь часовой пояс. Есть ли какое-либо решение для этого?

Если это имеет значение, я делаю это, чтобы я мог записать данные в текстовый файл и загрузить его в базу данных с помощью Oracle SQL * Loader.

Я по существу закончил работу с Алексом Мартелли. Здесь более полная реализация:

>>> from datetime import datetime
>>> d = datetime.now()
>>> d = d.replace(microsecond=0, tzinfo=None)
>>> str(d)
'2009-10-29 11:27:27'

Единственное отличие состоит в том, что str(d) эквивалентно d.isoformat(' ').

4b9b3361

Ответ 1

isoformat работает с datetime экземплярами без ограничения диапазона:

>>> import datetime
>>> x=datetime.datetime(1865, 7, 2, 9, 30, 21)
>>> x.isoformat()
'1865-07-02T09:30:21'

Если вам нужна строка другого формата, она не слишком сложна для фрагментов, кубиков и ремиксов, которые вы получаете из isoformat, что очень согласовано (YYYY-MM-DDTHH:MM:SS.mmmmmm, с точкой и последующими микросекундами, опущенными, если микросекунды равны нулю).

Ответ 2

Документация выглядит довольно понятной:

Точный диапазон лет, для которых strftime() работает, также варьируется на разных платформах. Независимо от платформы, годы до 1900 года не могут быть использованы.

Таким образом, не будет решения, которое использует strftime(). К счастью, это довольно просто сделать это "вручную":

>>> "%02d-%02d-%02d %02d:%02d" % (d.year,d.month,d.day,d.hour,d.minute)
'1899-01-01 00:00'

Ответ 3

mxDateTime может обрабатывать произвольные даты. Модули Python time и datetime используют временные метки UNIX внутри, поэтому они имеют ограниченный диапазон.

In [5]: mx.DateTime.DateTime(1899)
Out[5]: <mx.DateTime.DateTime object for '1899-01-01 00:00:00.00' at 154a960>

In [6]: DateTime.DateTime(1899).Format('%Y-%m-%d')
Out[6]: 1899-01-01

Ответ 4

Это из источник matplotlib. Это может послужить хорошей отправной точкой для вашего собственного.

def strftime(self, dt, fmt):
    fmt = self.illegal_s.sub(r"\1", fmt)
    fmt = fmt.replace("%s", "s")
    if dt.year > 1900:
        return cbook.unicode_safe(dt.strftime(fmt))

    year = dt.year
    # For every non-leap year century, advance by
    # 6 years to get into the 28-year repeat cycle
    delta = 2000 - year
    off = 6*(delta // 100 + delta // 400)
    year = year + off

    # Move to around the year 2000
    year = year + ((2000 - year)//28)*28
    timetuple = dt.timetuple()
    s1 = time.strftime(fmt, (year,) + timetuple[1:])
    sites1 = self._findall(s1, str(year))

    s2 = time.strftime(fmt, (year+28,) + timetuple[1:])
    sites2 = self._findall(s2, str(year+28))

    sites = []
    for site in sites1:
        if site in sites2:
        sites.append(site)

    s = s1
    syear = "%4d" % (dt.year,)
    for site in sites:
        s = s[:site] + syear + s[site+4:]

    return cbook.unicode_safe(s)

Ответ 5

Это "функция" библиотеки ctime (UTF). Также у вас может быть проблема выше 2038.