I have a date string and want to convert it to the date type:
I have tried to use datetime.datetime.strptime with the format that I want but it is returning the time with the conversion.
when = alldates[int(daypos[0])]
print when, type(when)
then = datetime.datetime.strptime(when, '%Y-%m-%d')
print then, type(then)
This is what the output returns:
2013-05-07 <type 'str'>
2013-05-07 00:00:00 <type 'datetime.datetime'>
I need to remove the time: 00:00:00.
print then.date()
What you want is a datetime.date object. What you have is a datetime.datetime object. You can either change the object when you print as per above, or do the following when creating the object:
then = datetime.datetime.strptime(when, '%Y-%m-%d').date()
If you need the result to be timezone-aware, you can use the replace() method of datetime objects. This preserves timezone, so you can do
>>> from django.utils import timezone
>>> now = timezone.now()
>>> now
datetime.datetime(2018, 8, 30, 14, 15, 43, 726252, tzinfo=<UTC>)
>>> now.replace(hour=0, minute=0, second=0, microsecond=0)
datetime.datetime(2018, 8, 30, 0, 0, tzinfo=<UTC>)
Note that this returns a new datetime object -- now remains unchanged.
>>> print then.date(), type(then.date())
2013-05-07 <type 'datetime.date'>
To convert a string into a date, the easiest way AFAIK is the dateutil module:
import dateutil.parser
datetime_object = dateutil.parser.parse("2013-05-07")
It can also handle time zones:
print(dateutil.parser.parse("2013-05-07"))
>>> datetime.datetime(2013, 5, 7, 1, 12, 12, tzinfo=tzutc())
If you have a datetime object, say:
import pytz
import datetime
now = datetime.datetime.now(pytz.UTC)
and you want chop off the time part, then I think it is easier to construct a new object instead of "substracting the time part". It is shorter and more bullet proof:
date_part datetime.datetime(now.year, now.month, now.day, tzinfo=now.tzinfo)
It also keeps the time zone information, it is easier to read and understand than a timedelta substraction, and you also have the option to give a different time zone in the same step (which makes sense, since you will have zero time part anyway).
For me, I needed to KEEP a timetime object because I was using UTC and it's a bit of a pain. So, this is what I ended up doing:
date = datetime.datetime.utcnow()
start_of_day = date - datetime.timedelta(
hours=date.hour,
minutes=date.minute,
seconds=date.second,
microseconds=date.microsecond
)
end_of_day = start_of_day + datetime.timedelta(
hours=23,
minutes=59,
seconds=59
)
Example output:
>>> date
datetime.datetime(2016, 10, 14, 17, 21, 5, 511600)
>>> start_of_day
datetime.datetime(2016, 10, 14, 0, 0)
>>> end_of_day
datetime.datetime(2016, 10, 14, 23, 59, 59)
If you specifically want a datetime and not a date but want the time zero'd out you could combine date with datetime.min.time()
Example:
datetime.datetime.combine(datetime.datetime.today().date(),
datetime.datetime.min.time())
You can use simply pd.to_datetime(then) and pandas will convert the date elements into ISO date format- [YYYY-MM-DD].
You can pass this as map/apply to use it in a dataframe/series too.
You can usee the following code:
week_start = str(datetime.today() - timedelta(days=datetime.today().weekday() % 7)).split(' ')[0]
I want to convert a datetime with US/Eastern timezone to Budapest/Europe timezone this way:
import pytz
from datetime import datetime
ET = pytz.timezone('US/Eastern')
CET = pytz.timezone('Europe/Budapest')
time = datetime(2013, 04, 18, 0, 0, tzinfo=ET)
newTime = time.astimezone(CET)
This results newTime being: datetime.datetime(2013, 4, 18, 7, 0, tzinfo=<DstTzInfo 'Europe/Budapest' CEST+2:00:00 DST>), but it should be 2013,04,18,6,0 according to time.is and timeanddate.com converters. What do I do wrong ?
This is because of the Daylight Saving Time issue. The time passed to datetime is in the ET, not EDT, hence the result.
Take a look at pytz documentation, the preferred way is to use localize method, rather than passing tzinfo. You'll get the expected result if you amend your code to use the following line:
time = ET.localize(datetime(2013, 04, 18, 0, 0))
US/Eastern is an alias. Perhaps pytz treats it as fixed to EST instead of EDT? I'm not sure. But try America/New_York and see if that is better.
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.
I want to compare UTC timestamps from a log file with local timestamps. When creating the local datetime object, I use something like:
>>> local_time=datetime.datetime(2010, 4, 27, 12, 0, 0, 0,
tzinfo=pytz.timezone('Israel'))
I want to find an automatic tool that would replace thetzinfo=pytz.timezone('Israel') with the current local time zone.
Any ideas?
In Python 3.x, local timezone can be figured out like this:
>>> import datetime
>>> print(datetime.datetime.now(datetime.timezone.utc).astimezone().tzinfo)
AEST
It's a tricky use of datetime's code .
For python < 3.6, you'll need
>>> import datetime
>>> print(datetime.datetime.now(datetime.timezone(datetime.timedelta(0))).astimezone().tzinfo)
AEST
Try dateutil, which has a tzlocal type that does what you need.
to compare UTC timestamps from a log file with local timestamps.
It is hard to find out Olson TZ name for a local timezone in a portable manner. Fortunately, you don't need it to perform the comparison.
tzlocal module returns a pytz timezone corresponding to the local timezone:
from datetime import datetime
import pytz # $ pip install pytz
from tzlocal import get_localzone # $ pip install tzlocal
tz = get_localzone()
local_dt = tz.localize(datetime(2010, 4, 27, 12, 0, 0, 0), is_dst=None)
utc_dt = local_dt.astimezone(pytz.utc) #NOTE: utc.normalize() is unnecessary here
Unlike other solutions presented so far the above code avoids the following issues:
local time can be ambiguous i.e., a precise comparison might be impossible for some local times
utc offset can be different for the same local timezone name for dates in the past. Some libraries that support timezone-aware datetime objects (e.g., dateutil) fail to take that into account
Note: to get timezone-aware datetime object from a naive datetime object, you should use*:
local_dt = tz.localize(datetime(2010, 4, 27, 12, 0, 0, 0), is_dst=None)
instead of:
#XXX fails for some timezones
local_dt = datetime(2010, 4, 27, 12, 0, 0, 0, tzinfo=tz)
*is_dst=None forces an exception if given local time is ambiguous or non-existent.
If you are certain that all local timestamps use the same (current) utc offset for the local timezone then you could perform the comparison using only stdlib:
# convert a naive datetime object that represents time in local timezone to epoch time
timestamp1 = (datetime(2010, 4, 27, 12, 0, 0, 0) - datetime.fromtimestamp(0)).total_seconds()
# convert a naive datetime object that represents time in UTC to epoch time
timestamp2 = (datetime(2010, 4, 27, 9, 0) - datetime.utcfromtimestamp(0)).total_seconds()
timestamp1 and timestamp2 can be compared directly.
Note:
timestamp1 formula works only if the UTC offset at epoch (datetime.fromtimestamp(0)) is the same as now
fromtimestamp() creates a naive datetime object in the current local timezone
utcfromtimestamp() creates a naive datetime object in UTC.
I was asking the same to myself, and I found the answer in 1:
Take a look at section 8.1.7: the format "%z" (lowercase, the Z uppercase returns also the time zone, but not in the 4-digit format, but in the form of timezone abbreviations, like in [3]) of strftime returns the form "+/- 4DIGIT" that is standard in email headers (see section 3.3 of RFC 2822, see [2], which obsoletes the other ways of specifying the timezone for email headers).
So, if you want your timezone in this format, use:
time.strftime("%z")
[1] http://docs.python.org/2/library/datetime.html
[2] https://www.rfc-editor.org/rfc/rfc2822#section-3.3
[3] Timezone abbreviations: http://en.wikipedia.org/wiki/List_of_time_zone_abbreviations , only for reference.
The following appears to work for 3.7+, using standard libs:
from datetime import timedelta
from datetime import timezone
import time
def currenttz():
if time.daylight:
return timezone(timedelta(seconds=-time.altzone),time.tzname[1])
else:
return timezone(timedelta(seconds=-time.timezone),time.tzname[0])
First get pytz and tzlocal modules
pip install pytz tzlocal
then
from tzlocal import get_localzone
local = get_localzone()
then you can do things like
from datetime import datetime
print(datetime.now(local))
Here's a way to get the local timezone using only the standard library, (only works in a *nix environment):
>>> '/'.join(os.path.realpath('/etc/localtime').split('/')[-2:])
'Australia/Sydney'
You can use this to create a pytz timezone:
>>> import pytz
>>> my_tz_name = '/'.join(os.path.realpath('/etc/localtime').split('/')[-2:])
>>> my_tz = pytz.timezone(my_tz_name)
>>> my_tz
<DstTzInfo 'Australia/Sydney' LMT+10:05:00 STD>
...which you can then apply to a datetime:
>>> import datetime
>>> now = datetime.datetime.now()
>>> now
datetime.datetime(2014, 9, 3, 9, 23, 24, 139059)
>>> now.replace(tzinfo=my_tz)
>>> now
datetime.datetime(2014, 9, 3, 9, 23, 24, 139059, tzinfo=<DstTzInfo 'Australia/Sydney' LMT+10:05:00 STD>)
Here's a slightly more concise version of #vbem's solution:
from datetime import datetime as dt
dt.utcnow().astimezone().tzinfo
The only substantive difference is that I replaced datetime.datetime.now(datetime.timezone.utc) with datetime.datetime.utcnow(). For brevity, I also aliased datetime.datetime as dt.
For my purposes, I want the UTC offset in seconds. Here's what that looks like:
dt.utcnow().astimezone().utcoffset().total_seconds()
Avoiding non-standard module (seems to be a missing method of datetime module):
from datetime import datetime
utcOffset_min = int(round((datetime.now() - datetime.utcnow()).total_seconds())) / 60 # round for taking time twice
utcOffset_h = utcOffset_min / 60
assert(utcOffset_min == utcOffset_h * 60) # we do not handle 1/2 h timezone offsets
print 'Local time offset is %i h to UTC.' % (utcOffset_h)
To create an ISO formatted string that includes the ISO representation of your local time zone in Israel (+04:00) :
on a server in Israel:
>>> datetime.now(datetime.now().astimezone().tzinfo).isoformat()
'2021-09-07T01:02.030042+04:00'
This will create a "timezone aware" date object that will compare to any other datetime object in UTC or local time appropriately. But the time zone ISO representation (and the date/time string itself) will change if you ran this on a server in San Francisco at the exact same time, as I did:
on a server in San Francisco, CA, USA (Pacific):
>>> datetime.now(datetime.now().astimezone().tzinfo).isoformat()
'2021-09-06T14:01:02.030042-07:00'
The datetime objects in in both cases would be compatible with each other. So if you subtracted them you'd get a time delta of 0:
On a server anywhere in Python3.6+:
>>> (datetime.fromisoformat('2021-09-06T14:01:02.030042-07:00') -
... datetime.fromisoformat('2021-09-07T01:01:02.030042+04:00'))
datetime.timedelta(0)
Based on Thoku's answer above, here's an answer that resolves the time zone to the nearest half hour (which is relevant for some timezones eg South Australia's) :
from datetime import datetime
round((round((datetime.now()-datetime.utcnow()).total_seconds())/1800)/2)
Based on J. F. Sebastian's answer, you can do this with the standard library:
import time, datetime
local_timezone = datetime.timezone(datetime.timedelta(seconds=-time.timezone))
Tested in 3.4, should work on 3.4+
You may be happy with pendulum
>>> pendulum.datetime(2015, 2, 5, tz='local').timezone.name
'Israel'
Pendulum has a well designed API for manipulating dates. Everything is TZ-aware.
I have also been looking for a simple way to read the local host configuration and get timezone aware local_time based on it. As of python 3.6+ the simplest approach is use dateutil.tz which will read /etc/localtime and assist in getting timezone aware datetime object.
Here is more info on it: https://dateutil.readthedocs.io/en/stable/tz.html
The implementation to accomplish what you're looking for is as follows:
from datetime import datetime
from dateutil import tz
local_time = datetime.now(tz.gettz())
This will provide you the following local_time:
2019-10-18 13:41:06.624536-05:00
Additional Resources I used in researching this topic:
Paul Ganssle Presentation about time zones:
https://www.youtube.com/watch?v=l4UCKCo9FWY
pytz: The Fastest Footgun in the West
https://blog.ganssle.io/articles/2018/03/pytz-fastest-footgun.html
I want to compare UTC timestamps from a log file with local timestamps
If this is your intent, then I wouldn't worry about specifying specific tzinfo parameters or any additional external libraries. Since Python 3.5, the built in datetime module is all you need to create a UTC and a local timestamp automatically.
import datetime
f = "%a %b %d %H:%M:%S %Z %Y" # Full format with timezone
# tzinfo=None
cdatetime = datetime.datetime(2010, 4, 27, 12, 0, 0, 0) # 1. Your example from log
cdatetime = datetime.datetime.now() # 2. Basic date creation (default: local time)
print(cdatetime.strftime(f)) # no timezone printed
# Tue Apr 27 12:00:00 2010
utctimestamp = cdatetime.astimezone(tz=datetime.timezone.utc) # 1. convert to UTC
utctimestamp = datetime.datetime.now(tz=datetime.timezone.utc) # 2. create in UTC
print(utctimestamp.strftime(f))
# Tue Apr 27 17:00:00 UTC 2010
localtimestamp = cdatetime.astimezone() # 1. convert to local [default]
localtimestamp = datetime.datetime.now().astimezone() # 2. create with local timezone
print(localtimestamp.strftime(f))
# Tue Apr 27 12:00:00 CDT 2010
The '%Z' parameter of datetime.strftime() prints the timezone acronym into the timestamp for humans to read.
For simple things, the following tzinfo implementation can be used, which queries the OS for time zone offsets:
import datetime
import time
class LocalTZ(datetime.tzinfo):
_unixEpochOrdinal = datetime.datetime.utcfromtimestamp(0).toordinal()
def dst(self, dt):
return datetime.timedelta(0)
def utcoffset(self, dt):
t = (dt.toordinal() - self._unixEpochOrdinal)*86400 + dt.hour*3600 + dt.minute*60 + dt.second + time.timezone
utc = datetime.datetime(*time.gmtime(t)[:6])
local = datetime.datetime(*time.localtime(t)[:6])
return local - utc
print datetime.datetime.now(LocalTZ())
print datetime.datetime(2010, 4, 27, 12, 0, 0, tzinfo=LocalTZ())
# If you're in the EU, the following datetimes are right on the DST change.
print datetime.datetime(2013, 3, 31, 0, 59, 59, tzinfo=LocalTZ())
print datetime.datetime(2013, 3, 31, 1, 0, 0, tzinfo=LocalTZ())
print datetime.datetime(2013, 3, 31, 1, 59, 59, tzinfo=LocalTZ())
# The following datetime is invalid, as the clock moves directly from
# 01:59:59 standard time to 03:00:00 daylight savings time.
print datetime.datetime(2013, 3, 31, 2, 0, 0, tzinfo=LocalTZ())
print datetime.datetime(2013, 10, 27, 0, 59, 59, tzinfo=LocalTZ())
print datetime.datetime(2013, 10, 27, 1, 0, 0, tzinfo=LocalTZ())
print datetime.datetime(2013, 10, 27, 1, 59, 59, tzinfo=LocalTZ())
# The following datetime is ambigous, as 02:00 can be either DST or standard
# time. (It is interpreted as standard time.)
print datetime.datetime(2013, 10, 27, 2, 0, 0, tzinfo=LocalTZ())
tzlocal from dateutil.
Code example follows. Last string suitable for use in filenames.
>>> from datetime import datetime
>>> from dateutil.tz import tzlocal
>>> str(datetime.now(tzlocal()))
'2015-04-01 11:19:47.980883-07:00'
>>> str(datetime.now(tzlocal())).replace(' ','-').replace(':','').replace('.','-')
'2015-04-01-111947-981879-0700'
>>>
First, note that the question presents an incorrect initialization of an aware datetime object:
>>> local_time=datetime.datetime(2010, 4, 27, 12, 0, 0, 0,
... tzinfo=pytz.timezone('Israel'))
creates an invalid instance. One can see the problem by computing the UTC offset of the resulting object:
>>> print(local_time.utcoffset())
2:21:00
(Note the result which is an odd fraction of an hour.)
To initialize an aware datetime properly using pytz one should use the localize() method as follows:
>>> local_time=pytz.timezone('Israel').localize(datetime.datetime(2010, 4, 27, 12))
>>> print(local_time.utcoffset())
3:00:00
Now, if you require a local pytz timezone as the new tzinfo, you should use the tzlocal package as others have explained, but if all you need is an instance with a correct local time zone offset and abbreviation then tarting with Python 3.3, you can call the astimezone() method with no arguments to convert an aware datetime instance to your local timezone:
>>> local_time.astimezone().strftime('%Y-%m-%d %H:%M %Z %z')
'2010-04-27 05:00 EDT -0400'
now_dt = datetime.datetime.now()
utc_now = datetime.datetime.utcnow()
now_ts, utc_ts = map(time.mktime, map(datetime.datetime.timetuple, (now_dt, utc_now)))
offset = int((now_ts - utc_ts) / 3600)
hope this will help you.
Suppose I have date d like this :
>>> d
datetime(2009, 4, 19, 21, 12, tzinfo=tzoffset(None, -7200))
As you can see, it is "timezone aware", there is an offset of 2 Hour, utctime is
>>> d.utctimetuple()
time.struct_time(tm_year=2009, tm_mon=4, tm_mday=19,
tm_hour=23, tm_min=12, tm_sec=0,
tm_wday=6, tm_yday=109, tm_isdst=0)
So, real UTC date is 19th March 2009 23:12:00, right ?
Now I need to format my date in string, I use
>>> d.strftime('%Y-%m-%d %H:%M:%S.%f')
'2009-04-19 21:12:00.000000'
Which doesn't seems to take this offset into account. How to fix that ?
In addition to what #Slam has already answered:
If you want to output the UTC time without any offset, you can do
from datetime import timezone, datetime, timedelta
d = datetime(2009, 4, 19, 21, 12, tzinfo=timezone(timedelta(hours=-2)))
d.astimezone(timezone.utc).strftime('%Y-%m-%d %H:%M:%S.%f')
See datetime.astimezone in the Python docs.
The reason is python actually formatting your datetime object, not some "UTC at this point of time"
To show timezone in formatting, use %z or %Z.
Look for strf docs for details
This will convert your local time to UTC and print it:
import datetime, pytz
from dateutil.tz.tz import tzoffset
loc = datetime.datetime(2009, 4, 19, 21, 12, tzinfo=tzoffset(None, -7200))
print(loc.astimezone(pytz.utc).strftime('%Y-%m-%d %H:%M:%S.%f') )
(http://pytz.sourceforge.net/)
I couldn't import timezone module (and hadn't much time to know why)
so I set TZ environment variable which override the /etc/localtime information
>>> import os
>>> import datetime
>>> print datetime.datetime.now().strftime('%Y-%m-%d %H:%M')
2019-05-17 11:26
>>> os.environ["TZ"] = "UTC"
>>> print datetime.datetime.now().strftime('%Y-%m-%d %H:%M')
2019-05-17 09:26