Source code for astrocalc.times.conversions

#!/usr/local/bin/python
# encoding: utf-8
"""
*Convert times between various epochs and units*

Author
: David Young
"""
from __future__ import division
from past.utils import old_div
from builtins import object
import sys
import os
os.environ['TERM'] = 'vt100'


[docs] class conversions(object): """ *The worker class for the conversions module* **Key Arguments** - ``log`` -- logger - ``settings`` -- the settings dictionary **Usage** .. todo:: - add usage info - create a sublime snippet for usage - add mjd_to_date - add decimal_day_to_day_hour_min_sec - add date_to_mjd - convert all functions in __init__ to modules ```python usage code ``` """ # Initialisation def __init__( self, log, settings=False, ): self.log = log log.debug("instansiating a new 'conversions' object") self.settings = settings # xt-self-arg-tmpx return None
[docs] def get(self): """ *get the conversions object* **Return** - ``conversions`` .. todo:: - @review: when complete, clean get method - @review: when complete add logging """ self.log.debug('starting the ``get`` method') conversions = None self.log.debug('completed the ``get`` method') return conversions
[docs] def ut_datetime_to_mjd( self, utDatetime): """*ut datetime to mjd* If the date given has no time associated with it (e.g. ``20160426``), then the datetime assumed is ``20160426 00:00:00.0``. Precision should be respected. **Key Arguments** - ``utDatetime`` -- UT datetime. Can accept various formats e.g. ``201604261444``, ``20160426``, ``20160426144444.5452``, ``2016-04-26 14:44:44.234``, ``20160426 14h44m44.432s`` **Return** - ``mjd`` -- the MJD .. todo :: - replace getMJDFromSqlDate in all code **Usage** ```python from astrocalc.times import conversions converter = conversions( log=log ) mjd = converter.ut_datetime_to_mjd(utDatetime="20160426t1446") print(mjd) # OUT: 57504.6153 mjd = converter.ut_datetime_to_mjd(utDatetime="2016-04-26 14:44:44.234") print(mjd) # OUT: 57504.61440 ``` """ self.log.debug('starting the ``ut_datetime_to_mjd`` method') import time import re mjd = None # TRIM WHITESPACE FROM AROUND STRING utDatetime = utDatetime.strip() # DATETIME REGEX matchObject = re.match( r'^(?P<year>\d{4})\D?(?P<month>(0\d|1[0-2]))\D?(?P<day>([0-2]\d|3[0-1])(\.\d+)?)(\D?(?P<hours>([0-1]\d|2[0-3]))\D?(?P<minutes>\d{2})(\D?(?P<seconds>\d{2}(\.\d*?)?))?)?s?$', utDatetime) # RETURN ERROR IF REGEX NOT MATCHED if not matchObject: self.log.error( 'UT Datetime is not in a recognised format. Input value was `%(utDatetime)s`' % locals()) raise IOError( 'UT Datetime is not in a recognised format. Input value was `%(utDatetime)s`' % locals()) year = matchObject.group("year") month = matchObject.group("month") day = matchObject.group("day") hours = matchObject.group("hours") minutes = matchObject.group("minutes") seconds = matchObject.group("seconds") # CLEAN NUMBERS AND SET OUTPUT PRECISION if "." in day: fhours = (float(day) - int(float(day))) * 24 hours = int(fhours) fminutes = (fhours - hours) * 60 minutes = int(fminutes) seconds = fhours - minutes precision = len(repr(day).split(".")[-1]) elif not hours: hours = "00" minutes = "00" seconds = "00" precision = 1 elif not seconds: seconds = "00" # PRECISION TO NEAREST MIN i.e. 0.000694444 DAYS precision = 4 else: if "." not in seconds: precision = 5 else: decLen = len(seconds.split(".")[-1]) precision = 5 + decLen # CONVERT VALUES TO FLOAT seconds = float(seconds) year = float(year) month = float(month) day = float(day) hours = float(hours) minutes = float(minutes) # DETERMINE EXTRA TIME (SMALLER THAN A SEC) extraTime = 0. if "." in repr(seconds): extraTime = old_div(float("." + repr(seconds).split(".") [-1]), (24. * 60. * 60.)) # CONVERT TO UNIXTIME THEN MJD t = (int(year), int(month), int(day), int(hours), int(minutes), int(seconds), 0, 0, 0) unixtime = int(time.mktime(t)) mjd = (old_div(unixtime, 86400.0) - 2400000.5 + 2440587.5) + extraTime mjd = "%0.*f" % (precision, mjd) self.log.debug('completed the ``ut_datetime_to_mjd`` method') return mjd
[docs] def mjd_to_ut_datetime( self, mjd, sqlDate=False, datetimeObject=False): """*mjd to ut datetime* Precision should be respected. **Key Arguments** - ``mjd`` -- time in MJD. - ``sqlDate`` -- add a 'T' between date and time instead of space - ``datetimeObject`` -- return a datetime object instead of a string. Default *False* .. todo:: - replace getDateFromMJD in all code - replace getSQLDateFromMJD in all code **Return** - ``utDatetime`` - the UT datetime in string format **Usage** ```python from astrocalc.times import conversions converter = conversions( log=log ) utDate = converter.mjd_to_ut_datetime( mjd=57504.61577585013 ) print(utDate) # OUT: 2016-04-26 14:46:43.033 utDate = converter.mjd_to_ut_datetime( mjd=57504.61577585013, sqlDate=True ) print(utDate) # OUT: 2016-04-26T14:46:43.033 ``` """ self.log.debug('starting the ``mjd_to_ut_datetime`` method') from datetime import datetime # CONVERT TO UNIXTIME unixtime = (float(mjd) + 2400000.5 - 2440587.5) * 86400.0 theDate = datetime.utcfromtimestamp(unixtime) if datetimeObject == False: # DETERMINE PRECISION strmjd = repr(mjd) if "." not in strmjd: precisionUnit = "day" precision = 0 utDatetime = theDate.strftime("%Y-%m-%d") else: lenDec = len(strmjd.split(".")[-1]) if lenDec < 2: precisionUnit = "day" precision = 0 utDatetime = theDate.strftime("%Y-%m-%d") elif lenDec < 3: precisionUnit = "hour" precision = 0 utDatetime = theDate.strftime("%Y-%m-%d") elif lenDec < 5: precisionUnit = "minute" precision = 0 utDatetime = theDate.strftime("%Y-%m-%d %H:%M") else: precisionUnit = "second" precision = lenDec - 5 if precision > 3: precision = 3 secs = float(theDate.strftime("%S.%f")) secs = "%02.*f" % (precision, secs) utDatetime = theDate.strftime("%Y-%m-%d %H:%M:") + secs if sqlDate: utDatetime = utDatetime.replace(" ", "T") else: utDatetime = theDate self.log.debug('completed the ``mjd_to_ut_datetime`` method') return utDatetime
[docs] def decimal_day_to_day_hour_min_sec( self, daysFloat): """*Convert a day from decimal format to hours mins and sec* Precision should be respected. **Key Arguments** - ``daysFloat`` -- the day as a decimal. **Return** - ``daysInt`` -- day as an integer - ``hoursInt`` -- hour as an integer (None if input precsion too low) - ``minsInt`` -- mins as an integer (None if input precsion too low) - ``secFloat`` -- secs as a float (None if input precsion too low) **Usage** .. todo:: - replace `decimal_day_to_day_hour_min_sec` in all other code ```python from astrocalc.times import conversions converter = conversions( log=log ) daysInt, hoursInt, minsInt, secFloat = converter.decimal_day_to_day_hour_min_sec( daysFloat=24.2453 ) print(daysInt, hoursInt, minsInt, secFloat) # OUTPUT: 24, 5, 53, None daysInt, hoursInt, minsInt, secFloat = converter.decimal_day_to_day_hour_min_sec( daysFloat=24.1232435454 ) print("%(daysInt)s days, %(hoursInt)s hours, %(minsInt)s mins, %(secFloat)s sec" % locals()) # OUTPUT: 24 days, 2 hours, 57 mins, 28.242 sec ``` """ self.log.debug( 'completed the ````decimal_day_to_day_hour_min_sec`` method') daysInt = int(daysFloat) hoursFloat = (daysFloat - daysInt) * 24. hoursInt = int(hoursFloat) minsFloat = (hoursFloat - hoursInt) * 60. minsInt = int(minsFloat) secFloat = (minsFloat - minsInt) * 60. # DETERMINE PRECISION strday = repr(daysFloat) if "." not in strday: precisionUnit = "day" precision = 0 hoursInt = None minsInt = None secFloat = None else: lenDec = len(strday.split(".")[-1]) if lenDec < 2: precisionUnit = "day" precision = 0 hoursInt = None minsInt = None secFloat = None elif lenDec < 3: precisionUnit = "hour" precision = 0 minsInt = None secFloat = None elif lenDec < 5: precisionUnit = "minute" precision = 0 secFloat = None else: precisionUnit = "second" precision = lenDec - 5 if precision > 3: precision = 3 secFloat = "%02.*f" % (precision, secFloat) self.log.debug( 'completed the ``decimal_day_to_day_hour_min_sec`` method') return daysInt, hoursInt, minsInt, secFloat
# use the tab-trigger below for new method # xt-class-method