JimFuqua
JimFuqua

Reputation: 1071

Python make datetime offset aware

I want to get the offset for datetime and make an aware string.

The following IDLE code works:

Python 3.6.5 (default, Apr 1 2018, 05:46:30)
[GCC 7.3.0] on linux

import datetime
date_now = datetime.datetime.now()
date_now_with_offset = date_now.astimezone()
print(date_now_with_offset)
2018-06-03 17:48:50.258504-05:00

The following code in a script gives an error:

import datetime
date_now = datetime.datetime.now()
date_now_with_offset = date_now.astimezone()
print(date_now_with_offset)

TypeError: Required argument 'tz' (pos 1) not found

I realize that offset and timezone are different but at any given moment the local time should be offset the same as an accurate timezone offset even though timezone offset may fluctuate during the year.

What is happening and why? What is the best solution?

Upvotes: 5

Views: 3497

Answers (4)

Overview: you can convert local time to another time zone and display the new time by using astimezone. The astimezone will convert the local time to the timezone datetime. timezone.utc has 0 timezone offset. astimezone changes the clock and the utc offset. astimezone moves the hours and days to match the timezone.

from datetime import datetime, timedelta, timezone
print("Eastern Standard Time Zone")
ET=timezone(timedelta(hours=-5))
dt=datetime(2017,12,30,15,9,3)
print(dt.astimezone(ET))
print("India Standard Time Zone")
IST= timezone(timedelta(hours=5,minutes=30))
dt=datetime(2017,12,30,15,9,3)
print(dt.astimezone(IST))

Upvotes: 0

user2314737
user2314737

Reputation: 29307

If a datetime object is missing a timezone you can add it with:

from datetime import datetime, timezone

datetime(1970,1,1).replace(tzinfo=timezone.utc)

or when constructing the datetime object

datetime(1970,1,1).tzinfo==None                                                                                                                              
# Out: True
datetime(1970,1,1, tzinfo=timezone.utc).tzinfo                                                                                                               
# Out: datetime.timezone.utc

timezone is available from version 3.2

I had a similar error with Python 3 when trying to compute the time difference

d = "Tue 01 May 2018 10:34:15 -0000" # date string with timezone
dt = datetime.strptime(d, "%a %d %b %Y %H:%M:%S %z")                                                                                                         
dt                                                                                                                                                           
# datetime.datetime(2018, 5, 1, 10, 34, 15, tzinfo=datetime.timezone.utc)
dt - datetime(1970,1,1)
# TypeError: can't subtract offset-naive and offset-aware datetimes

Solution: add timezone when creating datetime or modify existing datetime object

dt.tzinfo    
# datetime.timezone.utc
dt - datetime(1970,1,1, tzinfo=timezone.utc)                                                                                                                    
# datetime.timedelta(days=17652, seconds=38055)

# or modify already existing datetime 
d_aware = datetime(1970,1,1).replace(tzinfo=timezone.utc)
dt - d_aware
datetime.timedelta(days=17652, seconds=38055)

Define the timezone in your date as needed/according to your knowledge of the missing timezone.

Just a note: datetime(1970,1,1, tzinfo=timezone.utc) is the Epoch time (or POSIX/Unix time) and by definition has UTC timezone.

Upvotes: 4

From your traceback: TypeError: Required argument 'tz' (pos 1) not found. Your script is using Python2, which is generally not compatible with Python3. In Python2 you have to provide a timezone. See the difference between the Python2 and Python3 documentation.

In Linux, the python word specifically means python2. Python3 is typed using python3 unless you use an alias. To fix it, change all occurrences of python to python3, as in

#! /usr/bin/env python3
python3 offset.py

Note: From the Python3 Documentation, it does not work on all versions of Python3:

Changed in version 3.3: tz now can be omitted.

Changed in version 3.6: The astimezone() method can now be called on naive instances that are presumed to represent system local time.`

Upvotes: 1

NickD
NickD

Reputation: 6402

The script is being executed by the python2 interpreter. Add an explicit python3 shebang to the script:

#! /usr/bin/env python3

import datetime
....

Upvotes: 1

Related Questions