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

Есть ли эквивалент Python для С# DateTime.TryParse()?

Есть ли в Python эквивалент С# DateTime.TryParse()?

Я имею в виду тот факт, что он избегает исключения, а не тот факт, что он угадывает формат.

4b9b3361

Ответ 1

Если вы не хотите исключения, перехватите исключение.

try:
    d = datetime.datetime.strptime(s, "%Y-%m-%d %H:%M:%S")
except ValueError:
    d = None

В дзен Python явное лучше, чем неявное. strptime всегда возвращает дату и время, проанализированные в указанном формате. Это имеет смысл, потому что вы должны определить поведение в случае сбоя, может быть, то, что вы действительно хотите.

except ValueError:
    d = datetime.datetime.now()

или

except ValueError:
    d = datetime.datetime.fromtimestamp(0)

или

except ValueError:
    raise WebFramework.ServerError(404, "Invalid date")

Делая это явным, он ясно показывает следующему человеку, который его читает, что такое аварийное переключение, и что это именно то, что вам нужно.


Или, может быть, вы уверены, что дата не может быть недействительной; это происходит из базы данных DATETIME, столбца, в этом случае не будет исключений для перехвата, поэтому не перехватывайте его

Ответ 2

Мы хотим try...catch использовать несколько форматов даты и времени fmt1,fmt2,...,fmtn и подавлять/обрабатывать исключения (из strptime) для всех тех, которые не соответствуют друг другу (и, в частности, избегать необходимости в юкки-n-глубокой лестнице с отступами из предложений try..catch). Я нашел два элегантных способа, второй лучше вообще. (Это большая проблема для данных реального мира, где несколько, несовпадающих, неполных, несовместимых и многоязычных/региональных форматов даты часто свободно смешиваются в одном наборе данных.)

1) Индивидуально попробуйте применить каждый формат и обработать каждый отдельный сбой strptime() как возвращаемое значение None, чтобы вы могли связывать вызовы fn...

Для начала, адаптируясь из ответа @OrWeis для компактности:

def try_strptime_single_format(s, fmt):
    try:
        return datetime.datetime.strptime(s, fmt)
    except ValueError:
        return None

Теперь вы можете вызывать как try_strptime(s, fmt1) or try_strptime(s, fmt2) or try_strptime(s, fmt3) ..., но мы можем улучшить это следующим образом:

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

Более простой, понятный и более понятный для OO - это обобщить это, чтобы сделать параметр formats единственной строкой или списком, а затем выполнить итерацию по этому..., чтобы ваш вызов сократился до try_strptime(s, [fmt1, fmt2, fmt3, ...])

def try_strptime(s, fmts=['%d-%b-%y','%m/%d/%Y']):
    for fmt in fmts:
        try:
            return datetime.strptime(s, fmt)
        except:
            continue

    return None # or reraise the ValueError if no format matched, if you prefer

(В качестве боковой панели обратите внимание, что ...finally не тот дроид, которого мы хотим, так как он будет выполняться после каждого прохода цикла, т.е. в каждом подходящем формате, а не один раз в конце цикла.)

Я нахожу реализацию 2) чище и лучше. В частности, функция/метод может хранить список форматов по умолчанию, что делает его более отказоустойчивым и менее подверженным исключениям в реальных данных. (Мы могли бы даже определить, какие форматы по умолчанию применять на основе других столбцов, например, сначала попробуйте немецкие форматы даты на немецких данных, арабский на арабском, форматы даты и времени в блоге и другие данные)

Ответ 3

Нет, то, о чем вы просите, не является идиоматическим Python, и поэтому обычно не будет функций, которые отбрасывают такие ошибки в стандартной библиотеке. Соответствующие стандартные библиотечные модули описаны здесь:

http://docs.python.org/library/datetime.html

http://docs.python.org/library/time.html

Функции синтаксического анализа все вызывают исключения при недопустимом вводе.

Однако, как заявили другие ответы, было бы сложно построить один для вашего приложения (ваш вопрос был сформулирован "в Python", а не "в стандартной библиотеке Python", поэтому неясно, если помощь написана такая функция "в Python" отвечает на вопрос или нет).

Ответ 4

Здесь реализация эквивалентной функции

import datetime

def try_strptime(s, format):
    """
    @param s the string to parse
    @param format the format to attempt parsing of the given string
    @return the parsed datetime or None on failure to parse 
    @see datetime.datetime.strptime
    """
    try:
        date = datetime.datetime.strptime(s, format)
    except ValueError:
        date = None
    return date

Ответ 5

Грубая сила также вариант:

def TryParse(datestring, offset):
    nu = datetime.datetime.now()
    retval = nu
    formats = ["%d-%m-%Y","%Y-%m-%d","%d-%m-%y","%y-%m-%d"]  

    if datestring == None:
        retval = datetime.datetime(nu.year,nu.month,nu.day,0,0,0) - datetime.timedelta(offset,0,0,0,0,0,0)
    elif datestring == '':
        retval = datetime.datetime(nu.year,nu.month,nu.day,0,0,0) - datetime.timedelta(offset,0,0,0,0,0,0) 
    else:
        succes = False
        for aformat in formats:
            try:
                retval = datetime.datetime.strptime(datestring,aformat)
                succes = True
                break
            except:
                pass
        if not succes:
            retval = datetime.datetime(nu.year,nu.month,nu.day,0,0,0) - datetime.timedelta(offset,0,0,0,0,0,0) 
    return retval

Ответ 6

Используйте time.strptime для анализа дат из строк.

Документация: http://docs.python.org/library/time.html#time.strptime

Примеры из: http://pleac.sourceforge.net/pleac_python/datesandtimes.html

#----------------------------- 
# Parsing Dates and Times from Strings

time.strptime("Tue Jun 16 20:18:03 1981")
# (1981, 6, 16, 20, 18, 3, 1, 167, -1)

time.strptime("16/6/1981", "%d/%m/%Y")
# (1981, 6, 16, 0, 0, 0, 1, 167, -1)
# strptime() can use any of the formatting codes from time.strftime()

# The easiest way to convert this to a datetime seems to be; 
now = datetime.datetime(*time.strptime("16/6/1981", "%d/%m/%Y")[0:5])
# the '*' operator unpacks the tuple, producing the argument list.

Ответ 7

Как насчет strptime?

http://docs.python.org/library/time.html#time.strptime

Он выдаст ValueError, если не сможет проанализировать строку на основе предоставленного формата.


Изменить:

Так как вопрос был отредактирован, чтобы включить бит об исключениях после того, как я ответил на него. Я хотел добавить примечание об этом.

Как указывалось в других ответах, если вы не хотите, чтобы ваша программа вызывала исключение, вы можете просто его перехватить и обработать:

try:
    date = datetime.datetime.strptime(s, "%Y-%m-%d %H:%M:%S")
except ValueError:
    date = None

Это Pythonic способ делать то, что вы хотите.