I'm trying to convert Bill Clinton's Birthday
August 19, 8:51 AM - Hope, Arkansas
To UTC Time but I keep getting discrepancies.
In python when I do:
import datetime
from datetime import timezone
from zoneinfo import ZoneInfo
dt = datetime(1946, 8, 16, 8, 51, tzinfo=ZoneInfo('America/Chicago'))
dt.astimezone(timezone.utc)
# This returns
#datetime.datetime(1946, 8, 16, 13, 51, tzinfo=datetime.timezone.utc)
All libraries I use and even online date to UTC time converters converts the date to
13:51 UTC.
However, official astrology datasets such as https://www.astro-seek.com/birth-chart/bill-clinton-horoscope, https://www.astro.com/astro-databank/Clinton,_Bill,
etc
All compute his natal chart using his birth time as 14:51 UTC, even though they all still use the proper local time.
My question is: What is causing this discrepancy and how do I know which UTC time is right?
Related
I'm facing a python timezones problem and am unsure of what is the right approach to deal with it. I have to calculate timedeltas from given start and end DateTime objects. It can happen that daylight saving time will change during the runtime of my events, so I have to take that into account.
So far I've learned that for this to work I need to save my start and end times as timezone aware DateTime objects rather than regular UTC DateTimes.
I've been looking into DateTime.tzinfo, pytz,and dateutil but from what I understand these are all mostly focused on localised display of UTC DateTime objects or calculating the offsets between different timezones. Other helpers I found expect the timezone as a UTC offset, so would already require me to know if a date is affected by daylight saving or not.
So, I guess my question is: Is there a way so save a DateTime as "Central Europe" and have it be aware of daytime savings when doing calculations with them? Or, if not, what would be the established way to check if two DateTime objects are within daylight saving, so I can manually adjust the result if necessary?
I'd be grateful for any pointers.
You just need to produce an aware (localised) datetime instance, then any calculation you do with it will take DST into account. Here as an example with pytz:
>>> import pytz
>>> from datetime import *
>>> berlin = pytz.timezone('Europe/Berlin')
>>> d1 = berlin.localize(datetime(2023, 3, 25, 12))
datetime.datetime(2023, 3, 25, 12, 0, tzinfo=<DstTzInfo 'Europe/Berlin' CET+1:00:00 STD>)
>>> d2 = berlin.localize(datetime(2023, 3, 26, 12))
datetime.datetime(2023, 3, 26, 12, 0, tzinfo=<DstTzInfo 'Europe/Berlin' CEST+2:00:00 DST>)
>>> d2 - d1
datetime.timedelta(seconds=82800)
>>> (d2 - d1).total_seconds() / 60 / 60
23.0
datetime.utcnow()
This call is returning an incorrect datetime, delayed from UTC/GMT by 1 hour (check in: http://www.worldtimeserver.com/current_time_in_UTC.asp).
Is it working like it should be?
For example, it's returning, right now:
2015-02-17 23:58:44.761000.
Current UTC time is: 00:58, not 23:58
I know I'm five years late, but I had the same problem tonight. In my experience, the solution to the problem was to use the aware UTC datetime:
utc_dt_aware = datetime.datetime.now(datetime.timezone.utc)
If you google "utcnow() wrong" this is the first result you get, so I thought it would be good to answer anyway.
datetime.utcnow() uses OS provided values.
datetime.utcnow() uses gettimeofday(2) or time.time() on Python 2 (and gmtime(3) to convert the result into broken-down time).
time.time() uses gettimeofday(2), ftime(3), time(2). Newer CPython versions may use clock_gettime(2), GetSystemTimeAsFileTime().
You could check the self-consistency as follows:
#!/usr/bin/env python
import time
from datetime import datetime, timedelta
print(datetime.utcnow())
print(datetime(1970, 1, 1) + timedelta(seconds=time.time()))
print(datetime(*time.gmtime()[:6]))
Here's (non-tested) code that calls GetSystemTimeAsFileTime() on Windows based on CPython source:
#!/usr/bin/env python
import ctypes.wintypes
from datetime import datetime, timedelta
def utcnow_microseconds():
system_time = ctypes.wintypes.FILETIME()
ctypes.windll.kernel32.GetSystemTimeAsFileTime(ctypes.byref(system_time))
large = (system_time.dwHighDateTime << 32) + system_time.dwLowDateTime
return large // 10 - 11644473600000000
print(datetime(1970, 1, 1) + timedelta(microseconds=utcnow_microseconds()))
Here's code that calls clock_gettime() on Python 2.
Problem only occurs with utc time (Python3).
e.g. System time:
$ date
Wed Jul 15 10:44:26 BST 2015
Python time correct when using datetime.now():
>>> datetime.now()
datetime.datetime(2015, 7, 15, 10, 44, 30, 775840)
...But incorrect by one hour when using datetime.utcnow():
>>> datetime.utcnow()
datetime.datetime(2015, 7, 15, 9, 44, 32, 599823)
UTC's problem is it doesn't know my timezone.
You have to tell it, with the help of a timezone module called pytz:
>>> import pytz
>>> mytz = pytz.timezone('Europe/London')
>>> pytz.utc.localize(datetime.utcnow(), is_dst=None).astimezone(mytz)
datetime.datetime(2015, 7, 15, 11, 3, 43, 688681, tzinfo=<DstTzInfo 'Europe/London' BST+1:00:00 DST>)
References:
pytz - Converting UTC and timezone to local time
https://opensourcehacker.com/2008/06/30/relativity-of-time-shortcomings-in-python-datetime-and-workaround/
http://sweemengs-tech-world.blogspot.co.uk/2010/05/get-correct-datetime-value-for-python.html
http://bugs.python.org/issue5094)
I know I am tremendously late in replying to this.
I have tried doing this recently and therefore I suggest using datetime.now() instead of datetime.utcnow(). For my simple application that works fine.
I am having a hard time converting a string representation of non-UTC times to UTC due to the timezone abbreviation.
(update: it seems that the timezone abbreviations may not be unique. if so, perhaps i should also be trying to take this into account.)
I've been trying to look for a way around this using datetutil and pytz, but haven't had any luck.
Suggestions or workaround would be appreciated.
string = "Jun 20, 4:00PM EDT"
I'd like to convert that into UTC time, accounting for daylight savings when appropriate.
UPDATE: Found some references that may help more experienced users answer the Q.
Essentially, I would imagine part of the solution doing the reverse of this.
FINAL UPDATE (IMPORTANT)
Taken from the dateutil docs examples.
Some simple examples based on the date command, using the TZOFFSET dictionary to provide the BRST timezone offset.
parse("Thu Sep 25 10:36:28 BRST 2003", tzinfos=TZOFFSETS)
datetime.datetime(2003, 9, 25, 10, 36, 28,
tzinfo=tzoffset('BRST', -10800))
parse("2003 10:36:28 BRST 25 Sep Thu", tzinfos=TZOFFSETS)
datetime.datetime(2003, 9, 25, 10, 36, 28,
tzinfo=tzoffset('BRST', -10800))
Combine this with a library such as found here. and you will have a solution to this problem.
Using Nas Banov's excellent dictionary mapping timezone abbreviations to UTC offset:
import dateutil
import pytz
# timezone dictionary built here: https://stackoverflow.com/a/4766400/366335
# tzd = {...}
string = 'Jun 20, 4:00PM EDT'
date = dateutil.parser.parse(string, tzinfos=tzd).astimezone(pytz.utc)
I'm receiving a formatted date string like this via the pivotal tracker API: "2012/06/05 17:42:29 CEST"
I want to convert this string to a UTC datetime object, it looks like python-dateutil does not recognize that timezone, pytz doesn't know it either.
I fear my best bet is to replace CEST in the string with CET, but this feels very wrong. Is there any other way to parse summer time strings to UTC datetime objects I couldn't find?
pytz.timezone('CEST')
# -> pytz.exceptions.UnknownTimeZoneError: 'CEST'
dateutil.parser.parse("2012/06/05 17:42:29 CEST")
# -> datetime.datetime(2012, 6, 5, 17, 42, 29)
Edit: After thinking about it again subtracting one hour is completely false as the corresponding timezone is also currently in summer time, the issue of parsing still stands
There is no real CEST timezone. Use Europe/Paris, Europe/Berlin or Europe/Prague (or another one) according to your region:
>>> pytz.country_timezones('de')
[u'Europe/Berlin']
>>> pytz.country_timezones('fr')
[u'Europe/Paris']
They are (currently) identical and all referring to CEST in summer.
>>> dateutil.parser.parse("2012/06/05 17:42:29 CEST").astimezone(pytz.utc)
datetime.datetime(2012, 6, 5, 15, 42, 29, tzinfo=<UTC>)
If I convert a UTC datetime to swedish format, summertime is included (CEST). However, while creating a datetime with sweden as the timezone, it gets CET instead of CEST. Why is this?
>>> # Modified for readability
>>> import pytz
>>> import datetime
>>> sweden = pytz.timezone('Europe/Stockholm')
>>>
>>> datetime.datetime(2010, 4, 20, 16, 20, tzinfo=pytz.utc).astimezone(sweden)
datetime(2010, 4, 20, 18, 20, tzinfo=<... 'Europe/Stockholm' CEST+2:00:00 DST>)
>>>
>>> datetime.datetime(2010, 4, 20, 18, 20, tzinfo=sweden)
datetime(2010, 4, 20, 18, 20, tzinfo=<... 'Europe/Stockholm' CET+1:00:00 STD>)
>>>
The sweden object specifies the CET time zone by default but contains enough information to know when CEST starts and stop.
In the first example, you create a datetime object and convert it to local time. The sweden object knows that the UTC time you passed occurs during daylight savings time and can convert it appropriately.
In the second example, the datetime constructor always interprets your input as not-daylight-savings-time and returns an appropriate object.
If datetime treated your input as wall-clock time and chose the appropriate daylight-savings setting for you, there would be an ambiguity during the time of year when clocks are set back. On a wall-clock the same hour occurs twice. Hence, datetime forces you to specify which timezone you're using when you create the datetime object.
Timezone abbreviations are not unique. For example "IST" could refer to "Irish Standard Time", "Iranian Standard Time", "Indian Standard Time" or "Isreali Standard Time". You shouldn't rely on parsing that, and instead should use zoneinfo timezones.