python 带有可选位的 strptime 格式
python strptime format with optional bits
现在我有:
timestamp = datetime.strptime(date_string, '%Y-%m-%d %H:%M:%S.%f')
这很好用,除非我转换的字符串没有微秒。我如何指定微秒是可选的(如果它们不在字符串中则应被视为 0)?
您可以使用 try/except
块:
try:
timestamp = datetime.strptime(date_string, '%Y-%m-%d %H:%M:%S.%f')
except ValueError:
timestamp = datetime.strptime(date_string, '%Y-%m-%d %H:%M:%S')
如果它不存在就追加它怎么样?
if '.' not in date_string:
date_string = date_string + '.0'
timestamp = datetime.strptime(date_string, '%Y-%m-%d %H:%M:%S.%f')
我更喜欢使用正则表达式匹配而不是尝试和排除。这允许许多可接受格式的回退。
# full timestamp with milliseconds
match = re.match(r"\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d+Z", date_string)
if match:
return datetime.strptime(date_string, "%Y-%m-%dT%H:%M:%S.%fZ")
# timestamp missing milliseconds
match = re.match(r"\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}Z", date_string)
if match:
return datetime.strptime(date_string, "%Y-%m-%dT%H:%M:%SZ")
# timestamp missing milliseconds & seconds
match = re.match(r"\d{4}-\d{2}-\d{2}T\d{2}:\d{2}Z", date_string)
if match:
return datetime.strptime(date_string, "%Y-%m-%dT%H:%MZ")
# unknown timestamp format
return false
不要忘记为该方法导入 "re" 和 "datetime"。
datetime(*map(int, re.findall('\d+', date_string)))
可以解析'%Y-%m-%d %H:%M:%S.%f'
和'%Y-%m-%d %H:%M:%S'
。如果您的输入没有被过滤,那就太宽容了。
它快速而肮脏,但有时 strptime()
太慢了。如果您知道输入具有预期的日期格式,则可以使用它。
对于我使用 jq
的类似问题,我使用了以下内容:
|split("Z")[0]|split(".")[0]|strptime("%Y-%m-%dT%H:%M:%S")|mktime
作为按时间正确排序列表的解决方案。
使用一个正则表达式和一些列表表达式
time_str = "12:34.567"
# time format is [HH:]MM:SS[.FFF]
sum([a*b for a,b in zip(map(lambda x: int(x) if x else 0, re.match(r"(?:(\d{2}):)?(\d{2}):(\d{2})(?:\.(\d{3}))?", time_str).groups()), [3600, 60, 1, 1/1000])])
# result = 754.567
我来晚了,但我发现如果您不关心可选位,这将为您去掉 .%f。
datestring.split('.')[0]
如果您使用的是 Pandas,您还可以过滤系列并将其连接起来。索引自动加入。
import pandas as pd
# Every other row has a different format
df = pd.DataFrame({"datetime_string": ["21-06-08 14:36:09", "21-06-08 14:36:09.50", "21-06-08 14:36:10", "21-06-08 14:36:10.50"]})
df["datetime"] = pd.concat([
pd.to_datetime(df["datetime_string"].iloc[1::2], format="%y-%m-%d %H:%M:%S.%f"),
pd.to_datetime(df["datetime_string"].iloc[::2], format="%y-%m-%d %H:%M:%S"),
])
datetime_string
datetime
0
21-06-08 14:36:09
2021-06-08 14:36:09
1
21-06-08 14:36:09.50
2021-06-08 14:36:09.500000
2
21-06-08 14:36:10
2021-06-08 14:36:10
3
21-06-08 14:36:10.50
2021-06-08 14:36:10.500000
现在我有:
timestamp = datetime.strptime(date_string, '%Y-%m-%d %H:%M:%S.%f')
这很好用,除非我转换的字符串没有微秒。我如何指定微秒是可选的(如果它们不在字符串中则应被视为 0)?
您可以使用 try/except
块:
try:
timestamp = datetime.strptime(date_string, '%Y-%m-%d %H:%M:%S.%f')
except ValueError:
timestamp = datetime.strptime(date_string, '%Y-%m-%d %H:%M:%S')
如果它不存在就追加它怎么样?
if '.' not in date_string:
date_string = date_string + '.0'
timestamp = datetime.strptime(date_string, '%Y-%m-%d %H:%M:%S.%f')
我更喜欢使用正则表达式匹配而不是尝试和排除。这允许许多可接受格式的回退。
# full timestamp with milliseconds
match = re.match(r"\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d+Z", date_string)
if match:
return datetime.strptime(date_string, "%Y-%m-%dT%H:%M:%S.%fZ")
# timestamp missing milliseconds
match = re.match(r"\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}Z", date_string)
if match:
return datetime.strptime(date_string, "%Y-%m-%dT%H:%M:%SZ")
# timestamp missing milliseconds & seconds
match = re.match(r"\d{4}-\d{2}-\d{2}T\d{2}:\d{2}Z", date_string)
if match:
return datetime.strptime(date_string, "%Y-%m-%dT%H:%MZ")
# unknown timestamp format
return false
不要忘记为该方法导入 "re" 和 "datetime"。
datetime(*map(int, re.findall('\d+', date_string)))
可以解析'%Y-%m-%d %H:%M:%S.%f'
和'%Y-%m-%d %H:%M:%S'
。如果您的输入没有被过滤,那就太宽容了。
它快速而肮脏,但有时 strptime()
太慢了。如果您知道输入具有预期的日期格式,则可以使用它。
对于我使用 jq
的类似问题,我使用了以下内容:
|split("Z")[0]|split(".")[0]|strptime("%Y-%m-%dT%H:%M:%S")|mktime
作为按时间正确排序列表的解决方案。
使用一个正则表达式和一些列表表达式
time_str = "12:34.567"
# time format is [HH:]MM:SS[.FFF]
sum([a*b for a,b in zip(map(lambda x: int(x) if x else 0, re.match(r"(?:(\d{2}):)?(\d{2}):(\d{2})(?:\.(\d{3}))?", time_str).groups()), [3600, 60, 1, 1/1000])])
# result = 754.567
我来晚了,但我发现如果您不关心可选位,这将为您去掉 .%f。
datestring.split('.')[0]
如果您使用的是 Pandas,您还可以过滤系列并将其连接起来。索引自动加入。
import pandas as pd
# Every other row has a different format
df = pd.DataFrame({"datetime_string": ["21-06-08 14:36:09", "21-06-08 14:36:09.50", "21-06-08 14:36:10", "21-06-08 14:36:10.50"]})
df["datetime"] = pd.concat([
pd.to_datetime(df["datetime_string"].iloc[1::2], format="%y-%m-%d %H:%M:%S.%f"),
pd.to_datetime(df["datetime_string"].iloc[::2], format="%y-%m-%d %H:%M:%S"),
])
datetime_string | datetime | |
---|---|---|
0 | 21-06-08 14:36:09 | 2021-06-08 14:36:09 |
1 | 21-06-08 14:36:09.50 | 2021-06-08 14:36:09.500000 |
2 | 21-06-08 14:36:10 | 2021-06-08 14:36:10 |
3 | 21-06-08 14:36:10.50 | 2021-06-08 14:36:10.500000 |