This format you are wanting (2019-03-28T15:14:19.000Z
) is defined by the standard ISO 8601.
Either way, this one Z
at the end is an important information because indicates that the date/time is in UTC. And as you want the current date and time in UTC, you can’t just use datetime.now()
and think you’ll be right.
This is because datetime.now()
(when so called, no parameters) will use the system time zone to get the values of the current date and time. My machine, for example, is set to Brasilia Time, which means that today is March 28, 2019, and now it is 5pm. But if the time zone is changed to that of Germany, the time returned will be 9:00, and if you move to Japan, the result will be 29 from March to 5 morning. Already in UTC, the current date and time is 28 March 2019 at 20h.
To get the current date and time values in UTC, use datetime.utcnow()
, because this method returns the date and time values in UTC, regardless of the time zone configured in the system.
To format the date using ISO 8601 format, use the method isoformat()
. The detail is that in this case will print only the date and time, but not the Z
. But if you want, you can add it manually:
from datetime import datetime
print(datetime.utcnow().isoformat() + 'Z')
In that case I add the Z
manually, but just because I know utcnow()
returns the current date and time in UTC.
If you use now()
instead of utcnow()
and put the Z
at the front, you may be setting a wrong date and time. For example, in my system Timezone is the Brasilia Time and now it is 17h, so the result of datetime.now().isoformat()
would be 2019-03-28T17:00:00.000000
. If I put the Z
in the front stands 2019-03-28T17:00:00.000000Z
: 5pm in UTC, which corresponds to 14h in the Time of Brasilia, and this is not the current date/time (but an instant occurred 3 hours before the current date/time). What difference does a "little letter" make, no?
Add the Z
manually only "makes sense" using utcnow()
, then the result will be in UTC. Use now()
will only work in cases of "coincidence" if your system’s Timezone happens to be UTC, or some other one that also uses UTC (such as Timezone London when it’s not in daylight time, for example - yes, when it’s daylight saving, London is an hour ahead of UTC, so even the English should use utcnow()
).
If looking at the correct values of date and time is important, even more so if you use values in UTC (actually in any Timezone), because changing the values of the date and time you will end up with completely different instants. The problem will much and only "put a Z at the end of the string".
The code with isoformat()
above does not put the Z
because a datetime
can be naive ("naive") or Aware ("conscious"), and by default utcnow()
and now()
create an object naive.
Basically, when the datetime
is naive, he has no information about the Timezone (time zone), already a Aware has such information. Hence the method isoformat()
only returned the date and time. The Z
was not printed because the datetime
has no information about Timezone, he does not know that his date and time values came from the "current date/time in UTC" returned by utcnow()
.
But it is possible to create an object Aware passing the timezone.utc
for the method now()
:
from datetime import datetime, timezone
print(datetime.now(timezone.utc).isoformat())
The result is:
2019-03-28T20:00:00.736820+00:00
The problem is that now instead of Z
, he prints +00:00
, which is a offset: the difference with respect to UTC. In this case, it is zero hours and zero minutes, then +00:00
is the same as UTC, which is the same as Z
. So if you want, you can just make a replace
:
print(datetime.now(timezone.utc).isoformat().replace('+00:00', 'Z'))
That one replace
is correct because now(timezone.utc)
returns the current date and time in UTC (independent of the Timezone that is configured in the system), and therefore the offset generated by isoformat()
will always be +00:00
, which is the same as Z
(both mean "UTC"). But if used now()
no parameters happen the problems already mentioned above.
To avoid long discussions in the comments; your conversation was moved to the chat - to proceed just click on the link
– Bacco