17

I have a piece of python3 code, that calls a function at 22:00.

# Imports
from datetime import datetime, date, time, timedelta
import sched
import time as mod_time

# Find the next datetime corresponding to 22:00
first_run = datetime.combine(date.today(), time(22,0))
first_run = first_run if first_run > datetime.now() else first_run + timedelta(1)

# Dumb test function
def my_function():
    print('my_function')

# Run the function at 22:00
scheduler = sched.scheduler(mod_time.time, mod_time.sleep)
scheduler.enterabs(first_run.timestamp(), 1, my_function, ())
scheduler.run()

This code is currently working in python3. I would like it to work in python2. My only problem comes from the following:

first_run.timestamp()

I tried to replace it with something like:

(first_run - datetime(1970, 1, 1)).total_seconds()

But there seems to be a problem with my timezone (UTC would be too easy, I'm in UTC+2). There should be something with tzinfo in first_run. Maybe I should add something?

I'm quite lost, and any help would be appreciated. Thanks a lot by advance for helping me.

EDIT1:

After Haochen Wu's comment, I've read Convert datetime to Unix timestamp and convert it back in python

Now I know that the following lines are equivalent for me:

(datetime.now() - datetime(1970, 1, 1)).total_seconds()
(datetime.now() - datetime.utcfromtimestamp(0)).total_seconds()

The solution should be

(datetime.now() - datetime.fromtimestamp(0)).total_seconds()

But this is not the case. This value is still different from mod_time.time().

Maybe because of winter/summer hours?

Community
  • 1
  • 1
Niols
  • 627
  • 1
  • 4
  • 13
  • 1
    Did you read this one: http://stackoverflow.com/questions/19801727/convert-datetime-to-unix-timestamp-and-convert-it-back-in-python – Haochen Wu May 04 '15 at 00:35
  • I've just read it. Now I know that `(datetime.now() - datetime(1970, 1, 1)).total_seconds()` is equivalent for me to `(datetime.now() - datetime.utcfromtimestamp(0)).total_seconds()`. The solution should be `(datetime.now() - datetime.fromtimestamp(0)).total_seconds()`. But this is not the case. This value is still different from `mod_time.time()`. Maybe because of winter/summer hours? – Niols May 04 '15 at 00:41
  • My best guess is that you'll need to implement a sub-class of tzinfo and add that to the datetime object. See the docs:https://docs.python.org/2/library/datetime.html#tzinfo-objects – Haochen Wu May 04 '15 at 00:50
  • It seems there are some help function in dateutil. Are you OK with using extra package? – Haochen Wu May 04 '15 at 00:55
  • If possible, I would like to avoid using extra package (such as dateutils that seems not to be up-to-date on pypi). But considering that it's at least the third time I encounter an advantage of using dateutils, I'll maybe use it… – Niols May 04 '15 at 01:00
  • Actually, I looked at the python3 datetime source code (as said in you link), and I found a formula not far away from Richard Albright's one. I just need to understand a little thing in it, but this will do the trick. Thanks a lot for your help – Niols May 04 '15 at 01:08

2 Answers2

11

use the following to convert to a timestamp in python 2

int((mod_time.mktime(first_run.timetuple())+first_run.microsecond/1000000.0))

  • Wouldn't the correct formula be `int(mod_time.mktime(first_run.timetuple())+first_run.microsecond/1000000.0)`? This one seems to be working. Unless I miss something? – Niols May 04 '15 at 00:58
  • you are correct, i multiplied by 1000 too much. I use timestamps a lot in the flot javascript library where you have to multiply by 1000 all the time to get the timestamp represented correctly – Richard Albright May 04 '15 at 01:03
  • 1
    Actually, here is the (almost) exact formula from the python3 datetime source code: `mod_time.mktime(first_run.timetuple()) + first_run.microsecond / 1e6`. This is almost yours (modulo the little *1000 mistake). – Niols May 04 '15 at 01:06
9

use time.time() in python2, it's analog to datetime.timestamp() in python3

datetime.datetime.timestamp

IF you need for current datetime realization, see implementation of that in python3:

def timestamp(self):
    "Return POSIX timestamp as float"
    if self._tzinfo is None:
        return _time.mktime((self.year, self.month, self.day,
                             self.hour, self.minute, self.second,
                             -1, -1, -1)) + self.microsecond / 1e6
    else:
        return (self - _EPOCH).total_seconds()

where _EPOCH = datetime(1970, 1, 1, tzinfo=timezone.utc)

Reishin
  • 1,854
  • 18
  • 21
  • This is not correct. time.time() will only give the timestamp of current time, not the timestamp of the datetime instance. – Haochen Wu May 04 '15 at 00:47
  • 1
    Problem is that `time.time()` returns the current timestamp, and not the timestamp corresponding to a specific hour given by a datetime element. – Niols May 04 '15 at 00:50
  • @Niols so you completely ignore second part of the answer, nice – Reishin Oct 02 '16 at 08:48
  • This should be marked as the correct answer since it works as py3 timestamp() – nitely Mar 13 '19 at 09:07