def strptime(string, formats=None):
"""
Converts a date in string format into a datetime python object. The inverse can be obtained
by calling datetime.isoformat() (which returns 'T' as date time separator, and optionally
microseconds if they are not zero). This function is an easy version of
`dateutil.parser.parse` for parsing iso-like datetime format (e.g. fdnsws standard)
without the need of a module import
:param: string: if a datetime object, returns it. If date object, converts to datetime
and returns it. Otherwise must be a string representing a datetime
:type: string: a string, a date or a datetime object (in that case just returns it)
:param formats: if list or iterable, it holds the strings denoting the formats to be used
to convert string (in the order they are declared). If None (the default), the datetime
format will be guessed from the string length among the following (with optional 'Z', and
with 'T' replaced by space as vaild option):
- '%Y-%m-%dT%H:%M:%S.%fZ'
- '%Y-%m-%dT%H:%M:%SZ'
- '%Y-%m-%dZ'
:raise: ValueError if the string cannot be parsed
:type: on_err_return_none: object or Exception
:return: a datetime object
:Example:
strptime("2016-06-01T09:04:00.5600Z")
strptime("2016-06-01T09:04:00.5600")
strptime("2016-06-01 09:04:00.5600Z")
strptime("2016-06-01T09:04:00Z")
strptime("2016-06-01T09:04:00")
strptime("2016-06-01 09:04:00Z")
strptime("2016-06-01")
```
"""
if isinstance(string, datetime):
return string
try:
string = string.strip()
if formats is None:
has_z = string[-1] == 'Z'
has_t = 'T' in string
if has_t or has_z or ' ' in string:
t_str, z_str = 'T' if has_t else ' ', 'Z' if has_z else ''
formats = ['%Y-%m-%d{}%H:%M:%S.%f{}'.format(t_str, z_str),
'%Y-%m-%d{}%H:%M:%S{}'.format(t_str, z_str)]
else:
formats = ['%Y-%m-%d']
for dtformat in formats:
try:
return datetime.strptime(string, dtformat)
except ValueError: # as exce:
pass
raise ValueError("invalid date time '%s'" % str(string))
except ValueError:
raise
except Exception as exc:
raise ValueError(str(exc))
```