Reputation: 1101
What's an easy way to modify the following timestamps (as strings) like this:
2020-11-04T19:48:19.9 --> 2020-11-04T19:48:19.90
2020-11-04T19:48:20 --> 2020-11-04T19:48:20.00
A bit of background: I have timestamps coming from an API that typically look like this:
2020-11-04T19:48:19.87
I want to convert them to datetime, which can be done with the datetime module:
my_ts = datetime.datetime.strptime(my_ts, '%Y-%m-%dT%H:%M:%S.%f')
Now %f expects 6 digits, which is easily achieved by:
my_ts = my_ts + '0000'
However, for my data the fraction-bit may be missing a trailing zero, or missing altogether, like this:
2020-11-04T19:48:19.9
2020-11-04T19:48:20
What's an easy way to achieve this?
What I currently do is this:
teststring = "2020-11-04T19:48:19"
if '.' not in teststring:
fraction_length = 0
else:
fraction_length = len(teststring.split(".",1)[1])
if fraction_length == 0:
new_teststring = teststring + '.00'
elif fraction_length == 1:
new_teststring = teststring + '0'
else:
new_teststring = teststring
This appears to be unnecessarily complicated. There has to be a better way, doesn't it?
Any hints are greatly appreciated.
Upvotes: 4
Views: 1084
Reputation: 2658
Try this.
def f(string, suffix='.00', length=22):
if len(string) == length:
return string
return string + suffix[-(length - len(string)):]
suite = {
'2020-11-04T19:48:19.9': '2020-11-04T19:48:19.90',
'2020-11-04T19:48:20': '2020-11-04T19:48:20.00',
'2020-11-04T19:48:20.00': '2020-11-04T19:48:20.00',
}
for case, expected in suite.items():
assert f(case) == expected
Upvotes: 1
Reputation: 3288
try using the dateutil library
as an example:
from dateutil import parser
dt1 = ['2020-11-04T19:48:19.9', '2020-11-04T19:48:20', '2020-11-04T19:48', '2020-11-04T19:48:20.01']
for dt in dt1:
print(parser.parse(dt))
yields:
2020-11-04 19:48:19.900000
2020-11-04 19:48:20
2020-11-04 19:48:00
2020-11-04 19:48:20.010000
Upvotes: 2
Reputation: 123423
The problem seems to boil down into needing to handle the cases where there's no decimal point or there is but there are no digits following it — otherwise strptime()
can handle it.
The code below uses a regular expression to determine which of these two cases has occurred to modify the timestamps string accordingly when necessary.
import datetime
import re
tests = (
'2020-11-04T19:48:19',
'2020-11-04T19:48:19.',
'2020-11-04T19:48:19.9',
'2020-11-04T19:48:19.90',
'2020-11-04T19:48:19.900',
'2020-11-04T19:48:19.90000',
'2020-11-04T19:48:19.900000',
)
regex = re.compile(r'(\.\d*)')
for test in tests:
try:
my_ts = datetime.datetime.strptime(test, '%Y-%m-%dT%H:%M:%S.%f')
except ValueError:
m = regex.search(test)
test += '0' if m else '.0'
my_ts = datetime.datetime.strptime(test, '%Y-%m-%dT%H:%M:%S.%f')
print(my_ts)
Output:
2020-11-04 19:48:19
2020-11-04 19:48:19
2020-11-04 19:48:19.900000
2020-11-04 19:48:19.900000
2020-11-04 19:48:19.900000
2020-11-04 19:48:19.900000
2020-11-04 19:48:19.900000
Upvotes: 1