是否有一个Python等效于C#的DateTime.TryParse()?

时间:2011-07-07 18:44:27

标签: python parsing datetime exception tryparse

Python中是否有与C#的DateTime.TryParse()等价的内容?

我指的是它避免抛出异常的事实,而不是它猜测格式的事实。

8 个答案:

答案 0 :(得分:22)

如果您不想要异常,请捕获异常。

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,列,在这种情况下,不会有捕获的异常,所以不要捕获它。

答案 1 :(得分:9)

我们希望try...catch多个日期时间格式fmt1,fmt2,...,fmtn并禁止/处理所有不匹配的异常(来自strptime)(特别是,避免需要yukky n-deep 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, ...]) < / p>

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)更清洁,更好。特别地,该函数/方法可以存储默认格式的列表,这使得它更加安全,并且对现实世界数据的启发更少。 (我们甚至可以根据其他列推断应用哪些默认格式,例如首先尝试德语数据的德语日期格式,阿拉伯语的阿拉伯语,博客数据的weblog日期时间格式等。)

答案 2 :(得分:4)

不,你要求的不是惯用的Python,因此通常不会有丢弃标准库中错误的函数。相关的标准库模块在此处记录:

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

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

解析函数都会在无效输入上引发异常。

然而,正如其他答案所述,为你的应用程序构建一个代码并不是非常困难(你的问题是用“Python”而不是“在Python标准库中”,所以不清楚是否有助于编写这样一个“在Python中”的功能正在回答这个问题。)

答案 3 :(得分:3)

这是一个等效的函数实现

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

答案 4 :(得分:2)

蛮力也是一种选择:

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

答案 5 :(得分:0)

我同意tryparse在c#上非常有用。不幸的是,在python中没有等效的直接函数(可能我不知道)。我相信您想检查一个字符串是否为日期,而不必担心日期格式。我的建议是使用pandas to_datetime函数:

def is_valid_date(str_to_validate: str) -> bool:
    try:
        if pd.to_datetime(str_to_validate):
            return True
        else:
            return False
    except ValueError:
        return False

答案 6 :(得分:-1)

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方式。

答案 7 :(得分:-1)

使用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.