Ejemplo n.º 1
0
 def elevations(self, days_offset=0):
     '''
     Return the time of the astronomical, nautical, and civil dusk and dawns,
     as well as the solar noon and the sunrise and sunset, for the day (local time).
     
     @param   days_offset:int                       The number of days into the future, 0 for today.
     @return  :(:str?, :str?, :str?, :str?, :str,   The time, restrict to the selected day of, in order:
                :str?, :str?, :str?, :str?)         the astronomical dawn, the nautical dawn, the civil
                                                    dawn, the sunrise, the solar noon, the sunset, the
                                                    the civil dusk, thenautical dusk, and the astronomical
                                                    dusk. (Those are in chronological order.) If such
                                                    condition is not meet during the day, `None` is
                                                    returned in place. Solar noon is guaranteed (I think.)
                                                    Times are formatted in '%Y-%m-%d %H:%M:%S'.
     '''
     import solar_python as s, time
     tz = -(time.timezone, time.altzone)[time.localtime().tm_isdst]
     a_day = 60 * 60 * 24
     t = time.time()
     t += tz
     t -= t % a_day
     t -= tz
     t += days_offset * a_day
     start = s.epoch_to_julian_centuries(t)
     end = s.epoch_to_julian_centuries(t + a_day)
     t5a = s.future_elevation_derivative(self.lat, self.lon, 0, start)
     t5b = s.future_elevation_derivative(self.lat, self.lon, 0,
                                         t5a + 0.0000002)
     e1 = s.solar_elevation(self.lat, self.lon, t5a)
     e2 = s.solar_elevation(self.lat, self.lon, t5b)
     t5 = t5a if e1 > e2 else t5b
     t1 = s.past_elevation(self.lat, self.lon,
                           s.SOLAR_ELEVATION_ASTRONOMICAL_DUSK_DAWN, t5)
     t2 = s.past_elevation(self.lat, self.lon,
                           s.SOLAR_ELEVATION_NAUTICAL_DUSK_DAWN, t5)
     t3 = s.past_elevation(self.lat, self.lon,
                           s.SOLAR_ELEVATION_CIVIL_DUSK_DAWN, t5)
     t4 = s.past_elevation(self.lat, self.lon,
                           s.SOLAR_ELEVATION_SUNSET_SUNRISE, t5)
     t6 = s.future_elevation(self.lat, self.lon,
                             s.SOLAR_ELEVATION_SUNSET_SUNRISE, t5)
     t7 = s.future_elevation(self.lat, self.lon,
                             s.SOLAR_ELEVATION_CIVIL_DUSK_DAWN, t5)
     t8 = s.future_elevation(self.lat, self.lon,
                             s.SOLAR_ELEVATION_NAUTICAL_DUSK_DAWN, t5)
     t9 = s.future_elevation(self.lat, self.lon,
                             s.SOLAR_ELEVATION_ASTRONOMICAL_DUSK_DAWN, t5)
     t = (t1, t2, t3, t4, t5, t6, t7, t8, t9)
     #return tuple(Solar.__jc_to_str(x) if x is not None and start <= x <= end else None for x in t)
     return tuple(Solar.__jc_to_str(x) for x in t)
Ejemplo n.º 2
0
 def future_elevation(self, elevation):
     """
     Predict the time point of the next time the
     Sun reaches a specific elevation
     
     @param   elevation:float  The elevation of interest
     @return  :float?          The calculated time point, in POSIX time,
                               `None` if none were found within a year
     """
     return self.u(solar_python.future_elevation(self.lat, self.lon, elevation, self.now()))
Ejemplo n.º 3
0
 def future_elevation(self, elevation):
     '''
     Predict the time point of the next time the
     Sun reaches a specific elevation
     
     @param   elevation:float  The elevation of interest
     @return  :float?          The calculated time point, in POSIX time,
                               `None` if none were found within a year
     '''
     return self.u(
         solar_python.future_elevation(self.lat, self.lon, elevation,
                                       self.now()))
Ejemplo n.º 4
0
def get_elev(elev, start, morning):
    end = start + 0.0099
    while start < end:
        rc = sol.future_elevation(lat, lon, elev, start)
        if rc is None:
            return (None, end)
        else:
            start = rc + 1e-06
            d = sol.solar_elevation(lat, lon, rc + 3e-09)
            d -= sol.solar_elevation(lat, lon, rc)
            if d >= 0 if morning else d <= 0:
                return (sol.julian_centuries_to_epoch(rc), start)
    return (None, end)
Ejemplo n.º 5
0
def get_elev(elev, start, morning):
    end = start + 0.0099
    while start < end:
        rc = sol.future_elevation(lat, lon, elev, start)
        if rc is None:
            return (None, end)
        else:
            start = rc + 1e-06
            d  = sol.solar_elevation(lat, lon, rc + 3e-09)
            d -= sol.solar_elevation(lat, lon, rc)
            if d >= 0 if morning else d <= 0:
                return (sol.julian_centuries_to_epoch(rc), start)
    return (None, end)
Ejemplo n.º 6
0
    def hours(self, elevations, days_offset=0, format='%ih %i\' %i\'\''):
        '''
        Calculates the time and duration when the Sun's elevation is in
        a specific range. We will call this the X hour. Both the morning
        X hour and evening X hour is calculated. These may in fact be the
        same.
        
        @param  days_offset:int  The number of days into the future, 0 for today
        @param  :(float, float)  The Sun's lowest (first element) and highest
                                 (second element) elevation during the X hour
        @param  format:str?      The format for the returned strings, must take
                                 three integers, in order: hours, minutes, and
                                 seconds, or `None` if the total seconds shall be
                                 returned as integers
        @param  :(str?, str?, str|int, str?, str?, str|int)
                                 0: The beginning of the morning X hour
                                 1: The end of the morning X hour
                                 2: The duration of the morning X hour
                                 3: The beginning of the evening X hour
                                 4: The end of the evening X hour
                                 5: The duration of the evening X hour
        '''
        # TODO support not adjusting the timezone
        import solar_python as s, time
        tz = -(time.timezone, time.altzone)[time.localtime().tm_isdst]
        a_day = 60 * 60 * 24
        t = time.time()
        t += tz
        t -= t % a_day
        t -= tz
        t += days_offset * a_day
        start = s.epoch_to_julian_centuries(t)
        end = s.epoch_to_julian_centuries(t + a_day)
        t1 = s.future_elevation(self.lat, self.lon, elevations[0], start)
        t2 = s.future_elevation(self.lat, self.lon, elevations[1], start)
        t3 = s.past_elevation(self.lat, self.lon, elevations[1], end)
        t4 = s.past_elevation(self.lat, self.lon, elevations[0], end)
        (t1, t2, t3,
         t4) = tuple(x if x is not None and start <= x <= end else None
                     for x in (t1, t2, t3, t4))
        if t2 is None:
            t2 = t4
        if t3 is None:
            t3 = t1

        def dur(a, z):
            if a is None and z is None:
                e = s.solar_elevation(self.lat, self.lon, (start + end) / 2)
                if elevations[0] <= e <= elevations[1]:
                    return s.julian_centuries_to_epoch(
                        end) - s.julian_centuries_to_epoch(start)
                return 0
            elif a is None and z is not None:
                return s.julian_centuries_to_epoch(
                    z) - s.julian_centuries_to_epoch(start)
            elif a is not None and z is None:
                return s.julian_centuries_to_epoch(
                    end) - s.julian_centuries_to_epoch(a)
            else:
                return s.julian_centuries_to_epoch(
                    z) - s.julian_centuries_to_epoch(a)

        d12 = dur(t1, t2)
        d34 = dur(t3, t4)
        (t1, t2, t3, t4) = tuple(
            Solar.__jc_to_str(x) if x is not None else None
            for x in (t1, t2, t3, t4))

        def strise(s):
            if format is None:
                return int(s)
            m, s = s // 60, s % 60
            h, m = m // 60, m % 60
            return format % (h, m, s)

        return (t1, t2, strise(d12), t3, t4, strise(d34))