Option: isoformat()

Python's datetime does not support the military timezone suffixes like 'Z' suffix for UTC. The following simple string replacement does the trick:

In [1]: import datetime

In [2]: d = datetime.datetime(2014, 12, 10, 12, 0, 0)

In [3]: str(d).replace('+00:00', 'Z')
Out[3]: '2014-12-10 12:00:00Z'

str(d) is essentially the same as d.isoformat(sep=' ')

See: Datetime, Python Standard Library

Option: strftime()

Or you could use strftime to achieve the same effect:

In [4]: d.strftime('%Y-%m-%dT%H:%M:%SZ')
Out[4]: '2014-12-10T12:00:00Z'

Note: This option works only when you know the date specified is in UTC.

See: datetime.strftime()


Additional: Human Readable Timezone

Going further, you may be interested in displaying human readable timezone information, pytz with strftime %Z timezone flag:

In [5]: import pytz

In [6]: d = datetime.datetime(2014, 12, 10, 12, 0, 0, tzinfo=pytz.utc)

In [7]: d
Out[7]: datetime.datetime(2014, 12, 10, 12, 0, tzinfo=<UTC>)

In [8]: d.strftime('%Y-%m-%d %H:%M:%S %Z')
Out[8]: '2014-12-10 12:00:00 UTC'
Answer from Manav Kataria on Stack Overflow
Top answer
1 of 14
189

Option: isoformat()

Python's datetime does not support the military timezone suffixes like 'Z' suffix for UTC. The following simple string replacement does the trick:

In [1]: import datetime

In [2]: d = datetime.datetime(2014, 12, 10, 12, 0, 0)

In [3]: str(d).replace('+00:00', 'Z')
Out[3]: '2014-12-10 12:00:00Z'

str(d) is essentially the same as d.isoformat(sep=' ')

See: Datetime, Python Standard Library

Option: strftime()

Or you could use strftime to achieve the same effect:

In [4]: d.strftime('%Y-%m-%dT%H:%M:%SZ')
Out[4]: '2014-12-10T12:00:00Z'

Note: This option works only when you know the date specified is in UTC.

See: datetime.strftime()


Additional: Human Readable Timezone

Going further, you may be interested in displaying human readable timezone information, pytz with strftime %Z timezone flag:

In [5]: import pytz

In [6]: d = datetime.datetime(2014, 12, 10, 12, 0, 0, tzinfo=pytz.utc)

In [7]: d
Out[7]: datetime.datetime(2014, 12, 10, 12, 0, tzinfo=<UTC>)

In [8]: d.strftime('%Y-%m-%d %H:%M:%S %Z')
Out[8]: '2014-12-10 12:00:00 UTC'
2 of 14
90

Python datetime objects don't have time zone info by default, and without it, Python actually violates the ISO 8601 specification (if no time zone info is given, assumed to be local time). You can use the pytz package to get some default time zones, or directly subclass tzinfo yourself:

from datetime import datetime, tzinfo, timedelta
class simple_utc(tzinfo):
    def tzname(self,**kwargs):
        return "UTC"
    def utcoffset(self, dt):
        return timedelta(0)

Then you can manually add the time zone info to utcnow():

>>> datetime.utcnow().replace(tzinfo=simple_utc()).isoformat()
'2014-05-16T22:51:53.015001+00:00'

Note that this DOES conform to the ISO 8601 format, which allows for either Z or +00:00 as the suffix for UTC. Note that the latter actually conforms to the standard better, with how time zones are represented in general (UTC is a special case.)

🌐
Joetsoi
joetsoi.github.io › fromisoformat-django-json-encoder-utc-datetimes
Avoid fromisoformat when parsing UTC date times serialized by DjangoJSONEncoder
class DjangoJSONEncoder(json.JSONEncoder): def default(self, o): # See "Date Time String Format" in the ECMA-262 specification. if isinstance(o, datetime.datetime): r = o.isoformat() if o.microsecond: r = r[:23] + r[26:] if r.endswith("+00:00"): r = r[:-6] + "Z" return r This makes sense as we're dealing with JSON here instead of the specifics of python's fromisoformat implementation.
Discussions

No way to generate or parse timezone as produced by datetime.isoformat()
BPO 24954 Nosy @tim-one, @warsaw, @jcea, @abalkin, @vstinner, @jwilk, @mcepl, @merwok, @bitdancer, @karlcow, @flying-sheep, @mihaic, @Fak3, @berkerpeksag, @vadmium, @ztane, @boxed, @jstasiak, @offb... More on github.com
🌐 github.com
29
August 28, 2015
python - How to get current isoformat datetime string including the default timezone? - Stack Overflow
To make your datetime objects aware, you'll need to subclass tzinfo, like the second example in here, or simpler - use a package that does it for you, like pytz or python-dateutil ... Not entirely correct: the %z format directive prints the time zone offset without a colon, the ISO format however separates hours and minutes in the TZ specifier with a colon. However, calling the isoformat() method on a timezone... More on stackoverflow.com
🌐 stackoverflow.com
Need help removing time zone from datetime
Variable = df.replace(tzinfo=None) Formatted_datetime = Variable.strftime("%Y-%m-%d %H:%M:%S More on reddit.com
🌐 r/learnpython
8
4
February 28, 2024
datetime - ISO time (ISO 8601) in Python - Stack Overflow
I have a file. In Python, I would like to take its creation time, and convert it to an ISO time (ISO 8601) string while preserving the fact that it was created in the Eastern Time Zone (ET). How d... More on stackoverflow.com
🌐 stackoverflow.com
🌐
Crown
ccgit.crown.edu › cyber-reels › pythons-isoformat-date-and-time-without-the-timezone-hassle-1767647371
Python's Isoformat: Date And Time Without The Timezone Hassle
January 6, 2026 - Notice how the output includes the date, the time, and the ’T’ separator, but there’s no timezone info. Perfecto! ... from datetime import time # Create a time object current_time = time(10, 30, 0) # Get the ISO format string iso_time_string = current_time.isoformat() # Print the result print(iso_time_string) # Output: 10:30:00
🌐
GitHub
github.com › python › cpython › issues › 69142
No way to generate or parse timezone as produced by datetime.isoformat() · Issue #69142 · python/cpython
August 28, 2015 - assignee = 'https://github.com/abalkin' closed_at = None created_at = <Date 2015-08-28.22:34:41.660> labels = ['extension-modules', 'easy', 'type-feature', '3.7'] title = 'No way to generate or parse timezone as produced by datetime.isoformat()' updated_at = <Date 2018-07-05.19:25:05.940> user = 'https://github.com/gvanrossum' bugs.python.org fields: activity = <Date 2018-07-05.19:25:05.940> actor = 'gvanrossum' assignee = 'belopolsky' closed = False closed_date = None closer = None components = ['Extension Modules'] creation = <Date 2015-08-28.22:34:41.660> creator = 'gvanrossum' dependencies
Author   gvanrossum
🌐
GitHub
github.com › fastapi › fastapi › discussions › 9887
Converting datetime to UTC and ISO format ends up with Z instead of +00:00 · fastapi/fastapi · Discussion #9887
from fastapi import FastAPI from fastapi.testclient import TestClient from datetime import datetime, date import uvicorn import pytz import pytest app = FastAPI() @app.get("/") async def root(): test_date = datetime.now() test_date_tz = (datetime.now().replace(tzinfo=pytz.UTC)).isoformat() return { "date": test_date, "date_tz": test_date_tz } client = TestClient(app) def test_date(): response = client.get("/") print( response.json()) test_date = datetime.strptime(response.json()["date_tz"], "%Y-%m-%dT%H:%M:%S.%f+00:00").date() print(test_date)
Author   fastapi
🌐
Python documentation
docs.python.org › 3 › library › datetime.html
datetime — Basic date and time types
If you merely want to remove the timezone object from an aware datetime dt without conversion of date and time data, use dt.replace(tzinfo=None).
🌐
Crown
ccgit.crown.edu › cyber-reels › python-iso-format-handling-datetimes-without-timezones-1767647371
Python ISO Format: Handling Datetimes Without Timezones
January 6, 2026 - The key takeaway here is that replace(tzinfo=None) is your best friend for converting an aware datetime into a naive one, which then allows isoformat() to produce the string you desire without any timezone specifiers.
Top answer
1 of 7
163

To get the current time in UTC in Python 3.2+:

>>> from datetime import datetime, timezone
>>> datetime.now(timezone.utc).isoformat()
'2015-01-27T05:57:31.399861+00:00'

To get local time in Python 3.3+:

>>> from datetime import datetime, timezone
>>> datetime.now(timezone.utc).astimezone().isoformat()
'2015-01-27T06:59:17.125448+01:00'

Explanation: datetime.now(timezone.utc) produces a timezone aware datetime object in UTC time. astimezone() then changes the timezone of the datetime object, to the system's locale timezone if called with no arguments. Timezone aware datetime objects then produce the correct ISO format automatically.

2 of 7
42

You need to make your datetime objects timezone aware. from the datetime docs:

There are two kinds of date and time objects: “naive” and “aware”. This distinction refers to whether the object has any notion of time zone, daylight saving time, or other kind of algorithmic or political time adjustment. Whether a naive datetime object represents Coordinated Universal Time (UTC), local time, or time in some other timezone is purely up to the program, just like it’s up to the program whether a particular number represents metres, miles, or mass. Naive datetime objects are easy to understand and to work with, at the cost of ignoring some aspects of reality.

When you have an aware datetime object, you can use isoformat() and get the output you need.

To make your datetime objects aware, you'll need to subclass tzinfo, like the second example in here, or simpler - use a package that does it for you, like pytz or python-dateutil

Using pytz, this would look like:

import datetime, pytz
datetime.datetime.now(timezone.utc).isoformat()

You can also control the output format, if you use strftime with the '%z' format directive like

datetime.datetime.now(timezone.utc).strftime('%Y-%m-%dT%H:%M:%S.%f%z')
Find elsewhere
🌐
Python
bugs.python.org › issue46614
Issue 46614: Add option to output UTC datetimes as "Z" in `.isoformat()` - Python tracker
This issue tracker has been migrated to GitHub, and is currently read-only. For more information, see the GitHub FAQs in the Python's Developer Guide · This issue has been migrated to GitHub: https://github.com/python/cpython/issues/90772
🌐
Note.nkmk.me
note.nkmk.me › home › python
Convert Between Isoformat String and datetime in Python | note.nkmk.me
August 22, 2023 - As mentioned above, use fromisoformat() for Python 3.11 and later, and strptime() for earlier versions. s_basic = '20230401T050030.001000' print(datetime.datetime.fromisoformat(s_basic).isoformat()) # 2023-04-01T05:00:30.001000 · source: ...
🌐
Reddit
reddit.com › r/learnpython › need help removing time zone from datetime
r/learnpython on Reddit: Need help removing time zone from datetime
February 28, 2024 -

So i have a script that pulls some stuff from Sharepoint. One of the fields is the timestamp that an entry was made into the Sharepoint list. When pulling it from the API it is returned in the following format:

ENTERED_TM
2024-02-28T17:48:43Z

The datatype of this field when returned from the API is Object. I want to drop the time zone stuff so i just have YYYY-MM-DD H:M:S.

I've tried a couple different things:

First I convert it to datetime with cleaned_df["ENTERED_TM"] = pd.to_datetime(cleaned_df["ENTERED_TM"])

Then i've tried 2 ways of dropping the time zone cleaned_df["ENTERED_TM"].dt.tz_convert(None) and cleaned_df["ENTERED_TM"].dt.tz_localize(None)

Both of those leave me this:

ENTERED_TM
2024-02-28 17:48:43+00:00

Any help would be appreciated

🌐
Crown
ccgit.crown.edu › cyber-reels › mastering-pythons-isoformat-without-timezone-a-practical-guide-1767647371
Mastering Python's Isoformat() Without Timezone: A Practical Guide
January 6, 2026 - The T separates the date and time, and the milliseconds part (.mmmmmm) is optional. Now, the cool thing about isoformat() is that it can also handle timezone information. When you have a timezone-aware datetime object, isoformat() includes the timezone offset, like +00:00 for UTC.
Top answer
1 of 14
1247

Local to ISO 8601:

import datetime
datetime.datetime.now().isoformat()
>>> '2024-08-01T14:38:32.499588'

UTC to ISO 8601:

import datetime
datetime.datetime.now(datetime.timezone.utc).isoformat()
>>> '2024-08-01T04:38:47.731215+00:00'

Local to ISO 8601 without microsecond:

import datetime
datetime.datetime.now().replace(microsecond=0).isoformat()
>>> '2024-08-01T14:38:57'

UTC to ISO 8601 with timezone information (Python 3):

import datetime
datetime.datetime.now(datetime.timezone.utc).isoformat()
>>> '2024-08-01T04:39:06.274874+00:00'

Local to ISO 8601 with timezone information (Python 3):

import datetime
datetime.datetime.now().astimezone().isoformat()
>>> '2024-08-01T14:39:16.698776+10:00'

Local to ISO 8601 with local timezone information without microsecond (Python 3):

import datetime
datetime.datetime.now().astimezone().replace(microsecond=0).isoformat()
>>> '2024-08-01T14:39:28+10:00'

Notice there is a bug when using astimezone() on utcnow(). This gives an incorrect result:

datetime.datetime.utcnow().astimezone().isoformat() #Incorrect result, do not use.

.utcnow() is deprecated, use .now(datetime.timezome.utc) instead.

For Python 2, see and use pytz.

2 of 14
139

ISO 8601 allows a compact representation with no separators except for the T, so I like to use this one-liner to get a quick timestamp string:

>>> datetime.datetime.now(datetime.UTC).strftime("%Y%m%dT%H%M%S.%fZ")
'20180905T140903.591680Z'

If you don't need the microseconds, just leave out the .%f part:

>>> datetime.datetime.now(datetime.UTC).strftime("%Y%m%dT%H%M%SZ")
'20180905T140903Z'

For local time:

>>> datetime.datetime.now(datetime.timezone(datetime.timedelta(hours=-5))).strftime("%Y-%m-%dT%H:%M:%S%:z")
'2018-09-05T14:09:03-05:00'

In general, I recommend you leave the punctuation in. RFC 3339 recommends that style because if everyone uses punctuation, there isn't a risk of things like multiple ISO 8601 strings being sorted in groups on their punctuation. So the one liner for a compliant string would be:

>>> datetime.datetime.now(datetime.UTC).strftime("%Y-%m-%dT%H:%M:%SZ")
'2018-09-05T14:09:03Z'
🌐
Pythontic
pythontic.com › datetime › datetime › isoformat
The isoformat() method of datetime class in Python | Pythontic.com
In Python the isoformat() method of datetime class returns the date-time string with the specified separator. If no separator is specified space is printed
🌐
Fremontleaf
wiki.fremontleaf.org › official-files › python-datetimeisoformat-without-timezone-1767646942
Python Datetime.isoformat() Without Timezone
January 6, 2026 - When you create a datetime object, it can either be aware (meaning it knows its timezone) or naive (meaning it doesn’t). The isoformat() method, when called on an aware datetime object, will automatically include the timezone offset because, ...
Top answer
1 of 7
167

As of Python 3.7, datetime.datetime.fromisoformat() can handle your format:

>>> import datetime
>>> datetime.datetime.fromisoformat('2012-11-01T04:16:13-04:00')
datetime.datetime(2012, 11, 1, 4, 16, 13, tzinfo=datetime.timezone(datetime.timedelta(days=-1, seconds=72000)))

In older Python versions you can't, not without a whole lot of painstaking manual timezone defining.

Python versions before version 3.9 do not include a timezone database, because it would be outdated too quickly. Instead, for those versions Python relied on external libraries, which can have a far faster release cycle, to provide properly configured timezones for you.

As a side-effect, this means that timezone parsing also needs to be an external library. If dateutil is too heavy-weight for you, use iso8601 instead, it'll parse your specific format just fine:

>>> import iso8601
>>> iso8601.parse_date('2012-11-01T04:16:13-04:00')
datetime.datetime(2012, 11, 1, 4, 16, 13, tzinfo=<FixedOffset '-04:00'>)

iso8601 is a whopping 4KB small. Compare that tot python-dateutil's 148KB.

As of Python 3.2 Python can handle simple offset-based timezones, and %z will parse -hhmm and +hhmm timezone offsets in a timestamp. That means that for a ISO 8601 timestamp you'd have to remove the : in the timezone:

>>> from datetime import datetime
>>> iso_ts = '2012-11-01T04:16:13-04:00'
>>> datetime.strptime(''.join(iso_ts.rsplit(':', 1)), '%Y-%m-%dT%H:%M:%S%z')
datetime.datetime(2012, 11, 1, 4, 16, 13, tzinfo=datetime.timezone(datetime.timedelta(-1, 72000)))

The lack of proper ISO 8601 parsing was being tracked in Python issue 15873 (since migrated to GitHub issue #60077).

2 of 7
75

Here is the Python Doc for datetime object using dateutil package..

from dateutil.parser import parse

get_date_obj = parse("2012-11-01T04:16:13-04:00")
print get_date_obj
🌐
Crown
ccgit.crown.edu › cyber-reels › pythons-isoformat-timezone-free-formatting-1767647371
Python's Isoformat: Timezone-Free Formatting
January 6, 2026 - Here’s how you can use isoformat() to format dates and times without timezone information. We’ll start with the basics and then explore some variations. from datetime import datetime # Get the current date and time now = datetime.now() # Format without timezone (default behavior) iso_string = now.isoformat() print(iso_string)
🌐
Vibes News
ramgeheugen.com › blog › pythons-isoformat-date-and-time
Python's Isoformat: Date And Time Without The Timezone Hassle
November 14, 2025 - Notice how the output includes the date, the time, and the 'T' separator, but there’s no timezone info. Perfecto! ... from datetime import time # Create a time object current_time = time(10, 30, 0) # Get the ISO format string iso_time_string = current_time.isoformat() # Print the result print(iso_time_string) # Output: 10:30:00
🌐
GitHub
github.com › pyecore › pyecore › issues › 64
Missing timezone in datetime parser · Issue #64 · pyecore/pyecore
June 5, 2019 - def parse_date(str_date): try: return datetime.fromisoformat(str_date) except Exception: formats = ('%Y-%m-%dT%H:%M:%S.%f', '%Y-%m-%dT%H:%M:%S.%f', '%Y-%m-%dT%H:%M:%S', '%Y-%m-%dT%H:%M', '%Y-%m-%d %H:%M:%S.%f', '%Y-%m-%d %H:%M:%S.%f', '%Y-%m-%d %H:%M:%S', '%Y-%m-%d %H:%M', '%Y-%m-%d',) for format in formats: with ignored(ValueError): return datetime.strptime(str_date, format) raise ValueError('Date format is unknown') The timezone directive is %z, but is missing here. (Keep in mind that this directive is added in python 3).
Author   ewoudwerkman
🌐
GeeksforGeeks
geeksforgeeks.org › python › how-to-remove-timezone-information-from-datetime-object-in-python
How to remove timezone information from DateTime object in Python - GeeksforGeeks
July 23, 2025 - Explanation: We create a timezone-aware datetime using datetime.now(timezone.utc), which returns the current UTC time with a +00:00 offset and tzinfo attribute confirms it's set to UTC. While timezone-aware datetimes are useful for global time calculations and API integrations, there are situations such as local logging, database storage or display formatting where you may want to strip the timezone information and work with naive datetime objects.