Формат даты и времени Python, такой как C # String.Format - PullRequest
1 голос
/ 15 ноября 2010

Я пытаюсь портировать приложение с C # на Python.Приложение позволяет пользователю выбирать свой формат даты и времени, используя C # String.Format DateTime форматирование .Форматирование даты и времени в Python даже близко не совпадает, поэтому мне приходится перепрыгивать мой код через несколько циклов.

Есть ли какой-нибудь способ, которым Python может анализировать строки вроде yyyy-MM-dd HH-mm-ss вместо %Y-%m-%d %H-%M-%S?

Ответы [ 3 ]

3 голосов
/ 15 ноября 2010

Вы можете получить достаточное расстояние с помощью простой замены для преобразования строк формата.

_format_changes = (
    ('MMMM', '%B'),
    ('MMM',  '%b'), # note: the order in this list is critical
    ('MM',   '%m'),
    ('M',    '%m'), # note: no exact equivalent
    # etc etc
    )

def conv_format(s):
    for c, p in _format_changes:
        # s.replace(c, p) #### typo/braino
        s = s.replace(c, p)
    return s

Я предполагаю, что ваши "обручи" означают нечто подобное. Обратите внимание, что есть осложнения:
(1) формат C # может содержать буквальный текст, заключенный в одинарные кавычки (примеры в цитируемой вами ссылке)
(2) он, вероятно, позволяет сделать один символ буквальным, если экранировать его с (например) \
(3) Для 12- или 24-часовых часов может потребоваться дополнительная работа (я не углублялся в спецификацию C #; этот комментарий основан на другом подобном упражнении, в котором я участвовал). Вы можете написать компилятор и интерпретатор байт-кода, чтобы обойти все ошибки (такие как M, F, FF, FFF, ...).

Альтернативой для рассмотрения является использование ctypes или что-то похожее для прямого вызова C# RTL.

Обновление Исходный код был чрезмерно упрощенным и имел опечатку / брейно. В следующем новом коде показано, как решить некоторые проблемы (например, литеральный текст и обеспечить, чтобы литерал % во входных данных не делал strftime несчастным). Он не пытается дать точные ответы там, где нет прямого преобразования (M, F и т. Д.). Отмечаются места, где может быть возбуждено исключение, но код действует на основе принципа невмешательства.

_format_changes = (
    ('yyyy', '%Y'), ('yyy', '%Y'), ('yy', '%y'),('y', '%y'),
    ('MMMM', '%B'), ('MMM', '%b'), ('MM', '%m'),('M', '%m'),
    ('dddd', '%A'), ('ddd', '%a'), ('dd', '%d'),('d', '%d'),
    ('HH', '%H'), ('H', '%H'), ('hh', '%I'), ('h', '%I'),
    ('mm', '%M'), ('m', '%M'),
    ('ss', '%S'), ('s', '%S'),
    ('tt', '%p'), ('t', '%p'),
    ('zzz', '%z'), ('zz', '%z'), ('z', '%z'),
    )

def cnv_csharp_date_fmt(in_fmt):
    ofmt = ""
    fmt = in_fmt
    while fmt:
        if fmt[0] == "'":
            # literal text enclosed in ''
            apos = fmt.find("'", 1)
            if apos == -1:
                # Input format is broken.
                apos = len(fmt)
            ofmt += fmt[1:apos].replace("%", "%%")
            fmt = fmt[apos+1:]
        elif fmt[0] == "\\":
            # One escaped literal character.
            # Note graceful behaviour when \ is the last character.
            ofmt += fmt[1:2].replace("%", "%%")
            fmt = fmt[2:]
        else:
            # This loop could be done with a regex "(yyyy)|(yyy)|etc".
            for intok, outtok in _format_changes:
                if fmt.startswith(intok):
                    ofmt += outtok
                    fmt = fmt[len(intok):]
                    break
            else:
                # Hmmmm, what does C# do here?
                # What do *you* want to do here?
                # I'll just emit one character as literal text
                # and carry on. Alternative: raise an exception.
                ofmt += fmt[0].replace("%", "%%")
                fmt = fmt[1:]
    return ofmt

Проверено в следующей степени:

>>> from cnv_csharp_date_fmt import cnv_csharp_date_fmt as cv
>>> cv("yyyy-MM-dd hh:mm:ss")
'%Y-%m-%d %I:%M:%S'
>>> cv("3pcts %%% yyyy-MM-dd hh:mm:ss")
'3pc%p%S %%%%%% %Y-%m-%d %I:%M:%S'
>>> cv("'3pcts' %%% yyyy-MM-dd hh:mm:ss")
'3pcts %%%%%% %Y-%m-%d %I:%M:%S'
>>> cv(r"3pc\t\s %%% yyyy-MM-dd hh:mm:ss")
'3pcts %%%%%% %Y-%m-%d %I:%M:%S'
>>>
2 голосов
/ 15 ноября 2010

Сначала запустите несколько замен:

replacelist = [["yyyy","%Y"], ["MM","%m"]] # Etc etc
for replacer in replacelist:
    string.replace(replacer[0],replacer[1])
0 голосов
/ 15 ноября 2010

Боюсь, ты не сможешь.strftime () вызывает функцию strftime () базовой библиотеки C, которая, в свою очередь, принимает директивы форматирования точно в форме% X.Вам нужно написать несколько строк кода, чтобы выполнить преобразование.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...