0

I am new to Pythong and trying to convert DateTime in Python to int then convert int back again to DateTime, but I am missing 2 hours exactly which I don't know why.

Code:

import datetime
import calendar
import time

def test_time_conversion():
        now = datetime.datetime.now().replace(microsecond=0)
        time_now_decimal = calendar.timegm(now.timetuple())
        dt = datetime.datetime.fromtimestamp(time_now_decimal)
        time_expected_decimal = calendar.timegm(dt.replace(microsecond=0).timetuple())
        print("\n")
        print(now)
        print(time_now_decimal)
        print(dt)
        print(time_expected_decimal)

Output:

2021-11-17 14:49:39
1637160579
2021-11-17 16:49:39
1637167779
Adelin
  • 18,144
  • 26
  • 115
  • 175
  • 1
    You're not missing 2 *minutes*, you're missing 2 *hours*. Due to timezone conversion. – deceze Nov 17 '21 at 12:56
  • @deceze But since I've not provided any values for the timezone I believe it must not change ... – Adelin Nov 17 '21 at 12:58

2 Answers2

1

datetime.now() returns a local, naïve timestamp, i.e. 14:49 is your current wall clock time. timegm interprets this time as being in UTC (Greenwich mean time). And 14:49 in your timezone and 14:49 in Greenwich appears to have a 2 hour difference.

deceze
  • 510,633
  • 85
  • 743
  • 889
  • ... So use `dqtetime.utcnow()` instead of `datetime.now()`. – Mark Reed Nov 17 '21 at 12:59
  • @MarkReed Even better, use [time zone aware dates](https://stackoverflow.com/q/4530069/247696). In Python 3.2+, you can run `import datetime; datetime.datetime.now(datetime.timezone.utc).astimezone()` – Flimm Nov 17 '21 at 13:01
  • …and/or don't mix in weird functions like `timegm` which explicitly interpret dates in specific timezones. Either stay local for everything, or very explicitly handle timezones. – deceze Nov 17 '21 at 13:03
  • @deceze what do you suggest to do the jobs datetime -> number then number->datetime ? – Adelin Nov 17 '21 at 13:07
  • 1
    @Adelin `datetime.fromtimestamp(datetime.now().timestamp())` – deceze Nov 17 '21 at 13:08
0

You're missing 2 hours, not 2 minutes. It's because of timezone conversion.

datetime.now() returns timezone-naive (no timezone info saved) local time. Because of lack of timezone info, timestamp will get converted without adjusting, thus assuming the time is UTC.

Two fixes:

  • Either pass timezone you want as argument to datetime.now(). Docs. E.g. datetime.now(timezone.utc)
  • Or use datetime.utcnow() to get (still timezone-naive) UTC before converting. This approach is not recommended because timezone-naive datetime is often interpreted as local time - mentioned in all utc-but-naive methods in docs
h4z3
  • 5,265
  • 1
  • 15
  • 29