Skip to content

Instantly share code, notes, and snippets.

@wrenoud
Last active August 29, 2015 14:04
Show Gist options
  • Save wrenoud/02b12a9e0aab9866692b to your computer and use it in GitHub Desktop.
Save wrenoud/02b12a9e0aab9866692b to your computer and use it in GitHub Desktop.
Convert different time formats to datetimes or timestamps (comes with tests)
import calendar
from datetime import datetime, timedelta, tzinfo
from math import floor
def seconds(day=0.0,hour=0.0,minute=0.0,second=0.0,microsecond=0.0):
return ((day*24.0 + hour)*60.0 + minute)*60.0 + second + microsecond/1000000.0
def minutes(day=0.0,hour=0.0,minute=0.0,second=0.0,microsecond=0.0):
return (day*24.0 + hour)*60.0 + minute + (second + microsecond/1000000.0)/60.0
def hours(day=0.0,hour=0.0,minute=0.0,second=0.0,microsecond=0.0):
return day*24.0 + hour + (minute + (second + microsecond/1000000.0)/60.0)/60.0
def days(day=0.0,hour=0.0,minute=0.0,second=0.0,microsecond=0.0):
return day + (hour + (minute + (second + microsecond/1000000.0)/60.0)/60.0)/24.0
def timestamp(_datetime):
"""converts a datetime object to a timestamp"""
return float(calendar.timegm(_datetime.timetuple())) + _datetime.microsecond/10.0**6
def asDatetime(_timestamp):
"""converts a timestamp to a datetime object"""
return datetime.utcfromtimestamp(float(_timestamp))
def fromSOD(jd, SOD, year=None, timestamps=False):
_year = year if year else datetime.now().year
hour = floor(hours(second=SOD))
minute = floor(minutes(second=SOD+0.0001) - minutes(hour=hour))
second = SOD - seconds(hour=hour,minute=minute)
if second < 0: second = 0.0
_datetime = datetime.strptime("{0}{1:03d}{2:02.0f}{3:02.0f}{4:02.6f}".format(_year,jd,hour,minute,second),"%Y%j%H%M%S.%f")
return timestamp(_datetime) if timestamps else _datetime
def fromSOW(jd, SOW, year=None, timestamps=False):
_year = year if year else datetime.now().year
"""gets timestamp from jd and SOW"""
DOW = int(floor(days(second=SOW)))
SOD = SOW - seconds(DOW)
_datetime = fromSOD(jd, SOD, _year, timestamps)
return _datetime
def fromDOY(DOY, year=None, timestamps=False):
_year = year if year else datetime.now().year
# just in case
DOY = float(DOY)
jd = int(floor(DOY)) + 1
SOD = round(seconds(DOY + 1 - jd),6)
_datetime = fromSOD(jd, SOD, _year, timestamps)
return _datetime
def DOY(_datetime, timestamps=False):
"""gets timestamp from jd and SOW"""
return days(int(_datetime.strftime('%j'))-1,_datetime.hour,_datetime.minute,_datetime.second,_datetime.microsecond)
dayOfYear = DOY
day_of_year = DOY
def SOW(_datetime, timestamps=False):
"""gets timestamp from jd and SOW"""
DOW = (_datetime.weekday() + 1) % 7
return seconds(DOW,_datetime.hour,_datetime.minute,_datetime.second,_datetime.microsecond)
secondsOfWeek = SOW
seconds_of_week = SOW
def SOD(_datetime, timestamps=False):
"""gets timestamp from jd and SOW"""
return seconds(0.0,_datetime.hour,_datetime.minute,_datetime.second,_datetime.microsecond)
secondsOfDay = SOD
seconds_of_day = SOD
def gpsWeek(_datetime):
return (_datetime - datetime(1980,1,6)).days / 7
def gpsToUTC(data):
"""Converts datetimes from GPS to UTC"""
if isinstance(data, datetime):
ref_date = data
else:
ref_date = data[0]
if(ref_date < datetime(1981,7,1)):
gpsoffset = 0
elif(ref_date < datetime(1982,7,1)):
gpsoffset = 1
elif(ref_date < datetime(1983,7,1)):
gpsoffset = 2
elif(ref_date < datetime(1985,7,1)):
gpsoffset = 3
elif(ref_date < datetime(1988,1,1)):
gpsoffset = 4
elif(ref_date < datetime(1990,1,1)):
gpsoffset = 5
elif(ref_date < datetime(1991,1,1)):
gpsoffset = 6
elif(ref_date < datetime(1992,7,1)):
gpsoffset = 7
elif(ref_date < datetime(1993,7,1)):
gpsoffset = 8
elif(ref_date < datetime(1994,7,1)):
gpsoffset = 9
elif(ref_date < datetime(1996,1,1)):
gpsoffset = 10
elif(ref_date < datetime(1997,7,1)):
gpsoffset = 11
elif(ref_date < datetime(1999,1,1)):
gpsoffset = 12
elif(ref_date < datetime(2006,1,1)):
gpsoffset = 13
elif(ref_date < datetime(2009,1,1)):
gpsoffset = 14
elif(ref_date < datetime(2012,7,1)):
gpsoffset = 15
else:
gpsoffset = 16
return data - timedelta(0, gpsoffset)
if __name__ == "__main__":
import unittest
class timehandlerTests(unittest.TestCase):
def setUp(self):
# specifically using date before end of February to avoid leapyears
self.dt_1999 = datetime(1999, 2, 12, 0, 0, 50, 138)
self.dt_now = datetime(datetime.now().year, 2, 12, 0, 0, 50, 138)
self.jd = 43
self.dow = 5
self.sod = 50.000138
self.sow = 432050.000138
self.doy = (self.jd - 1) + days(second=self.sod)
self.ts = 918777650.000138
def testTimestamp(self):
_datetime = datetime(2013, 1, 1, 1, 1, 1, 138)
self.assertEqual(timestamp(self.dt_1999), self.ts)
self.assertEqual(datetime.utcfromtimestamp(timestamp(self.dt_1999)),self.dt_1999)
def testFromSOD(self):
self.assertEqual(fromSOD(self.jd,self.sod,1999),self.dt_1999)
self.assertEqual(fromSOD(self.jd,self.sod,1999,True),timestamp(self.dt_1999))
self.assertEqual(fromSOD(self.jd,self.sod),self.dt_now)
self.assertEqual(fromSOD(self.jd,self.sod,timestamps=True),timestamp(self.dt_now))
def testFromSOW(self):
self.assertEqual(fromSOW(self.jd,self.sow,1999),self.dt_1999)
self.assertEqual(fromSOW(self.jd,self.sow,1999,True),timestamp(self.dt_1999))
self.assertEqual(fromSOW(self.jd,self.sow),self.dt_now)
self.assertEqual(fromSOW(self.jd,self.sow,timestamps=True),timestamp(self.dt_now))
def testFromDOY(self):
self.assertEqual(fromDOY(self.doy,1999),self.dt_1999)
self.assertEqual(fromDOY(self.doy,1999,True),timestamp(self.dt_1999))
self.assertEqual(fromDOY(self.doy),self.dt_now)
self.assertEqual(fromDOY(self.doy,timestamps=True),timestamp(self.dt_now))
def testSOW(self):
self.assertEqual(SOW(self.dt_1999),self.sow)
def testSOD(self):
self.assertEqual(SOD(self.dt_1999),self.sod)
def testDOY(self):
self.assertEqual(DOY(self.dt_1999),self.doy)
def testSeconds(self):
self.assertEqual(seconds(1,1,1,1,1), 90061.000001)
def testMinutes(self):
self.assertAlmostEqual(minutes(1,1,1,1,1), 90061.000001/60.0)
def testHours(self):
self.assertAlmostEqual(hours(1,1,1,1,1), 90061.000001/60.0/60.0)
def testDays(self):
self.assertAlmostEqual(days(1,1,1,1,1), 90061.000001/60.0/60.0/24.0)
unittest.main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment