You can replace the microseconds with 0 and use isoformat:
import pytz
from datetime import datetime
tz = pytz.timezone('Asia/Taipei')
dt = datetime.now()
loc_dt = tz.localize(dt).replace(microsecond=0)
print loc_dt.isoformat()
2015-09-17T19:12:33+08:00
If you want to keep loc_dt as is do the replacing when you output:
loc_dt = tz.localize(dt)
print loc_dt.replace(microsecond=0).isoformat()
As commented you would be better passing the tz to datetime.now:
dt = datetime.now(tz)
The reasons are discussed in pep-0495, you might also want to add an assert to catch any bugs when doing the replace:
ssert loc_dt.resolution >= timedelta(microsecond=0)
Answer from Padraic Cunningham on Stack OverflowYou can replace the microseconds with 0 and use isoformat:
import pytz
from datetime import datetime
tz = pytz.timezone('Asia/Taipei')
dt = datetime.now()
loc_dt = tz.localize(dt).replace(microsecond=0)
print loc_dt.isoformat()
2015-09-17T19:12:33+08:00
If you want to keep loc_dt as is do the replacing when you output:
loc_dt = tz.localize(dt)
print loc_dt.replace(microsecond=0).isoformat()
As commented you would be better passing the tz to datetime.now:
dt = datetime.now(tz)
The reasons are discussed in pep-0495, you might also want to add an assert to catch any bugs when doing the replace:
ssert loc_dt.resolution >= timedelta(microsecond=0)
Since python 3.6, datetime.isoformat accepts a timespec keyword to pick a precision. This argument gives the smallest time unit you want to be included in the output:
>>> loc_dt.isoformat()
'2022-10-21T19:59:59.991999+08:00'
>>> loc_dt.isoformat(timespec='seconds')
'2022-10-21T19:59:59+08:00'
>>> loc_dt.isoformat(timespec='milliseconds')
'2022-10-21T19:59:59.991+08:00'
Notice how the time is truncated and not rounded.
You can also use timespec to remove seconds/minutes:
>>> loc_dt.isoformat(timespec='minutes')
'2022-10-21T19:59+08:00'
>>> loc_dt.isoformat(timespec='hours')
'2022-10-21T19+08:00'
This all assume you ran the following setup script beforehand:
from datetime import datetime
import pytz
tz = pytz.timezone('Asia/Taipei')
dt = datetime.now()
loc_dt = tz.localize(dt)
Also note that this works without timezone:
>>> from datetime import datetime
>>> now = datetime.now()
>>> now.isoformat(timespec='minutes')
>>> '2022-10-21T19:59'
If you want to format a datetime object in a specific format that is different from the standard format, it's best to explicitly specify that format:
>>> import datetime
>>> datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
'2011-11-03 18:21:26'
See the documentation of datetime.strftime() for an explanation of the % directives.
Starting from Python 3.6, the isoformat() method is flexible enough to also produce this format:
datetime.datetime.now().isoformat(sep=" ", timespec="seconds")
>>> import datetime
>>> now = datetime.datetime.now()
>>> print unicode(now.replace(microsecond=0))
2011-11-03 11:19:07
How do i remove milliseconds?
PSA: As of Python 3.11, `datetime.fromisoformat` supports most ISO 8601 formats (notably the "Z" suffix)
Add timespec optional flag to datetime isoformat() to choose the precision
datetime - ISO time (ISO 8601) in Python - Stack Overflow
In my django project i need to display duration of quiz test. In my model i have two datetime fields:
create_timestamp = models.DateTimeField(auto_now_add=True) update_timestamp = models.DateTimeField(auto_now=True)
I've made a property method to display duration:
@property
def duration(self):
return self.update_timestamp - self.create_timestampIn HTML output is like this: 0:02:09.099502
I wanna get rid of milliseconds. Please help \_o_O_/
In Python 3.10 and earlier, datetime.fromisoformat only supported formats outputted by datetime.isoformat. This meant that many valid ISO 8601 strings could not be parsed, including the very common "Z" suffix (e.g. 2000-01-01T00:00:00Z).
I discovered today that 3.11 supports most ISO 8601 formats. I'm thrilled: I'll no longer have to use a third-party library to ingest ISO 8601 and RFC 3339 datetimes. This was one of my biggest gripes with Python's stdlib.
It's not 100% standards compliant, but I think the exceptions are pretty reasonable:
-
Time zone offsets may have fractional seconds.
-
The T separator may be replaced by any single unicode character.
-
Ordinal dates are not currently supported.
-
Fractional hours and minutes are not supported.
https://docs.python.org/3/library/datetime.html#datetime.datetime.fromisoformat
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.
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'
If timezone without colon is ok, you can use
d = datetime.datetime(2018, 10, 9, 8, 19, 16, 999578,
tzinfo=dateutil.tz.tzoffset(None, 7200))
s = d.strftime('%Y-%m-%dT%H:%M:%S.%f')[:-3] + d.strftime('%z')
# '2018-10-09T08:19:16.999+0200'
For colon, you need to split the timezone and add it there yourself. %z does not produce Z either for UTC.
And Python 3.6 supports timespec='milliseconds' so you should shim this:
try:
datetime.datetime.now().isoformat(timespec='milliseconds')
def milliseconds_timestamp(d):
return d.isoformat(timespec='milliseconds')
except TypeError:
def milliseconds_timestamp(d):
z = d.strftime('%z')
z = z[:3] + ':' + z[3:]
return d.strftime('%Y-%m-%dT%H:%M:%S.%f')[:-3] + z
Given the latter definition in Python 3.6,
>>> milliseconds_timestamp(d) == d.isoformat(timespec='milliseconds')
True
with
>>> milliseconds_timestamp(d)
'2018-10-09T08:19:16.999+02:00'
on 3.10 (maybe earlier, too), you can do it on a one-liner
>>> now = datetime.datetime.now()
>>> tz = datetime.timezone(datetime.timedelta(hours=-6), name="CST")
>>> now_tz = now.replace(tzinfo=tz)
>>> now_tz.isoformat("#","milliseconds")
'2023-03-02#11:02:07.592-06:00'
If you're using Python 3.6+, you can pass the timespec parameter to isoformat()
The function ends up calling _format_time, where you can see the supported values for the parameter:
specs = {
'hours': '{:02d}',
'minutes': '{:02d}:{:02d}',
'seconds': '{:02d}:{:02d}:{:02d}',
'milliseconds': '{:02d}:{:02d}:{:02d}.{:03d}',
'microseconds': '{:02d}:{:02d}:{:02d}.{:06d}'
}
This will force the value to be rendered even if the specific part is zero
Here is the implementation of datetime isoformat():
static char *
isoformat_time(PyDateTime_DateTime *dt, char buffer[], int bufflen)
{
int x;
int us = DATE_GET_MICROSECOND(dt);
x = PyOS_snprintf(buffer, bufflen,
"%02d:%02d:%02d",
DATE_GET_HOUR(dt),
DATE_GET_MINUTE(dt),
DATE_GET_SECOND(dt));
assert(bufflen >= x);
if (us)
x += PyOS_snprintf(buffer + x, bufflen - x, ".%06d", us);
assert(bufflen >= x);
return buffer + x;
}
Doesn't look like you can do anything to enforce microseconds in the output string.