Convert string to datetime in Python

When we develop applications, the problem we often face is a string to datetime conversion. We have to deal with different formats and time zones. Sometimes we need to convert dates and times to human-readable format, and vice versa.

Converting a string to datetime

Python comes with the datetime module that consists of a date, time, and datetime. This module comes with various functions for manipulating dates and time.

The following code is going to print the current date and time. The custom formatting is not applied, therefore it uses the default one.

from datetime import datetime

print('Current date/time:', str(
print('Current date:', str(
print('Current time:', str(

This code will display the current date + time, date, and time using the default formatting. Date and time can be accessed using the date and time functions.

Current date/time: 2020-04-29 11:16:03.562353
Current date: 2020-04-29
Current time: 11:16:03.562353

 This module uses ISO 8601. This is the international standard for exchanging dates and time-related data.

The strptime function

Now, instead of displaying the current date, we are going to use a date from a string and try to convert it to a datetime object. To do it, we will use the strptime function.

This function is going to convert string to a datetime object. In the second parameter, you have to apply the datetime formatting, because the module can’t figure it out on its own.

from datetime import datetime

datetime_string = '2019-03-29 10:26:06.562353'
datetime_object = datetime.strptime(datetime_string, '%Y-%m-%d %H:%M:%S.%f')

print('Date and time:', datetime_object)
print('Time:', datetime_object.time())

Let’s take a look at the result:

Date and time: 2019-03-29 10:26:06.562353
Date: 2019-03-29
Time: 10:26:06.562353

The formatting has to be exactly the same as the values in the string. If you don’t add, for example, the fraction of the second, the program is going to return an error.

ValueError: unconverted data remains: .562353

If you want to get rid of the fractional part of a second, you can use the format function.

print('Time:', format(datetime_object.time(), '%H:%M:%S'))

It will print the same result, but this time without microseconds.

Time: 10:26:06

Let’s try something more complicated.

from datetime import datetime

datetime_string = 'Jun 4 2020 2:34PM'
datetime_object = datetime.strptime(datetime_string, '%b %d %Y %I:%M%p')

This time the date is written in a more complicated fashion. We don’t have only numbers, but also an abbreviated name of the month, and time that is written using the 12-hour clock.

If you run this code the date and time will be complicated in the standard fashion:

2020-06-04 14:34:00

Formatting data

The formats we use to convert string to datetime consists of format tokens. Each token represents a different part of datetime, such a month, day, hour, etc.

The following table contains most of the commonly used tokens. These examples are for en_US.

%aWeekday as a word in an abbreviated form.Sun, Mon, …, Sat
%AWeekdays as a full word.Sunday, Monday, …, Saturday
%wWeekdays as a number. 0 is Sunday, 6 is Saturday.0, 1, 2, 3, 4, 5, 6
%dDay of the month as a zero-padded decimal number.01, 02, 03, …, 29, 30, 31
%bMonth as a word in an abbreviated form.Jan, Feb, …, Dec
%BMonth as a full word.January, February, …, December
%mMonth as a zero-padded decimal number.01, 02 …, 11, 12
%yYear as a zero-padded two-digit number.01, 02, …, 98, 99, 00
%YYear as a zero-padded four-digit number.0001, …, 2020, …., 9999
%HA zero-padded, 24-hour clock01, 02, … , 23, 00
%IA zero-padded, 12-hour clock01, 02, … , 12
%pAM and PMAM, PM
%MMinute as a zero-padded decimal number.01, 02, … , 59
%SSecond as a zero-padded decimal number.01, 02, … , 59
%fMicrosecond as a zero-padded decimal number.000000, 000001, …, 999999
%zUTC offset in the form ±HHMM[SS].(empty), +0000, -0300, +1020
%ZTime zone name.(empty), UTC, IST, CST
%jDay of the year as a zero-padded three-digit number.001, 002, …, 366
%UWeek of the year as a zero-padded two-digit number.
(Sunday as the first day of the week).
00, 01, …, 53
%WWeek of the year as a zero-padded two-digit number
(Monday as the first day of the week)
00, 01, …, 53
%cLocale’s appropriate date and time representation.Wed Apr 29 22:30:00 2020
%xLocale’s appropriate date representation.04/29/20
%XLocale’s appropriate time representation.22:30
%%A literal ‘%’ character.%

Introducing timezones

So far, we were dealing with naive datetime objects. Naive datetime objects don’t contain any timezone-related data.

If you want to check whether your object holds information about timezone, you can use the tzinfo parameter.


Because we are using the naive datetime object, the result of tzinfo is None.

The pytz module

The easy way to apply timezone to naive objects is by using the pytz module. It’s not present in the standard library, you have to install it.

After installation you can run this code:

from datetime import datetime
from pytz import timezone

datetime_string = '2019-03-29 10:26:06.562353'
datetime_object = datetime.strptime(datetime_string, '%Y-%m-%d %H:%M:%S.%f')

eastern = timezone('US/Eastern')
timezone_datetime_object = eastern.localize(datetime_object)


The result shows date and timezone.

2019-03-29 10:26:06.562353-04:00

Notice, that there is -04:00 at the end. This means, that the Eastern/US time is 4 hours earlier than the GMT timezone (Greenwich Mean Time).

You can change the timezone to a different one:

eastern = timezone('Europe/Warsaw')
timezone_datetime_object = eastern.localize(datetime_object)


Now if you run the code, the timezone will change to +01:00.

2019-03-29 10:26:06.562353+01:00

You can use the datetime module for converting strings to datetime objects. The problem with this module is that you have to apply the formatting, which can be time-consuming.

Instead, you can use third-party libraries that make the process of string to datetime conversion much easier.

In Python, there is a huge amount of modules. I created a list of the most popular ones:

  • dateutil
  • maya
  • arrow
  • moment
  • delorean


This module provides an extension to the datetime module.

You can install it using PIP.

pip install python-dateutil

With this module, you don’t have to apply formatting to the string, it will recognize tokens and automatically convert string to the datetime object.

from dateutil.parser import parse

datetime_string = '2019-03-29 10:26:06.562353'
datetime_object = parse(datetime_string)

print('Date and time:', datetime_object)
print('Time:', datetime_object.time())
print('Timezone:', datetime_object.tzinfo)

Now, the code is cleaner and the result is the same as before.

Date and time: 2019-03-29 10:26:06.562353
Date: 2019-03-29
Time: 10:26:06.562353
Timezone: None

The string was recognized as a naive object. Which is correct because you didn’t add a zone number.

Write code like this with two hours added to GMT:

datetime_string = '2019-03-29 10:26:06.562353+02:00'

It will be recognized by dateutil, but the module will display it in a form that is not very attractive to the user:

Timezone: tzoffset(None, 7200)


Maya is another module to help you with parsing dates and time.

To install it with PIP use this command:

pip install maya

After you install this module, three other modules will be installed as well: humanize, pendulum, and already mentioned: pytz.

The code with maya looks like this:

import maya

datetime_object = maya.parse('2019-03-29 10:26:06.562353+02:00')

print('Date and time:', datetime_object)

After you run the code, you will see the following result:

Date and time: Fri, 29 Mar 2019 08:26:06 GMT
Date: 2019-03-29

The date is returned as an attribute and not as a function as we saw with the previous module. There is no attribute time. If you want to display time, you have to display an hour, minute, and second separately.

Notice, that time is already converted to GMT, so instead of 10:26:06, you see 08:26:06.

With maya, you can easily add date and time to the object:

datetime_object = maya.parse('2019-03-29 10:26:06.562353').add(hours=3, months=1)

This code adds 1 month and 3 hours to the date.

Date and time: Mon, 29 Apr 2019 13:26:06 GMT


The arrow library aims to help you work with datetime objects by using fewer imports and less code. It offers a human-friendly approach to creating, manipulating, formatting, and converting dates.

You can install it using this command:

pip install arrow

Here is an example of how a program looks like:

import arrow

datetime_object = arrow.get('2019-03-29 10:26:06.562353')

print('Date and time:', datetime_object.shift(hours=-2))
print('Time:', datetime_object.time())

It returns a date that is two hours earlier than that in a string and date and time with functions.

Date and time: 2019-03-29T08:26:06.562353+00:00
Date: 2019-03-29
Time: 10:26:06.562353

You can use humanize to make the result more … human.

import arrow

datetime_object = arrow.get('2019-03-29 10:26:06.562353')

After you run the code, you are going to get a result that is written as a string.

a year ago


Another interesting module used to deal with dates is moment. You can import the date from as a string in a similar way as you did with other modules.

import moment

datetime_object ='2019-03-29 10:26:06.562353')
tomorrow_date ='tomorrow')


By default, the module treats the date using a local timezone. With the moment module, the date function can get a string parameter, such as ‘tomorrow’ to return the tomorrow date.



In this tutorial, I presented a standard Python library and a few third-party libraries.

The main advantage of these libraries over the standard module is that you don’t have to specify the format and they can figure it out on their own.

Each of these libraries has its pros and cons. To learn more about them, you should read their documentation and decide which one is the most suitable for your needs.