printing datetime with tzinfo results in two different offsets [duplicate] - python-3.x

I'm trying to convert timezone aware datetime object to UTC and then back to it's original timezone. I have a following snippet
t = datetime(
2013, 11, 22, hour=11, minute=0,
tzinfo=pytz.timezone('Europe/Warsaw')
)
now in ipython:
In [18]: t
Out[18]: datetime.datetime(
2013, 11, 22, 11, 0, tzinfo=<DstTzInfo 'Europe/Warsaw' WMT+1:24:00 STD>
)
and now let's try to do conversion to UTC and back. I would expect to have the same representation as:
In [19]: t.astimezone(pytz.utc).astimezone(pytz.timezone('Europe/Warsaw'))
Out[19]: datetime.datetime(
2013, 11, 22, 10, 36, tzinfo=<DstTzInfo 'Europe/Warsaw' CET+1:00:00 STD>
)
Yet we see that Out[18] and Out[19] differ. What's going on?

The documentation http://pytz.sourceforge.net/ states "Unfortunately using the tzinfo argument of the standard datetime constructors 'does not work' with pytz for many timezones." The code:
t = datetime(
2013, 5, 11, hour=11, minute=0,
tzinfo=pytz.timezone('Europe/Warsaw')
)
doesn't work according to this, instead you should use the localize method:
t = pytz.timezone('Europe/Warsaw').localize(
datetime(2013, 5, 11, hour=11, minute=0))

Related

Sorting datetime objects in Python with timezone imported from SQL

I have a list of datetime objects in a Python list and want to sort it using .sort().
Reading other similar questions, this is fairly straight forward and should do the job.
But it seems to be not working in my case.
I have following datetime objects
d1 = datetime.datetime(2017, 2, 20, 14, 25, 10, tzinfo=<git.objects.util.tzoffset object at 0x7f773d9c02d0>)
d2 = datetime.datetime(2017, 2, 20, 15, 11, 44, tzinfo=<git.objects.util.tzoffset object at 0x7f773d9c02d0>)
d1<d2 # returns false which is incorrect
d1.tzname() #returns 'fixed' for both d1 and d2
I am not sure if there are any other aspect of datetime object I am missing. The datetime list is populated extracting from SQL . Extracting from SQL is pretty straight forward and does not seem relevant to this case.
Not entirely sure whats going on but the underlying reason for the comparison result is obtained by .astimezone()
d1 = datetime.datetime(2017, 2, 20, 16, 25, 10, tzinfo=datetime.timezone(datetime.timedelta(days=-1, seconds=64800), 'CST'))
d2 = datetime.datetime(2017, 2, 20, 16, 11, 44, tzinfo=datetime.timezone(datetime.timedelta(days=-1, seconds=64800), 'CST'))

python get unix timestamp given a timezone and datetime

is there a simplified way to get unix timestamp given a timezone and datetime using datetime and pytz?
I searched some answers but not exactly this case.
Given the moment datetime.datetime(2020, 3, 15, 22, 0, 0) in tz Asia/Tokyo, goal is to get the unix timestamp of that moment.
You will need to use a 3rd-party library to convert 'Asia/Tokyo' into a proper timezone. The most common one used is the pytz library as follows:
import datetime
import pytz
naive_datetime = datetime.datetime(2020, 3, 15, 22, 0, 0)
new_datetime = naive_datetime.astimezone(pytz.timezone('Asia/Tokyo'))
new_datetime will now yield datetime.datetime(2020, 3, 16, 5, 0, tzinfo=<DstTzInfo 'Asia/Tokyo' JST+9:00:00 STD>)
Then you use the timestamp method on the datetime to get the UTC UNIX timestamp:
>>> new_datetime.timestamp()
1584302400.0
>>> datetime.datetime.utcfromtimestamp(1584302400.0)
datetime.datetime(2020, 3, 15, 20, 0)
You could also look into the pendulum library, which offers an all-around friendly experience dealing with times and dates.

Using Python Boto3 AWS Lambda, S3 Key LastModified returns in two types for two different ways

The LastModified of a given key returns in two different formats.
If I store in a variable or directly print, it gives me this format:
2019-04-17 11:14:11+00:00
And
If I try to store it as a value in a dict, and then print it, it shows in this format:
{'redshift_data_source/grid/load.csv': datetime.datetime(2019, 4, 17, 11, 14, 11, tzinfo=tzlocal())}
Why such a difference in formats?
Secondly, my purpose is to store the LastModified in a file and check everyday if the LastModified of the file has changed or not. How can I do it without uploading .zip of extra libraries?
I want something like this (where a should come from the file I am storing the metadata and b should be the latest file's metadata read:
a = datetime.datetime(2019, 4, 17, 11, 14, 11, tzinfo=tzlocal()) # yesterday
b = datetime.datetime(2019, 4, 18, 05, 53, 19, tzinfo=tzlocal()) # today
print(a < b) # True
Solved it using stringification of the value I get from the metadata:
str(datetime.datetime(2019, 4, 17, 11, 14, 11, tzinfo=tzlocal()))
The above line gave me:
2019-04-17 11:14:11+00:00
And then, for a comparison I had to strip the last portion, as that is not fitting into any standard date format, so I did:
old = datetime.datetime.strptime(tables_dict[objects["Contents"][0]["Key"]][:19], '%Y-%m-%d %H:%M:%S')
And then do my comparison to go ahead with the logic.

Force AWS Lambda to use UTC when listing S3 objects using boto3

When retrieving a list of objects on AWS Lambda using Python 3.6 and boto3, the objects' LastModified attribute is using 'LastModified': datetime.datetime(2018, 8, 17, 1, 51, 31, tzinfo=tzlocal()).
When I run my program locally, this attribute is using 'LastModified': datetime.datetime(2018, 8, 17, 1, 51, 31, tzinfo=tzutc()), which is what I want.
Why is this happening? Is there a workaround that will allow me to specify UTC as part of the request? Alternatively, is there a simple way to convert these datetimes to UTC after they're returned from S3?
Running this code:
from datetime import datetime
from dateutil import tz
from dateutil.tz import tzlocal
d_local = datetime(2018, 8, 17, 1, 51, 31, tzinfo=tzlocal())
d_utc = d_local.astimezone(tz.tzutc())
The result is that d_utc is:
datetime.datetime(2018, 8, 16, 15, 51, 31, tzinfo=tzutc())

Parse date/time in the format 2017-05-16T19:00:00.451-0400 with Python

I've following string representing date/time:
my_datetime = "2017-05-16T19:00:00.451-0400"
With
datetime.strptime(my_datetime[:19], "%Y-%m-%dT%H:%M:%S")
I get
datetime.datetime(2017, 5, 16, 19, 0)
However, I don't understand what the 451-0400 part means and if there is better way to parse this string.
You have microseconds and a timezone offset. You can parse the first with %f, and the latter with %z, provided you use Python 3.2 or newer:
>>> datetime.strptime(my_datetime, "%Y-%m-%dT%H:%M:%S.%f%z")
datetime.datetime(2017, 5, 16, 19, 0, 0, 451000, tzinfo=datetime.timezone(datetime.timedelta(-1, 72000)))

Resources