def find_new_moon(d): # used in doublepage # find previous & next new moon global PreviousNewMoon global NextNewMoon PreviousNewMoon = None NextNewMoon = None # note: the python datetimes above are timezone 'aware' (not 'naive') # search from 30 days earlier than noon... till noon on this day d0 = d - datetime.timedelta(days=30) t0 = ts.utc(d0.year, d0.month, d0.day, 12, 0, 0) t1 = ts.utc(d.year, d.month, d.day, 12, 0, 0) t, y = almanac.find_discrete(t0, t1, almanac.moon_phases(eph)) for i in range(len(t)): if y[i] == 0: # 0=New Moon, 1=First Quarter, 2=Full Moon, 3=Last Quarter PreviousNewMoon = t[i].utc_datetime() if PreviousNewMoon != None: # synodic month = about 29.53 days t2 = ts.utc(PreviousNewMoon + datetime.timedelta(days=28)) t3 = ts.utc(PreviousNewMoon + datetime.timedelta(days=30)) t, y = almanac.find_discrete(t2, t3, almanac.moon_phases(eph)) for i in range(len(t)): if y[i] == 0: # 0 = New Moon NextNewMoon = t[i].utc_datetime() return
def seek_moonrise(t9, t9noon, t0, t1, t1noon, t2, lats, ts, earth, moon): # for the specified date & latitude ... # return -1 if there is NO MOONRISE yesterday # return +1 if there is NO MOONRISE tomorrow # return 0 if there was a moonrise yesterday and will be a moonrise tomorrow # note: this is called when there is only a moonset on the specified date+latitude time00 = 0.0 # 00000 Hseeks = 1 m_rise_t = 0 # normal case: assume moonrise yesterday & tomorrow locn = Topos(lats, "0.0 E") horizon = getHorizon(t1noon, earth, moon) start00 = time() # 00000 moonrise, y = almanac.find_discrete(t1, t2, moonday(earth, moon, locn, horizon)) time00 += time() - start00 # 00000 rise, sett, ris2, set2, fs = rise_set(moonrise, y, lats, ts) if rise == '--:--': m_rise_t = +1 # if no moonrise detected - it is after tomorrow else: Hseeks += 1 locn = Topos(lats, "0.0 E") horizon = getHorizon(t9noon, earth, moon) start00 = time() # 00000 moonrise, y = almanac.find_discrete( t9, t0, moonday(earth, moon, locn, horizon)) time00 += time() - start00 # 00000 rise, sett, ris2, set2, fs = rise_set(moonrise, y, lats, ts) if rise == '--:--': m_rise_t = -1 # if no moonrise detected - it is before yesterday return m_rise_t, time00, Hseeks
def test_solar_terms(): ts = api.load.timescale() e = api.load('de421.bsp') # https://en.wikipedia.org/wiki/Lichun t0 = ts.utc(2019, 2, 2) t1 = ts.utc(2019, 2, 5) t, y = almanac.find_discrete(t0, t1, skyfield.almanac_east_asia.solar_terms(e)) t.tt += half_minute strings = t.utc_strftime('%Y-%m-%d %H:%M') print(strings) assert strings == ['2019-02-04 03:14'] assert (y == (21)).all() # https://en.wikipedia.org/wiki/Lixia t0 = ts.utc(2019, 5, 4) t1 = ts.utc(2019, 5, 6) t, y = almanac.find_discrete(t0, t1, skyfield.almanac_east_asia.solar_terms(e)) t.tt += half_minute strings = t.utc_strftime('%Y-%m-%d %H:%M') print(strings) assert strings == ['2019-05-05 19:03'] assert (y == (3)).all() # https://en.wikipedia.org/wiki/Liqiu t0 = ts.utc(2019, 8, 6) t1 = ts.utc(2019, 8, 8) t, y = almanac.find_discrete(t0, t1, skyfield.almanac_east_asia.solar_terms(e)) t.tt += half_minute strings = t.utc_strftime('%Y-%m-%d %H:%M') print(strings) assert strings == ['2019-08-07 19:13'] assert (y == (9)).all() # https://en.wikipedia.org/wiki/Lidong t0 = ts.utc(2019, 11, 7) t1 = ts.utc(2019, 11, 9) t, y = almanac.find_discrete(t0, t1, skyfield.almanac_east_asia.solar_terms(e)) t.tt += half_minute strings = t.utc_strftime('%Y-%m-%d %H:%M') print(strings) assert strings == ['2019-11-07 17:24'] assert (y == (15)).all()
def session_plan_set_moonless_astro_twilight(session_plan_id): session_plan = SessionPlan.query.filter_by(id=session_plan_id).first() _check_session_plan(session_plan) t1, t2 = _get_twighligh_component(session_plan, 1) if t1 and t2: ts = load.timescale() _, latitude, longitude, _ = _get_location_info_from_session_plan( session_plan) observer = wgs84.latlon(latitude, longitude) tz_info = _get_session_plan_tzinfo(session_plan) ldate_start = tz_info.localize(session_plan.for_date + timedelta(hours=0)) ldate_end = tz_info.localize(session_plan.for_date + timedelta(hours=48)) start_t = ts.from_datetime(ldate_start) end_t = ts.from_datetime(ldate_end) eph = load('de421.bsp') f = almanac.risings_and_settings(eph, eph['Moon'], observer) t, y = almanac.find_discrete(start_t, end_t, f) if t1 and t2: rise_sets = [] moon_rise, moon_set = None, None for i in range(len(y)): if y[i]: moon_rise = t[i].astimezone(tz_info) else: moon_set = t[i].astimezone(tz_info) rise_sets.append((moon_rise, moon_set)) moon_rise, moon_set = None, None if moon_rise or moon_set: rise_sets.append((moon_rise, moon_set)) for moon_rise, moon_set in rise_sets: if not moon_rise: moon_rise = ldate_start if not moon_set: moon_set = ldate_end if moon_set < t1 or moon_rise > t2: continue if moon_rise < t1 and moon_set > t2: t1, t2 = None, None break if moon_rise > t1: t2 = moon_rise else: t1 = moon_set if t1 and t2 and t1 > t2: t1, t2 = None, None if t1 and t2: session['planner_time_from'] = t1.strftime(SCHEDULE_TIME_FORMAT) session['planner_time_to'] = t2.strftime(SCHEDULE_TIME_FORMAT) session['is_backr'] = True return redirect( url_for('main_sessionplan.session_plan_schedule', session_plan_id=session_plan.id))
def _get_twighligh_component(session_plan, comp): ts = load.timescale() _, latitude, longitude, _ = _get_location_info_from_session_plan( session_plan) observer = wgs84.latlon(latitude, longitude) tz_info = _get_session_plan_tzinfo(session_plan) ldate1 = tz_info.localize(session_plan.for_date + timedelta(hours=12)) ldate2 = tz_info.localize(session_plan.for_date + timedelta(hours=36)) t1 = ts.from_datetime(ldate1) t2 = ts.from_datetime(ldate2) eph = load('de421.bsp') t, y = almanac.find_discrete(t1, t2, almanac.dark_twilight_day(eph, observer)) index1 = None index2 = None for i in range(len(y)): if y[i] == comp: if index1 is None: index1 = i + 1 elif index2 is None: index2 = i if index1 is None or index2 is None: return None, None return t[index1].astimezone(tz_info), t[index2].astimezone(tz_info)
def DayNightProg(time_dt, time_ordinal, ob_cond): period_start = TIMESCALE.utc(time_dt - timedelta(days=1)) period_end = TIMESCALE.utc(time_dt + timedelta(days=1)) ST, SI = almanac.find_discrete(period_start, period_end, ob_cond) ST_ORD = ST.toordinal().tolist() SI_ARR = SI.tolist() while len(ST_ORD) > 1: if ST_ORD[1] < time_ordinal: SI_ARR.pop(0) ST_ORD.pop(0) else: break if len(ST_ORD) in [0, 1]: # If we are near polar regions, we may have [last_raise_set] or [] or [next_raise_set] # TODO: Support polar regions by expanding time period until we find the last/next event pass if len(ST_ORD) < 3: _logger.warning( "Unexpected day-night lookup - expect 3+ entries, got %d", len(ST_ORD)) return [] # Normally, we have [last_raise_set, next_set_raise, ...] day_night_start = ST_ORD[0] day_night_end = ST_ORD[1] day_night_length = (day_night_end - day_night_start) * HOURS_IN_DAY day_night_elapsed = (time_ordinal - day_night_start) * HOURS_IN_DAY day_night_remain = (day_night_end - time_ordinal) * HOURS_IN_DAY day_night_endts = day_night_end * SECS_IN_DAY - UNIX_TS_OFFSET return (round(day_night_elapsed, 3), round(day_night_elapsed / day_night_length * 100, 2), round(day_night_endts, 2), round(day_night_remain, 3))
def get_sunrise_sunset(latitude, longitude, date, timezone): """ :type timezone: datetime.tzinfo :type date: datetime.date :type latitude: float :type longitude: float :return Tuple of datetime (sunrise, sunset), or None instead of a datetime if it doesn't occur that day. """ # TODO: 4 AM is used in the documentation, but does it work everywhere? # https://rhodesmill.org/skyfield/almanac.html#sunrise-and-sunset t0 = ts.utc(date.year, date.month, date.day, 4) t1 = ts.utc(date.year, date.month, date.day + 1, 4) location = api.Topos(latitude_degrees=latitude, longitude=longitude) # The result t will be an array of times, and y will be True if the sun # rises at the corresponding time and False if it sets. times, are_sunrise = almanac.find_discrete( t0, t1, almanac.sunrise_sunset(e, location)) sunrise = None sunset = None for time, is_sunrise in zip(times, are_sunrise): if is_sunrise: # Not expecting multiple sunrises per day. assert sunrise is None sunrise = time.astimezone(timezone) else: # Not expecting multiple sunsets per day. assert sunset is None sunset = time.astimezone(timezone) return sunrise, sunset
def MoonPhaseProg(time_dt, time_ordinal): QUARTER = MOON_SYNODIC_PERIOD // 4 period_start = TIMESCALE.utc(time_dt - timedelta(days=QUARTER + 1)) period_end = TIMESCALE.utc(time_dt + timedelta(days=QUARTER + 1)) PT, PI = almanac.find_discrete(period_start, period_end, MOON_PHASE_EVENTS) PT_ORD = PT.toordinal().tolist() PI_ARR = PI.tolist() if len(PT_ORD) == 3: if time_ordinal >= PT_ORD[1]: PI_ARR.pop(0) PT_ORD.pop(0) if len(PT_ORD) != 2: _logger.warning( "Unexpected moon-phase lookup - expect 2 entries, got %d", len(PT_ORD)) return [] phase_start = PT_ORD[0] phase_end = PT_ORD[1] phase_length = phase_end - phase_start phase_elapsed = time_ordinal - phase_start phase_remain = phase_end - time_ordinal phase_endts = phase_end * SECS_IN_DAY - UNIX_TS_OFFSET return (round(phase_elapsed, 3), round(phase_elapsed / phase_length * 100, 2), round(phase_endts, 2), round(phase_remain, 3), almanac.MOON_PHASES[PI_ARR[1]])
def __init__(self, t_0, t_1, sat, topos, earth, sun, visible=True): self.sat_minimum_observable_altitude = 10.0 self.sat_pass_rough_period = 0.0042 # average pass duration of 6 minutes time, _ = almanac.find_discrete( t_0, t_1, self._satellite_pass(sat, topos, earth, sun, visible)) difference = sat - topos self.passes = [] self.pass_types = ['eclipsed', 'visible', 'daylight'] timezone_str = tzwhere.tzwhere().tzNameAt(topos.latitude.degrees, topos.longitude.degrees) for i in range(1, len(time), 2): start_t, end_t = time[i - 1], time[ i] # TODO: check that y[i-1] and not y[i] culm_t, _ = extremum.find_maximum( start_t, end_t, lambda t: difference.at(t).altaz('standard')[0].degrees) _, mag = extremum.find_minimum( start_t, end_t, lambda t: satpred_utilities.apparent_magnitude( sat, topos, earth, sun, t)) if satpred_utilities.civil_twilight( topos, earth, sun, start_t) and satpred_utilities.civil_twilight( topos, earth, sun, end_t): if satpred_utilities.umbral_eclipse( sat, earth, sun, start_t) and satpred_utilities.umbral_eclipse( sat, earth, sun, end_t): pass_type = self.pass_types[0] else: pass_type = self.pass_types[1] else: pass_type = self.pass_types[2] self.passes.append( SatellitePass(sat, topos, timezone_str, start_t, culm_t, end_t, pass_type, np.round(mag, 1)))
def getmoonstate(dt, lat, hemisph, ts, earth, moon): # populate the moon state (visible or not) for the specified date & latitude # note: the first parameter 'dt' is already a datetime 30 seconds before midnight # note: getmoonstate is called when there is neither a moonrise nor a moonset on 'dt' time00 = 0.0 # 00000 Hseeks = 0 lats = '{:3.1f} {}'.format(abs(lat), hemisph) locn = Topos(lats, '0.0 E') t0 = ts.ut1(dt.year, dt.month, dt.day, dt.hour, dt.minute, dt.second) horizon = 0.8333 # search for the next moonrise or moonset (returned in moonrise[0] and y[0]) mstate = None while mstate == None: Hseeks += 1 t0 = ts.ut1(dt.year, dt.month, dt.day, dt.hour, dt.minute, dt.second) dt += timedelta(days=1) t9 = ts.ut1(dt.year, dt.month, dt.day, dt.hour, dt.minute, dt.second) start00 = time() # 00000 moonrise, y = almanac.find_discrete( t0, t9, moonday(earth, moon, locn, horizon)) time00 += time() - start00 # 00000 if len(moonrise) > 0: if y[0]: mstate = False else: mstate = True return mstate, time00, Hseeks
def MoonRiseSetProg(time_dt, time_ordinal, ob_cond): period_start = TIMESCALE.utc(time_dt - timedelta(days=1, hours=1)) period_end = TIMESCALE.utc(time_dt + timedelta(days=1, hours=1)) ST, SI = almanac.find_discrete(period_start, period_end, ob_cond) ST_ORD = ST.toordinal().tolist() SI_ARR = SI.tolist() while len(ST_ORD) > 1: if ST_ORD[1] < time_ordinal: SI_ARR.pop(0) ST_ORD.pop(0) else: break if len(ST_ORD) < 3: _logger.warning( "Unexpected moon-night lookup - expect 3+ entries, got %d", len(ST_ORD)) return [] # We should have [last_raise_set, next_set_raise, ...] moon_night_start = ST_ORD[0] moon_night_end = ST_ORD[1] moon_night_length = (moon_night_end - moon_night_start) * HOURS_IN_DAY moon_night_elapsed = (time_ordinal - moon_night_start) * HOURS_IN_DAY moon_night_remain = (moon_night_end - time_ordinal) * HOURS_IN_DAY moon_night_endts = moon_night_end * SECS_IN_DAY - UNIX_TS_OFFSET return (round(moon_night_elapsed, 3), round(moon_night_elapsed / moon_night_length * 100, 2), round(moon_night_endts, 2), round(moon_night_remain, 3))
def planet_timestamp(name, action, ts, planets, city, eph, names): print(name, action) logging.info('%s %s' % (name, action)) # this function returns the next rise or set time from now t0 = datetime.datetime.now(timezone.utc) print('t0:', t0) logging.info('t0: %s' % t0) # make hours 24+1 because during spring, next sunset will be more than 24h later than current t1 = t0 + datetime.timedelta(hours=25) print('t1:', t1) logging.info('t1: %s' % t1) # t0 = t0.replace(tzinfo=utc) t0 = ts.utc(t0) # t1 = t1.replace(tzinfo=utc) t1 = ts.utc(t1) f = risings_and_settings(eph, planets[names.index(name)], city) #This returns a function taking a Time argument returning True if the body’s altazimuth altitude angle plus radius_degrees is greater than horizon_degrees, else False t, values = find_discrete(t0, t1, f) #Find the times at which a discrete function of time changes value. in this case, find the set (0) and rise (1) times, t. if action == 'rise': #values array is 1 for the rise. we look up the index of the rise in the time array, t, to get the time of the rise event. timestamp = t[numpy.where(values == 1)].utc_datetime() print('timestamp:', timestamp) logging.info('timestamp: %s' % timestamp) else: #values array is 0 for the set. we look up the index of the set in the time array, t, to get the time of the set event. timestamp = t[numpy.where(values == 0)].utc_datetime() print('timestamp:', timestamp) logging.info('timestamp: %s' % timestamp) timestamp = timestamp[0].timestamp() return int(timestamp)
def SeasonProg(time_dt, time_ordinal): QUARTER = DAYS_IN_YEAR / 4 period_start = TIMESCALE.utc(time_dt - timedelta(days=QUARTER + 1)) period_end = TIMESCALE.utc(time_dt + timedelta(days=QUARTER + 1)) ST, SI = almanac.find_discrete(period_start, period_end, SEASONS) ST_ORD = ST.toordinal().tolist() SI_ARR = SI.tolist() if len(ST_ORD) == 3: if time_ordinal >= ST_ORD[1]: SI_ARR.pop(0) ST_ORD.pop(0) if len(ST_ORD) != 2: _logger.warning("Unexpected seasons lookup - expect 2 entries, got %d", len(ST_ORD)) return [] season_start = ST_ORD[0] season_end = ST_ORD[1] season_length = season_end - season_start season_elapsed = time_ordinal - season_start season_remain = season_end - time_ordinal season_endts = season_end * SECS_IN_DAY - UNIX_TS_OFFSET return (round(season_elapsed, 5), round(season_elapsed / season_length * 100, 2), round(season_endts, 2), round(season_remain, 5), almanac.SEASON_EVENTS[SI_ARR[1]])
def _compute_loc_sunset(input_str): geolocator = Nominatim(user_agent='sunset_app', timeout=3) geoloc = geolocator.geocode(input_str) lat, lon = geoloc.latitude, geoloc.longitude loc = api.Topos('{0} N'.format(lat), '{0} E'.format(lon)) t0 = ts.utc(2020, 7, 1) t1 = ts.utc(2021, 7, 1) t, y = almanac.find_discrete(t0, t1, almanac.sunrise_sunset(e, loc)) df = pd.DataFrame({'datetime': t.utc_iso(), 'sun_down': y}) df['datetime'] = pd.to_datetime(df['datetime']) tz = GeoNames(username='******').reverse_timezone( (geoloc.latitude, geoloc.longitude)) try: df['datetime'] = df['datetime'].dt.tz_localize('utc').dt.tz_convert( tz.pytz_timezone) except TypeError: df['datetime'] = df['datetime'].dt.tz_convert(tz.pytz_timezone) df['date'] = df['datetime'].dt.date df['time'] = df['datetime'].dt.time df['hour'] = (df['time'].astype(str).str.split( ':', expand=True).astype(int).apply( lambda row: row[0] + row[1] / 60. + row[2] / 3600., axis=1)) df['hour_24'] = 240 df['daylight'] = np.abs(df['hour'].diff().shift(-1)) return df, geoloc
def get_sun_data(lat, lon, flight_date): sky_fmt = "%Y-%m-%dT%H:%M:%SZ" ts = api.load.timescale() e = api.load('de421.bsp') sunrise = None sunset = None bluffton = api.Topos(lat, lon) # first get sunrise and sunset times t, y = almanac.find_discrete( ts.utc(flight_date.date()), ts.utc(flight_date.date() + datetime.timedelta(days=1)), almanac.sunrise_sunset(e, bluffton)) for ti, yi in zip(t, y): if yi: sunrise = ti.utc_iso() else: sunset = ti.utc_iso() return (datetime.datetime.strptime( sunrise, sky_fmt).replace(tzinfo=datetime.timezone.utc) - datetime.timedelta(minutes=30), datetime.datetime.strptime( sunset, sky_fmt).replace(tzinfo=datetime.timezone.utc) + datetime.timedelta(minutes=30))
def find_twilight(location, t_timescale_nights_local_list): planets = load("de421.bsp") topo = Topos(location["latitude"], location["longitude"], elevation_m=location["elevation"]) result = [] for t_night in t_timescale_nights_local_list: t_start = t_night[0] t_end = t_night[-1] f = almanac.dark_twilight_day(planets, topo) ts, twilight_types = almanac.find_discrete(t_start, t_end, f) t_night_start = None t_night_end = None for t, twilight_type in zip(ts, twilight_types): #print(twilight_type, t, t.utc_iso(), ' Start of', almanac.TWILIGHTS[twilight_type]) # exclude all twilight, just full dark night # relies on start of night, twilight, day, etc being in order if twilight_type == 0: # start of night t_night_start = t elif not ( t_night_start is None ) and twilight_type == 1: # start of astro twilight after start of night t_night_end = t break result.append((t_night_start, t_night_end)) return result
def equinox_solstice(): lookup_table = [ 'VE', 'SS', 'AE', 'WS', ] start = datetime.today().astimezone().replace(month=1, day=1, hour=0, minute=0, second=0, microsecond=0) end = datetime.today().astimezone().replace(month=12, day=31, hour=0, minute=0, second=0, microsecond=0) today = datetime.today().astimezone() t0 = ts.utc(start) t1 = ts.utc(end) times, events = almanac.find_discrete(t0, t1, almanac.seasons(ephem)) tz = datetime.now().astimezone().tzinfo for yi, ti in zip(events, times): ti = ti.astimezone(tz) if (today.month, today.day) == (ti.month, ti.day): return lookup_table[yi] + ti.strftime('%H%M') return ''
def testSunrise(self): timisoaraLoc = api.Topos('45.4758 N', '21.1738 E') t0 = ts.utc(2018, 9, 12, 4) t1 = ts.utc(2018, 9, 13, 4) t, y = almanac.find_discrete(t0, t1, almanac.sunrise_sunset(eph, timisoaraLoc)) print("****************") print(t.utc_iso()) print(y)
def _compute_sun_rise_sun_set(self, start: Time, stop: Time): times, rise_set = find_discrete( start, stop, sunrise_sunset(self.planets, self.topo)) for t in times[rise_set]: cur_date = t.utc_datetime().date() if cur_date not in self.sun_rise_cache.keys(): self.sun_rise_cache[cur_date] = t return times[rise_set], times[~rise_set]
def moon_phase_list(t0, t1): t, p = almanac.find_discrete(t0, t1, almanac.moon_phases(e)) l = [] for i in range(0, len(t)): l.append({'t': t[i].utc_datetime(), 'p': p[i]}) return l
def test_close_start_and_end(): ts = api.load.timescale() t0 = ts.utc(2018, 9, 23, 1) t1 = ts.utc(2018, 9, 23, 2) e = api.load('de421.bsp') t, y = almanac.find_discrete(t0, t1, almanac.seasons(e)) strings = t.utc_strftime('%Y-%m-%d %H:%M') assert strings == ['2018-09-23 01:54']
def test_close_start_and_end(): ts = api.load.timescale() t0 = ts.utc(2018, 9, 23, 1) t1 = ts.utc(2018, 9, 23, 2) e = api.load('de421.bsp') t, y = almanac.find_discrete(t0, t1, almanac.seasons(e)) t.tt += half_minute strings = t.utc_strftime('%Y-%m-%d %H:%M') assert strings == ['2018-09-23 01:54']
def find_phases(endyear, startyear, zone): d0 = datetime(startyear, 1, 1) d1 = datetime(endyear + 1, 1, 1) # localize to eastern timezone e0 = zone.localize(d0) e1 = zone.localize(d1) t, y = almanac.find_discrete(ts.from_datetime(e0), ts.from_datetime(e1), almanac.moon_phases(eph)) return t, y
def next_full_moon(given_date): start = ts.utc(given_date) finish = ts.utc(given_date + timedelta(30)) times, phases = almanac.find_discrete(start, finish, almanac.moon_phases(e)) for t, p in zip(times, phases): if p == 2: return t.utc_datetime() else: raise ExceptionalError("That's no moon.") #there should always be a full moon over the span of 30 days
def risings_and_settings(data: AstroData, body: str, t0: Time, t1: Time) -> List[RisingOrSetting]: f = almanac.risings_and_settings(data.ephemeris, data.get_body(body), data.babylon_topos) t, y = almanac.find_discrete(t0, t1, f) out = [] for ti, yi in zip(t, y): type = RiseSetType.RISE if yi else RiseSetType.SET out.append(RisingOrSetting(ti, type)) return out
def test_moon_phases(): ts = api.load.timescale() t0 = ts.utc(2018, 9, 11) t1 = ts.utc(2018, 9, 30) e = api.load('de421.bsp') t, y = almanac.find_discrete(t0, t1, almanac.moon_phases(e)) strings = t.utc_strftime('%Y-%m-%d %H:%M') assert strings == ['2018-09-16 23:15', '2018-09-25 02:52'] assert (y == (1, 2)).all()
def test_moon_phases(): ts = api.load.timescale() t0 = ts.utc(2018, 9, 11) t1 = ts.utc(2018, 9, 30) e = api.load('de421.bsp') t, y = almanac.find_discrete(t0, t1, almanac.moon_phases(e)) t.tt += half_minute strings = t.utc_strftime('%Y-%m-%d %H:%M') assert strings == ['2018-09-16 23:15', '2018-09-25 02:52'] assert (y == (1, 2)).all()
def test_oppositions_conjunctions_of_moon(): ts = api.load.timescale() t0 = ts.utc(2019, 1, 1) t1 = ts.utc(2019, 2, 1) e = api.load('de421.bsp') f = almanac.oppositions_conjunctions(e, e['moon']) t, y = almanac.find_discrete(t0, t1, f) strings = t.utc_strftime('%Y-%m-%d %H:%M') assert strings == ['2019-01-06 01:28', '2019-01-21 05:16'] assert (y == (1, 0)).all()
def test_sunrise_sunset(): ts = api.load.timescale() t0 = ts.utc(2018, 9, 12, 4) t1 = ts.utc(2018, 9, 13, 4) e = api.load('de421.bsp') bluffton = api.Topos('40.8939 N', '83.8917 W') t, y = almanac.find_discrete(t0, t1, almanac.sunrise_sunset(e, bluffton)) strings = t.utc_strftime('%Y-%m-%d %H:%M') assert strings == ['2018-09-12 11:13', '2018-09-12 23:50'] assert (y == (1, 0)).all()
def test_oppositions_conjunctions(): ts = api.load.timescale() t0 = ts.utc(2019, 1, 1) t1 = ts.utc(2021, 1, 1) e = api.load('de421.bsp') f = almanac.oppositions_conjunctions(e, e['mars']) t, y = almanac.find_discrete(t0, t1, f) strings = t.utc_strftime('%Y-%m-%d %H:%M') assert strings == ['2019-09-02 10:42', '2020-10-13 23:26'] assert (y == (0, 1)).all()
def test_seasons(): ts = api.load.timescale() t0 = ts.utc(2018, 9, 20) t1 = ts.utc(2018, 12, 31) e = api.load('de421.bsp') t, y = almanac.find_discrete(t0, t1, almanac.seasons(e)) strings = t.utc_strftime('%Y-%m-%d %H:%M') print(strings) assert strings == ['2018-09-23 01:54', '2018-12-21 22:23'] assert (y == (2, 3)).all()
def march_equinox(year): # must be 15 day range minimum, apparently? t0 = ts.utc(year, 3, 13) t1 = ts.utc(year, 3, 28) tstamp, phase = almanac.find_discrete(t0, t1, almanac.seasons(e)) for phi, ti in zip(phase, tstamp): if phi == 0: return ti.utc_datetime() else: raise ExceptionalError("Is this Earth?")
def test_seasons(): ts = api.load.timescale() t0 = ts.utc(2018, 9, 20) t1 = ts.utc(2018, 12, 31) e = api.load('de421.bsp') t, y = almanac.find_discrete(t0, t1, almanac.seasons(e)) t.tt += half_minute strings = t.utc_strftime('%Y-%m-%d %H:%M') print(strings) assert strings == ['2018-09-23 01:54', '2018-12-21 22:23'] assert (y == (2, 3)).all()
def test_sunrise_sunset(): ts = api.load.timescale() t0 = ts.utc(2018, 9, 12, 4) t1 = ts.utc(2018, 9, 13, 4) e = api.load('de421.bsp') bluffton = api.Topos('40.8939 N', '83.8917 W') t, y = almanac.find_discrete(t0, t1, almanac.sunrise_sunset(e, bluffton)) t.tt += half_minute strings = t.utc_strftime('%Y-%m-%d %H:%M') assert strings == ['2018-09-12 11:13', '2018-09-12 23:50'] assert (y == (1, 0)).all()
def getSeason( n, season ): '''Returns the date of the season for year n.''' from skyfield import almanac loadAstronomyData( ) if not g.astroDataAvailable: raise ValueError( "Astronomy functions are unavailable." ) t, y = almanac.find_discrete( g.timescale.utc( real_int( n ), 1, 1 ), g.timescale.utc( n, 12, 31 ), almanac.seasons( g.ephemeris ) ) result = RPNDateTime.parseDateTime( t[ season ].utc_datetime( ) ) return result.getLocalTime( )
def sun_time(which_one="sunrise"): from skyfield import api, almanac import dateutil.tz load = api.Loader("~/.skyfield", verbose=False) location = config["location"] ts = load.timescale() e = load('de421.bsp') here = api.Topos(location["latitude"], location["longitude"]) now = datetime.datetime.now() today = now.date() local = dateutil.tz.gettz() midnight = datetime.datetime.combine(today, datetime.time(), local) next_midnight = midnight + datetime.timedelta(1) begin = ts.utc(midnight) end = ts.utc(next_midnight) t, _ = almanac.find_discrete(begin, end, almanac.sunrise_sunset(e, here)) idx = 0 if which_one == "sunrise" else 1 return t[idx].astimezone(local)