converting time from UTC to CST - python-3.x

I am trying to convert UTC time to CST. But I am not getting the output as expected.
Below is my code:
import datetime
import pytz
fmt = '%Y-%m-%d %H:%M:%S %Z%z'
e = pytz.timezone('US/Central')
time_from_utc = datetime.datetime.utcfromtimestamp(int(1607020200))
time_from = time_from_utc.astimezone(e)
time_from.strftime(fmt)
time_to_utc = datetime.datetime.utcfromtimestamp(int(1609785000))
time_to = time_to_utc.astimezone(tz=pytz.timezone('US/Central'))
print(time_from_utc)
print(time_from)
print(time_to_utc)
print(time_to)
Here is the output:
(base) ranjeet#casper:~/Desktop$ python3 ext.py
2020-12-03 18:30:00
2020-12-03 07:00:00-06:00
2021-01-04 18:30:00
2021-01-04 07:00:00-06:00
I was expecting that after conversion, I should get time corresponding to the time of UTC i.e.
2020-12-03 18:30:00
2020-12-03 12:30:00-06:00
since CST is -6 Hours from UTC.
Any help is appreciated.

the problem is that
time_from_utc = datetime.datetime.utcfromtimestamp(int(1607020200))
gives you a naive datetime object - which Python treats as local time by default. Then, in
time_from = time_from_utc.astimezone(e)
things go wrong since time_from_utc is treated as local time. Instead, set UTC explicitly when calling fromtimestamp:
from datetime import datetime, timezone
import pytz
fmt = '%Y-%m-%d %H:%M:%S %Z%z'
e = pytz.timezone('US/Central')
time_from_utc = datetime.fromtimestamp(1607020200, tz=timezone.utc)
time_from = time_from_utc.astimezone(e)
time_from.strftime(fmt)
time_to_utc = datetime.fromtimestamp(1609785000, tz=timezone.utc)
time_to = time_to_utc.astimezone(tz=pytz.timezone('US/Central'))
which will give you
2020-12-03 18:30:00+00:00
2020-12-03 12:30:00-06:00
2021-01-04 18:30:00+00:00
2021-01-04 12:30:00-06:00
Final Remarks: with Python 3.9, you have zoneinfo, so you don't need a third party library for handling of time zones. Example usage.

Related

How can I parse a custom string as a timezone aware datetime?

How can I parse
18 January 2022, 14:50 GMT-5
as a timezone aware datetime.
pytz.timezone('GMT-5')
fails.
It appears I may need to parse the GMT part, and manually apply the 5 hours offset post parsing?
Hmm How about maybe:
import re
import datetime
foo = "18 January 2022, 14:50 GMT-5"
bar = re.sub(r"[+-]\d+$", lambda m: "{:05d}".format(100 * int(m.group())), foo)
print(datetime.datetime.strptime(bar, "%d %B %Y, %H:%M %Z%z" ))
I think that gives you:
2022-01-18 14:50:00-05:00

How to determine the appropriate the timezone to apply for historical dates in a give region in python3

I'm using python3 on Ubuntu 20.04.
I have a trove of files with naive datetime strings in them, dating back more than 20 years. I know that all of these datetimes are in the Pacific Timezone. I would like to convert them all to UTC datetimes.
However, whether they are relative to PDT or PST is a bigger question. Since when PDT/PST changes has changed over the last 20 years, it's not just a matter of doing a simple date/month threshold to figure out whether to apply the pdt or pst timezone. Is there an elegant way to make this determination and apply it?
Note upfront, for Python 3.9+: use zoneinfo from the standard library, no need anymore for a third party library. Example.
Here's what you can to do set the timezone and convert to UTC. dateutil will take DST changes from the IANA database.
from datetime import datetime
import dateutil
datestrings = ['1991-04-06T00:00:00', # PST
'1991-04-07T04:00:00', # PDT
'1999-10-30T00:00:00', # PDT
'1999-10-31T02:01:00', # PST
'2012-03-11T00:00:00', # PST
'2012-03-11T02:00:00'] # PDT
# to naive datetime objects
dateobj = [datetime.fromisoformat(s) for s in datestrings]
# set timezone:
tz_pacific = dateutil.tz.gettz('US/Pacific')
dtaware = [d.replace(tzinfo=tz_pacific) for d in dateobj]
# with pytz use localize() instead of replace
# check if has DST:
# for d in dtaware: print(d.dst())
# 0:00:00
# 1:00:00
# 1:00:00
# 0:00:00
# 0:00:00
# 1:00:00
# convert to UTC:
dtutc = [d.astimezone(dateutil.tz.UTC) for d in dtaware]
# check output
# for d in dtutc: print(d.isoformat())
# 1991-04-06T08:00:00+00:00
# 1991-04-07T11:00:00+00:00
# 1999-10-30T07:00:00+00:00
# 1999-10-31T10:01:00+00:00
# 2012-03-11T08:00:00+00:00
# 2012-03-11T09:00:00+00:00
Now if you'd like to be absolutely sure that DST (PDT vs. PST) is set correctly, you'd have to setup test cases and verify against IANA I guess...

Python time module mktime method returns DST as set to 1 when it is not DST

Running the following line returns a timestamp that is one hour head of the expected UTC
time.mktime(datetime.now().astimezone(pytz.UTC).timetuple())
Example:
Date: 09/19/2017 15:19:56
Correct UTC: 1505834396
Resulting UTC from line above: 1505837996
How would I get the correct UTC timestamp without it being one hour ahead?

localtime not actually giving localtime

there's obviously a time module that works in combination with this problem, but I have not found it yet.
I'm simply trying to use Pyephem on a Raspberry Pi to find out what time sunrise and sunset is for my latitude longitude coordinates.
the code is quite simply this:
import ephem
import datetime
import time
now = datetime.datetime.now()
gmNow = time.mktime(time.localtime())
Vancouver = ephem.Observer()
Vancouver.lat = 49.2878
Vancouver.horizon = 0
Vancouver.lon = -123.0502
Vancouver.elevation = 80
Vancouver.date = now
# Vancouver.date = time.localtime()
sun = ephem.Sun()
print("sunrise is at",ephem.localtime(Vancouver.next_rising(sun)))
print("sunset is going to be at ",ephem.localtime(Vancouver.next_setting(sun)))
print("now is ",now)
print("gmNow is",gmNow)
what exports, when that runs is wrong by 8 hours though. so it appears that the
ephem.localtime() is not actually running.
pi#raspberrypi ~ $ sudo python3 vivarium_sun.py
sunrise is at 2014-09-19 12:55:56.000004
sunset is going to be at 2014-09-19 00:52:30.000004
now is 2014-09-19 06:22:24.014859
gmNow is 1411132944.0
It's driving me nuts, and it's obviously one of those simple things once it's figured out, so I'm going to the hive mind here.
EDIT** Just typing 'date' into the command line of the Raspberry Pi returns the following:
pi#raspberrypi ~ $ date
Fri Sep 19 18:41:42 PDT 2014
which is accurate.
You should pass datetime.utcnow() to the observer instead of your local time.
ephem expects latitude and longitude in radians if passed as floats, use strings instead:
from datetime import datetime, timezone
import ephem
now = datetime.now(timezone.utc)
Vancouver = ephem.Observer()
Vancouver.lat = '49.2878'
Vancouver.horizon = 0
Vancouver.lon = '-123.0502'
Vancouver.elevation = 80
Vancouver.date = now
sun = ephem.Sun(Vancouver)
print("sunrise is at", ephem.localtime(Vancouver.next_rising(sun)))
print("sunset is going to be at ",
ephem.localtime(Vancouver.next_setting(sun)))
print("now is ",now.astimezone())
Output
sunrise is at 2014-09-20 06:55:38.000005
sunset is going to be at 2014-09-19 19:16:38.000004
now is 2014-09-19 19:15:04.171486-07:00

String To Datetime 5/7/2013 07:42 53 AM C#

I want to convert string to Datetime Format.
I am suing the following code but its giving me error.
Please help.
DateTime dtCurrentFile = DateTime.ParseExact(" 5/7/2013 07:42 53 AM ","d/M/yyyy HH:mm ss",null);
I am getting exception as:
String was not recognized as a valid DateTime.
Try this (not sure if that's exactly right, I'm not on windows right now):
DateTime dtCurrentFile = DateTime.ParseExact("5/7/2013 07:42 53 AM","d/M/yyyy hh:mm ss tt",null);
What has changed: using "tt" for "AM/PM", using "hh" for 12-hour clock.
DateTime dtCurrentFile = DateTime.ParseExact("5/7/2013 07:42 53 AM","d/M/yyyy HH:mm ss tt",null);
I found this solution on net.

Resources