0

I have a datetime string like:

"2016-08-15T07:50:12"

I used strptime() function in datetime module to convert the string to datetime object. My datetime format is

"%Y-%m-%dT%H:%M:%S.%f"

When I parse this above string, the function raises ValueError because of missing millisecond part in the string. How can I have datetime object with millisecond is 0 when I don't specify it in the string?

Asnim P Ansari
  • 1,932
  • 1
  • 18
  • 41
Thanh Kiet
  • 111
  • 1
  • 8
  • 3
    What’s the result if you simply omit the `.%f`…? – deceze Sep 14 '20 at 05:04
  • if I omit .%f in my datetime format, strptime() works fine. However, when I have string that have milliseconds on it, eg: "2016-08-15T07:50:12.34". The function raise ValueError – Thanh Kiet Sep 14 '20 at 05:35
  • the format of your datetime string is ISO 8601; have a look at [this post](https://stackoverflow.com/q/127803/10197418). – FObersteiner Sep 14 '20 at 06:05

3 Answers3

0

you need to parse the date without timezone first and add the timezone later. Unfortunately you need to subclass tzinfo for that.

you can use below code and change it accordingly with your requirements.

from datetime import datetime, timedelta, tzinfo

class FixedOffset(tzinfo):
    """offset_str: Fixed offset in str: e.g. '-0400'"""
    def __init__(self, offset_str):
        sign, hours, minutes = offset_str[0], offset_str[1:3], offset_str[3:]
        offset = (int(hours) * 60 + int(minutes)) * (-1 if sign == "-" else 1)
        self.__offset = timedelta(minutes=offset)
        # NOTE: the last part is to remind about deprecated POSIX GMT+h timezones
        # that have the opposite sign in the name;
        # the corresponding numeric value is not used e.g., no minutes
        '<%+03d%02d>%+d' % (int(hours), int(minutes), int(hours)*-1)
    def utcoffset(self, dt=None):
        return self.__offset
    def tzname(self, dt=None):
        return self.__name
    def dst(self, dt=None):
        return timedelta(0)
    def __repr__(self):
        return 'FixedOffset(%d)' % (self.utcoffset().total_seconds() / 60)

date_with_tz = "2017-01-12T14:12:06.000-0500"
date_str, tz = date_with_tz[:-5], date_with_tz[-5:]
dt_utc = datetime.strptime(date_str, "%Y-%m-%dT%H:%M:%S.%f")
dt = dt_utc.replace(tzinfo=FixedOffset(tz))
print(dt)

For more information please visit link

General Grievance
  • 4,555
  • 31
  • 31
  • 45
0

If you get an ISO 8601 string like: "2016-08-15T07:50:12" easiest way I feel is using dateutil to convert it.

import dateutil.parser
yourdate = dateutil.parser.parse(datestring)
  • 2
    I feel you should mention that `dateutil` is not a standard library. – martineau Sep 14 '20 at 05:22
  • 1
    No. The easiest way is to use [fromisoformat](https://docs.python.org/3/library/datetime.html#datetime.datetime.fromisoformat). It is also [more efficient](https://stackoverflow.com/q/13468126/10197418). – FObersteiner Sep 14 '20 at 06:07
0

Probably below code snippet help that you are looking

from datetime import datetime
fmt='%Y-%m-%dT%H:%M:%S'
dt="2016-08-15T07:50:12"

datetime.strptime(dt, fmt)
datetime.datetime(2016, 8, 15, 7, 50, 12)

fmt1='%Y-%m-%dT%H:%M:%S.%f'
dt1="2016-08-15T07:50:12.34" 

datetime.strptime(dt1, fmt1)
datetime.datetime(2016, 8, 15, 7, 50, 12, 340000)

By adding a simple conditional statement you will able to achieve.