I get the server date and I need to get the difference of this date from GMT
I get
Datetime = "2011-04-27 2:17:45"
I would like to get the result like
Datetime = "2011-04-27 2:17:45 +0500"
Try this:
import datetime, pytz
now = datetime.datetime.now(pytz.timezone('Asia/Kolkata'))
print now.strftime('%Y-%m-%d %H:%M:%S %z')
# prints: '2011-04-27 13:56:09 +0530'
From the example you have given, it looks to me that what you are looking for is datetime.isoformat. The example in the page shows how to convert the datetime values to the ISO format with the time zone information.
To do this, you have to know the timezone (or the UTC offset) of the server date. What you have here is a "naive" date, without timezone info, you can't guess the UTC difference.
I think the datetime module is what you need here:
>>> from datetime import datetime
>>> datetime.now()
datetime.datetime(2011, 4, 27, 11, 8, 26, 149000)
>>> datetime.utcnow()
datetime.datetime(2011, 4, 27, 8, 8, 47, 712000)
For a difference between two dates:
>>> dtnow = datetime.now()
>>> dtutc = datetime.utcnow()
>>> dtnow - dtutc
datetime.timedelta(0, 10792, 847000)
Look up the datetime module and the relevant classes in Python's docs.
A very powerful extension of the datetime standard python library is the dateutil one, that allows you to easily:
set the delta of your time zone:
parse dates with various convenient options (in our case we will use the default option, which will allow us to set our time zone)
So 1st set time zone, and default date with this zone:
>>> from datetime import datetime
>>> from dateutil import parser
>>> from dateutil.tz import tzoffset
>>> tz_plus_5 = tzoffset(None, 5 * 60 * 60) # offset is in seconds !
>>> default = datetime.now(tz_plus_5)
Now use this default date in the parsing:
>>> Datetime = "2011-04-27 2:17:45"
>>> my_date = parser.parse(Datetime, default=default)
>>> my_date
datetime.datetime(2011, 4, 27, 2, 17, 45, tzinfo=tzoffset(None, 18000))
>>> my_date.strftime("%Y-%m-%d %H:%M:%S %z")
'2011-04-27 02:17:45 +0500'
For those that simply need to get the offset between local time and UTC, the time module has an attribute time.altzone that specifies the difference between UTC and local time in seconds:
The offset of the local DST timezone, in seconds west of UTC, if one is defined. This is negative if the local DST timezone is east of UTC (as in Western Europe, including the UK). Only use this if daylight is nonzero.
Here's an example of how it works:
>>> datetime.now().isoformat()
'2011-09-01T17:26:46.971000'
>>> datetime.utcnow().isoformat()
'2011-09-01T15:27:32.699000'
>>> time.altzone / (60*60)
-2
Doesn't get much cleaner than that.
# parses some string into that format.
datetime1 = datetime.strptime(somestring, "%Y-%m-%dT%H:%M:%S")
# gets the seconds from the above date.
timestamp1 = time.mktime(datetime1.timetuple())
# adds milliseconds to the above seconds.
timeInMillis = int(timestamp1) * 1000
How do I (at any point in that code) turn the date into UTC format? I've been ploughing through the API for what seems like a century and cannot find anything that I can get working. Can anyone help? It's currently turning it into Eastern time i believe (however I'm in GMT but want UTC).
EDIT: I gave the answer to the guy with the closest to what I finally found out.
datetime1 = datetime.strptime(somestring, someformat)
timeInSeconds = calendar.timegm(datetime1.utctimetuple())
timeInMillis = timeInSeconds * 1000
:)
datetime.utcfromtimestamp is probably what you're looking for:
>>> timestamp1 = time.mktime(datetime.now().timetuple())
>>> timestamp1
1256049553.0
>>> datetime.utcfromtimestamp(timestamp1)
datetime.datetime(2009, 10, 20, 14, 39, 13)
I think you can use the utcoffset() method:
utc_time = datetime1 - datetime1.utcoffset()
The docs give an example of this using the astimezone() method here.
Additionally, if you're going to be dealing with timezones, you might want to look into the PyTZ library which has lots of helpful tools for converting datetime's into various timezones (including between EST and UTC)
With PyTZ:
from datetime import datetime
import pytz
utc = pytz.utc
eastern = pytz.timezone('US/Eastern')
# Using datetime1 from the question
datetime1 = datetime.strptime(somestring, "%Y-%m-%dT%H:%M:%S")
# First, tell Python what timezone that string was in (you said Eastern)
eastern_time = eastern.localize(datetime1)
# Then convert it from Eastern to UTC
utc_time = eastern_time.astimezone(utc)
def getDateAndTime(seconds=None):
"""
Converts seconds since the Epoch to a time tuple expressing UTC.
When 'seconds' is not passed in, convert the current time instead.
:Parameters:
- `seconds`: time in seconds from the epoch.
:Return:
Time in UTC format.
"""
return time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime(seconds))`
This converts local time to UTC
time.mktime(time.localtime(calendar.timegm(utc_time)))
http://feihonghsu.blogspot.com/2008/02/converting-from-local-time-to-utc.html
If converting a struct_time to seconds-since-the-epoch is done using mktime, this
conversion is in local timezone. There's no way to tell it to use any specific timezone, not even just UTC. The standard 'time' package always assumes that a time is in your local timezone.
You probably want one of these two:
import time
import datetime
from email.Utils import formatdate
rightnow = time.time()
utc = datetime.datetime.utcfromtimestamp(rightnow)
print utc
print formatdate(rightnow)
The two outputs look like this
2009-10-20 14:46:52.725000
Tue, 20 Oct 2009 14:46:52 -0000
How do I get the current time?
Use datetime:
>>> import datetime
>>> now = datetime.datetime.now()
>>> now
datetime.datetime(2009, 1, 6, 15, 8, 24, 78915)
>>> print(now)
2009-01-06 15:08:24.789150
For just the clock time without the date:
>>> now.time()
datetime.time(15, 8, 24, 78915)
>>> print(now.time())
15:08:24.789150
To save typing, you can import the datetime object from the datetime module:
>>> from datetime import datetime
Then remove the prefix datetime. from all of the above.
Use time.strftime():
>>> from time import gmtime, strftime
>>> strftime("%Y-%m-%d %H:%M:%S", gmtime())
'2009-01-05 22:14:39'
from datetime import datetime
datetime.now().strftime('%Y-%m-%d %H:%M:%S')
Example output: '2013-09-18 11:16:32'
See list of strftime directives.
Similar to Harley's answer, but use the str() function for a quick-n-dirty, slightly more human readable format:
>>> from datetime import datetime
>>> str(datetime.now())
'2011-05-03 17:45:35.177000'
How do I get the current time in Python?
The time module
The time module provides functions that tell us the time in "seconds since the epoch" as well as other utilities.
import time
Unix Epoch Time
This is the format you should get timestamps in for saving in databases. It is a simple floating-point number that can be converted to an integer. It is also good for arithmetic in seconds, as it represents the number of seconds since Jan 1, 1970, 00:00:00, and it is memory light relative to the other representations of time we'll be looking at next:
>>> time.time()
1424233311.771502
This timestamp does not account for leap-seconds, so it's not linear - leap seconds are ignored. So while it is not equivalent to the international UTC standard, it is close, and therefore quite good for most cases of record-keeping.
This is not ideal for human scheduling, however. If you have a future event you wish to take place at a certain point in time, you'll want to store that time with a string that can be parsed into a datetime object or a serialized datetime object (these will be described later).
time.ctime
You can also represent the current time in the way preferred by your operating system (which means it can change when you change your system preferences, so don't rely on this to be standard across all systems, as I've seen others expect). This is typically user friendly, but doesn't typically result in strings one can sort chronologically:
>>> time.ctime()
'Tue Feb 17 23:21:56 2015'
You can hydrate timestamps into human readable form with ctime as well:
>>> time.ctime(1424233311.771502)
'Tue Feb 17 23:21:51 2015'
This conversion is also not good for record-keeping (except in text that will only be parsed by humans - and with improved Optical Character Recognition and Artificial Intelligence, I think the number of these cases will diminish).
datetime module
The datetime module is also quite useful here:
>>> import datetime
datetime.datetime.now
The datetime.now is a class method that returns the current time. It uses the time.localtime without the timezone info (if not given, otherwise see timezone aware below). It has a representation (which would allow you to recreate an equivalent object) echoed on the shell, but when printed (or coerced to a str), it is in human readable (and nearly ISO) format, and the lexicographic sort is equivalent to the chronological sort:
>>> datetime.datetime.now()
datetime.datetime(2015, 2, 17, 23, 43, 49, 94252)
>>> print(datetime.datetime.now())
2015-02-17 23:43:51.782461
datetime's utcnow
You can get a datetime object in UTC time, a global standard, by doing this:
>>> datetime.datetime.utcnow()
datetime.datetime(2015, 2, 18, 4, 53, 28, 394163)
>>> print(datetime.datetime.utcnow())
2015-02-18 04:53:31.783988
UTC is a time standard that is nearly equivalent to the GMT timezone. (While GMT and UTC do not change for Daylight Savings Time, their users may switch to other timezones, like British Summer Time, during the Summer.)
datetime timezone aware
However, none of the datetime objects we've created so far can be easily converted to various timezones. We can solve that problem with the pytz module:
>>> import pytz
>>> then = datetime.datetime.now(pytz.utc)
>>> then
datetime.datetime(2015, 2, 18, 4, 55, 58, 753949, tzinfo=<UTC>)
Equivalently, in Python 3 we have the timezone class with a utc timezone instance attached, which also makes the object timezone aware (but to convert to another timezone without the handy pytz module is left as an exercise to the reader):
>>> datetime.datetime.now(datetime.timezone.utc)
datetime.datetime(2015, 2, 18, 22, 31, 56, 564191, tzinfo=datetime.timezone.utc)
And we see we can easily convert to timezones from the original UTC object.
>>> print(then)
2015-02-18 04:55:58.753949+00:00
>>> print(then.astimezone(pytz.timezone('US/Eastern')))
2015-02-17 23:55:58.753949-05:00
You can also make a naive datetime object aware with the pytz timezone localize method, or by replacing the tzinfo attribute (with replace, this is done blindly), but these are more last resorts than best practices:
>>> pytz.utc.localize(datetime.datetime.utcnow())
datetime.datetime(2015, 2, 18, 6, 6, 29, 32285, tzinfo=<UTC>)
>>> datetime.datetime.utcnow().replace(tzinfo=pytz.utc)
datetime.datetime(2015, 2, 18, 6, 9, 30, 728550, tzinfo=<UTC>)
The pytz module allows us to make our datetime objects timezone aware and convert the times to the hundreds of timezones available in the pytz module.
One could ostensibly serialize this object for UTC time and store that in a database, but it would require far more memory and be more prone to error than simply storing the Unix Epoch time, which I demonstrated first.
The other ways of viewing times are much more error-prone, especially when dealing with data that may come from different time zones. You want there to be no confusion as to which timezone a string or serialized datetime object was intended for.
If you're displaying the time with Python for the user, ctime works nicely, not in a table (it doesn't typically sort well), but perhaps in a clock. However, I personally recommend, when dealing with time in Python, either using Unix time, or a timezone aware UTC datetime object.
Do
from time import time
t = time()
t - float number, good for time interval measurement.
There is some difference for Unix and Windows platforms.
>>> from time import gmtime, strftime
>>> strftime("%a, %d %b %Y %X +0000", gmtime())
'Tue, 06 Jan 2009 04:54:56 +0000'
That outputs the current GMT in the specified format. There is also a localtime() method.
This page has more details.
The previous answers are all good suggestions, but I find it easiest to use ctime():
In [2]: from time import ctime
In [3]: ctime()
Out[3]: 'Thu Oct 31 11:40:53 2013'
This gives a nicely formatted string representation of the current local time.
The quickest way is:
>>> import time
>>> time.strftime("%Y%m%d")
'20130924'
If you need current time as a time object:
>>> import datetime
>>> now = datetime.datetime.now()
>>> datetime.time(now.hour, now.minute, now.second)
datetime.time(11, 23, 44)
You can use the time module:
>>> import time
>>> print(time.strftime("%d/%m/%Y"))
06/02/2015
The use of the capital Y gives the full year, and using y would give 06/02/15.
You could also use the following code to give a more lengthy time:
>>> time.strftime("%a, %d %b %Y %H:%M:%S")
'Fri, 06 Feb 2015 17:45:09'
.isoformat() is in the documentation, but not yet here
(this is mighty similar to #Ray Vega's answer):
>>> import datetime
>>> datetime.datetime.now().isoformat()
'2013-06-24T20:35:55.982000'
Why not ask the U.S. Naval Observatory, the official timekeeper of the United States Navy?
import requests
from lxml import html
page = requests.get('http://tycho.usno.navy.mil/cgi-bin/timer.pl')
tree = html.fromstring(page.content)
print(tree.xpath('//html//body//h3//pre/text()')[1])
If you live in the D.C. area (like me) the latency might not be too bad...
Using pandas to get the current time, kind of overkilling the problem at hand:
import pandas as pd
print(pd.datetime.now())
print(pd.datetime.now().date())
print(pd.datetime.now().year)
print(pd.datetime.now().month)
print(pd.datetime.now().day)
print(pd.datetime.now().hour)
print(pd.datetime.now().minute)
print(pd.datetime.now().second)
print(pd.datetime.now().microsecond)
Output:
2017-09-22 12:44:56.092642
2017-09-22
2017
9
22
12
44
56
92693
if you are using numpy already then directly you can use numpy.datetime64()
function.
import numpy as np
str(np.datetime64('now'))
for only date:
str(np.datetime64('today'))
or, if you are using pandas already then you can use pandas.to_datetime() function
import pandas as pd
str(pd.to_datetime('now'))
or,
str(pd.to_datetime('today'))
This is what I ended up going with:
>>>from time import strftime
>>>strftime("%m/%d/%Y %H:%M")
01/09/2015 13:11
Also, this table is a necessary reference for choosing the appropriate format codes to get the date formatted just the way you want it (from Python "datetime" documentation here).
datetime.now() returns the current time as a naive datetime object that represents time in the local timezone. That value may be ambiguous e.g., during DST transitions ("fall back"). To avoid ambiguity either UTC timezone should be used:
from datetime import datetime
utc_time = datetime.utcnow()
print(utc_time) # -> 2014-12-22 22:48:59.916417
Or a timezone-aware object that has the corresponding timezone info attached (Python 3.2+):
from datetime import datetime, timezone
now = datetime.now(timezone.utc).astimezone()
print(now) # -> 2014-12-23 01:49:25.837541+03:00
import datetime
date_time = datetime.datetime.now()
date = date_time.date() # Gives the date
time = date_time.time() # Gives the time
print date.year, date.month, date.day
print time.hour, time.minute, time.second, time.microsecond
Do dir(date) or any variables including the package. You can get all the attributes and methods associated with the variable.
>>> import datetime, time
>>> time = time.strftime("%H:%M:%S:%MS", time.localtime())
>>> print time
'00:21:38:20S'
This question doesn't need a new answer just for the sake of it ... a shiny new-ish toy/module, however, is enough justification. That being the Pendulum library, which appears to do the sort of things which arrow attempted, except without the inherent flaws and bugs which beset arrow.
For instance, the answer to the original question:
>>> import pendulum
>>> print(pendulum.now())
2018-08-14T05:29:28.315802+10:00
>>> print(pendulum.now('utc'))
2018-08-13T19:29:35.051023+00:00
There's a lot of standards which need addressing, including multiple RFCs and ISOs, to worry about. Ever get them mixed up; not to worry, take a little look into dir(pendulum.constants) There's a bit more than RFC and ISO formats there, though.
When we say local, though what do we mean? Well I mean:
>>> print(pendulum.now().timezone_name)
Australia/Melbourne
>>>
Presumably most of the rest of you mean somewhere else.
And on it goes. Long story short: Pendulum attempts to do for date and time what requests did for HTTP. It's worth consideration, particularly for both its ease of use and extensive documentation.
By default, now() function returns output in the YYYY-MM-DD HH:MM:SS:MS format. Use the below sample script to get the current date and time in a Python script and print results on the screen. Create file getDateTime1.py with the below content.
import datetime
currentDT = datetime.datetime.now()
print (str(currentDT))
The output looks like below:
2018-03-01 17:03:46.759624
Try the arrow module from http://crsmithdev.com/arrow/:
import arrow
arrow.now()
Or the UTC version:
arrow.utcnow()
To change its output, add .format():
arrow.utcnow().format('YYYY-MM-DD HH:mm:ss ZZ')
For a specific timezone:
arrow.now('US/Pacific')
An hour ago:
arrow.utcnow().replace(hours=-1)
Or if you want the gist.
arrow.get('2013-05-11T21:23:58.970460+00:00').humanize()
>>> '2 years ago'
Current time of a timezone
from datetime import datetime
import pytz
tz_NY = pytz.timezone('America/New_York')
datetime_NY = datetime.now(tz_NY)
print("NY time:", datetime_NY.strftime("%H:%M:%S"))
tz_London = pytz.timezone('Europe/London')
datetime_London = datetime.now(tz_London)
print("London time:", datetime_London.strftime("%H:%M:%S"))
tz_India = pytz.timezone('Asia/India')
datetime_India = datetime.now(tz_India)
print("India time:", datetime_India.strftime("%H:%M:%S"))
#list timezones
pytz.all_timezones
To get exactly 3 decimal points for milliseconds 11:34:23.751 run this:
def get_time_str(decimal_points=3):
return time.strftime("%H:%M:%S", time.localtime()) + '.%d' % (time.time() % 1 * 10**decimal_points)
More context:
I want to get the time with milliseconds. A simple way to get them:
import time, datetime
print(datetime.datetime.now().time()) # 11:20:08.272239
# Or in a more complicated way
print(datetime.datetime.now().time().isoformat()) # 11:20:08.272239
print(datetime.datetime.now().time().strftime('%H:%M:%S.%f')) # 11:20:08.272239
# But do not use this:
print(time.strftime("%H:%M:%S.%f", time.localtime()), str) # 11:20:08.%f
But I want only milliseconds, right? The shortest way to get them:
import time
time.strftime("%H:%M:%S", time.localtime()) + '.%d' % (time.time() % 1 * 1000)
# 11:34:23.751
Add or remove zeroes from the last multiplication to adjust number of decimal points, or just:
def get_time_str(decimal_points=3):
return time.strftime("%H:%M:%S", time.localtime()) + '.%d' % (time.time() % 1 * 10**decimal_points)
If you just want the current timestamp in ms (for example, to measure execution time), you can also use the "timeit" module:
import timeit
start_time = timeit.default_timer()
do_stuff_you_want_to_measure()
end_time = timeit.default_timer()
print("Elapsed time: {}".format(end_time - start_time))
You can use this function to get the time (unfortunately it doesn't say AM or PM):
def gettime():
from datetime import datetime
return ((str(datetime.now())).split(' ')[1]).split('.')[0]
To get the hours, minutes, seconds and milliseconds to merge later, you can use these functions:
Hour:
def gethour():
from datetime import datetime
return (((str(datetime.now())).split(' ')[1]).split('.')[0]).split(':')[0]
Minute:
def getminute():
from datetime import datetime
return (((str(datetime.now())).split(' ')[1]).split('.')[0]).split(':')[1]
Second:
def getsecond():
from datetime import datetime
return (((str(datetime.now())).split(' ')[1]).split('.')[0]).split(':')[2]
Millisecond:
def getmillisecond():
from datetime import datetime
return (str(datetime.now())).split('.')[1]
You can try the following
import datetime
now = datetime.datetime.now()
print(now)
or
import datetime
now = datetime.datetime.now()
print(now.strftime("%Y-%b-%d, %A %I:%M:%S"))
Because no one has mentioned it yet, and this is something I ran into recently... a pytz timezone's fromutc() method combined with datetime's utcnow() is the best way I've found to get a useful current time (and date) in any timezone.
from datetime import datetime
import pytz
JST = pytz.timezone("Asia/Tokyo")
local_time = JST.fromutc(datetime.utcnow())
If all you want is the time, you can then get that with local_time.time().
import datetime
todays_date = datetime.date.today()
print(todays_date)
>>> 2019-10-12
# adding strftime will remove the seconds
current_time = datetime.datetime.now().strftime('%H:%M')
print(current_time)
>>> 23:38
Method1: Getting Current Date and Time from system datetime
The datetime module supplies classes for manipulating dates and times.
Code
from datetime import datetime,date
print("Date: "+str(date.today().year)+"-"+str(date.today().month)+"-"+str(date.today().day))
print("Year: "+str(date.today().year))
print("Month: "+str(date.today().month))
print("Day: "+str(date.today().day)+"\n")
print("Time: "+str(datetime.today().hour)+":"+str(datetime.today().minute)+":"+str(datetime.today().second))
print("Hour: "+str(datetime.today().hour))
print("Minute: "+str(datetime.today().minute))
print("Second: "+str(datetime.today().second))
print("MilliSecond: "+str(datetime.today().microsecond))
Output will be like
Date: 2020-4-18
Year: 2020
Month: 4
Day: 18
Time: 19:30:5
Hour: 19
Minute: 30
Second: 5
MilliSecond: 836071
Method2: Getting Current Date and Time if Network is available
urllib package helps us to handle the url's that means webpages. Here we collects data from the webpage http://just-the-time.appspot.com/ and parses dateime from the webpage using the package dateparser.
Code
from urllib.request import urlopen
import dateparser
time_url = urlopen(u'http://just-the-time.appspot.com/')
datetime = time_url.read().decode("utf-8", errors="ignore").split(' ')[:-1]
date = datetime[0]
time = datetime[1]
print("Date: "+str(date))
print("Year: "+str(date.split('-')[0]))
print("Month: "+str(date.split('-')[1]))
print("Day: "+str(date.split('-')[2])+'\n')
print("Time: "+str(time))
print("Hour: "+str(time.split(':')[0]))
print("Minute: "+str(time.split(':')[1]))
print("Second: "+str(time.split(':')[2]))
Output will be like
Date: 2020-04-18
Year: 2020
Month: 04
Day: 18
Time: 14:17:10
Hour: 14
Minute: 17
Second: 10
Method3: Getting Current Date and Time from Local Time of the Machine
Python's time module provides a function for getting local time from the number of seconds elapsed since the epoch called localtime(). ctime() function takes seconds passed since epoch as an argument and returns a string representing local time.
Code
from time import time, ctime
datetime = ctime(time()).split(' ')
print("Date: "+str(datetime[4])+"-"+str(datetime[1])+"-"+str(datetime[2]))
print("Year: "+str(datetime[4]))
print("Month: "+str(datetime[1]))
print("Day: "+str(datetime[2]))
print("Week Day: "+str(datetime[0])+'\n')
print("Time: "+str(datetime[3]))
print("Hour: "+str(datetime[3]).split(':')[0])
print("Minute: "+str(datetime[3]).split(':')[1])
print("Second: "+str(datetime[3]).split(':')[2])
Output will be like
Date: 2020-Apr-18
Year: 2020
Month: Apr
Day: 18
Week Day: Sat
Time: 19:30:20
Hour: 19
Minute: 30
Second: 20
The best I can come up with for now is this monstrosity:
>>> datetime.utcnow() \
... .replace(tzinfo=pytz.UTC) \
... .astimezone(pytz.timezone("Australia/Melbourne")) \
... .replace(hour=0,minute=0,second=0,microsecond=0) \
... .astimezone(pytz.UTC) \
... .replace(tzinfo=None)
datetime.datetime(2008, 12, 16, 13, 0)
I.e., in English, get the current time (in UTC), convert it to some other timezone, set the time to midnight, then convert back to UTC.
I'm not just using now() or localtime() as that would use the server's timezone, not the user's timezone.
I can't help feeling I'm missing something, any ideas?
I think you can shave off a few method calls if you do it like this:
>>> from datetime import datetime
>>> datetime.now(pytz.timezone("Australia/Melbourne")) \
.replace(hour=0, minute=0, second=0, microsecond=0) \
.astimezone(pytz.utc)
BUT… there is a bigger problem than aesthetics in your code: it will give the wrong result on the day of the switch to or from Daylight Saving Time.
The reason for this is that neither the datetime constructors nor replace() take DST changes into account.
For example:
>>> now = datetime(2012, 4, 1, 5, 0, 0, 0, tzinfo=pytz.timezone("Australia/Melbourne"))
>>> print now
2012-04-01 05:00:00+10:00
>>> print now.replace(hour=0)
2012-04-01 00:00:00+10:00 # wrong! midnight was at 2012-04-01 00:00:00+11:00
>>> print datetime(2012, 3, 1, 0, 0, 0, 0, tzinfo=tz)
2012-03-01 00:00:00+10:00 # wrong again!
However, the documentation for tz.localize() states:
This method should be used to construct localtimes, rather
than passing a tzinfo argument to a datetime constructor.
Thus, your problem is solved like so:
>>> import pytz
>>> from datetime import datetime, date, time
>>> tz = pytz.timezone("Australia/Melbourne")
>>> the_date = date(2012, 4, 1) # use date.today() here
>>> midnight_without_tzinfo = datetime.combine(the_date, time())
>>> print midnight_without_tzinfo
2012-04-01 00:00:00
>>> midnight_with_tzinfo = tz.localize(midnight_without_tzinfo)
>>> print midnight_with_tzinfo
2012-04-01 00:00:00+11:00
>>> print midnight_with_tzinfo.astimezone(pytz.utc)
2012-03-31 13:00:00+00:00
No guarantees for dates before 1582, though.
#hop's answer is wrong on the day of transition from Daylight Saving Time (DST) e.g., Apr 1, 2012. To fix it tz.localize() could be used:
tz = pytz.timezone("Australia/Melbourne")
today = datetime.now(tz).date()
midnight = tz.localize(datetime.combine(today, time(0, 0)), is_dst=None)
utc_dt = midnight.astimezone(pytz.utc)
The same with comments:
#!/usr/bin/env python
from datetime import datetime, time
import pytz # pip instal pytz
tz = pytz.timezone("Australia/Melbourne") # choose timezone
# 1. get correct date for the midnight using given timezone.
today = datetime.now(tz).date()
# 2. get midnight in the correct timezone (taking into account DST)
#NOTE: tzinfo=None and tz.localize()
# assert that there is no dst transition at midnight (`is_dst=None`)
midnight = tz.localize(datetime.combine(today, time(0, 0)), is_dst=None)
# 3. convert to UTC (no need to call `utc.normalize()` due to UTC has no
# DST transitions)
fmt = '%Y-%m-%d %H:%M:%S %Z%z'
print midnight.astimezone(pytz.utc).strftime(fmt)
This is more straightforward with dateutil.tz than pytz:
>>>import datetime
>>>import dateutil.tz
>>>midnight=(datetime.datetime
.now(dateutil.tz.gettz('Australia/Melbourne'))
.replace(hour=0, minute=0, second=0, microsecond=0)
.astimezone(dateutil.tz.tzutc()))
>>>print(midnight)
2019-04-26 14:00:00+00:00
The tzinfo documentation recommends dateutil.tz since Python 3.6. The tzinfo objects from dateutil.tz have no problems with anomalies like DST without requiring the localize functionality of pytz. Using the example from user3850:
>>> now = (datetime.datetime(2012, 4, 1, 5,
... tzinfo = dateutil.tz.gettz('Australia/Melbourne')))
>>> print(now.replace(hour = 0).astimezone(dateutil.tz.tzutc()))
2012-03-31 13:00:00+00:00
Setting the TZ environment variable modifies what timezone Python's date and time functions work with.
>>> time.gmtime()
(2008, 12, 17, 1, 16, 46, 2, 352, 0)
>>> time.localtime()
(2008, 12, 16, 20, 16, 47, 1, 351, 0)
>>> os.environ['TZ']='Australia/Melbourne'
>>> time.localtime()
(2008, 12, 17, 12, 16, 53, 2, 352, 1)
Each time zone has a number, eg US/Central = -6. This is defined as the offset in hours from UTC. Since 0000 is midnight, you can simply use this offset to find the time in any time zone when it is midnight UTC. To access that, I believe you can use time.timezone
According to The Python Docs, time.timezone actually gives the negative value of this number:
time.timezone
The offset of the local (non-DST) timezone, in seconds west of UTC (negative in most of Western Europe, positive in the US, zero in the UK).
So you would simply use that number for the time in hours if it's positive (i.e., if it's midnight in Chicago (which has a +6 timezone value), then it's 6000 = 6am UTC).
If the number is negative, subtract from 24. For example, Berlin would give -1, so 24 - 1 => 2300 = 11pm.
It's worth remarking that we can adapt the answer given by #jfs to find tomorrow's midnight or yesterday's midnight, etc. The trick is to add a certain number of days to the aware timezone. This works because although this usually adds 24 hours, sometimes it might add 23 or 25 based on DST issues.
from datetime import datetime, time, timedelta
import pytz
def midnight_UTC(offset):
# Construct a timezone object
tz = pytz.timezone('Australia/Melbourne')
# Work out today/now as a timezone-aware datetime
today = datetime.now(tz)
# Adjust by the offset. Note that that adding 1 day might actually move us 23 or 25
# hours into the future, depending on daylight savings. This works because the {today}
# variable is timezone aware
target_day = today + timedelta(days=1) * offset
# Discard hours, minutes, seconds and microseconds
midnight_aware = tz.localize(
datetime.combine(target_day, time(0, 0, 0, 0)), is_dst=None)
# Convert to UTC
midnight_UTC = midnight_aware.astimezone(pytz.utc)
return midnight_UTC
print("The UTC time of the previous midnight is:", midnight_UTC(0))
print("The UTC time of the upcoming midnight is:", midnight_UTC(1))