def parse_time(config, when, tomorrow=False): city = config.get('city', '') region = config.get('region', '') latitude = config.get('latitude', 0.0) longitude = config.get('longitude', 0.0) timezone = config.get('timezone', '') elevation = config.get('elevation', 0) if city: latitude = latitude or _a[city].latitude longitude = longitude or _a[city].longitude region = region or _a[city].region timezone = timezone or _a[city].timezone elevation = elevation or _a[city].elevation info = (city, region, latitude, longitude, timezone, elevation) location = astral.Location(info) date = datetime.datetime.now(tz=location.tz).replace(hour=0, minute=0, second=0, microsecond=0) result = getattr(location, when)(date=date) if result < datetime.datetime.now(tz=location.tz): result = getattr(location, when)(date=date + datetime.timedelta(days=1)) return result
def _parse_time(self, time): """Parse time string (HH:MM).""" if HAVE_ASTRAL: try: location = astral.Location(( 'Unknown', 'Unknown', float(os.environ['LATITUDE']), float(os.environ['LONGITUDE']), 'UTC', 0 )) if time == 'sunrise': return location.sunrise().time() elif time == 'sunset': return location.sunset().time() except (KeyError, ValueError): pass try: hour, minute = time.split(':') return datetime.time(hour=int(hour), minute=int(minute), second=0) except (ValueError, IndexError): return None
def filter_stationtype(self, stobs, dtobj): ''' check if it is day or night based on the solar angle construct location ''' lat = stobs[0] lon = stobs[1] elevation = 0 # placeholder loc = astral.Location(info=('name', 'region', lat, lon, 'UTC', elevation)) solar_elevation = loc.solar_elevation(dtobj) # set stime according to day/night based on solar angle if (solar_elevation > 0): stime = 'day' else: stime = 'night' if ((stime == 'day') and self.dstationtypes): try: mask = any([x.lower() in stobs[3].lower() for x in self.dstationtypes]) except AttributeError: mask = False elif ((stime == 'night') and self.nstationtypes): try: mask = any([x.lower() in stobs[3].lower() for x in self.nstationtypes]) except AttributeError: mask = False else: mask = True return mask
def _get_auto_time(self): """Get dawn, sunrise, noon, sunset, and dusk time. Returns: times (dict): dict with associated (datetime, level) """ tz = self.location["timezone"]["code"] lat = self.location["coordinate"]["latitude"] lon = self.location["coordinate"]["longitude"] ast_loc = astral.Location() ast_loc.timezone = tz ast_loc.lattitude = lat ast_loc.longitude = lon user_set_tz = timezone(tz).localize(datetime.now()).strftime("%Z") device_tz = time.tzname if user_set_tz in device_tz: sunrise = ast_loc.sun()["sunrise"] noon = ast_loc.sun()["noon"] sunset = ast_loc.sun()["sunset"] else: secs = int(self.location["timezone"]["offset"]) / -1000 sunrise = (arrow.get(ast_loc.sun()["sunrise"]).shift( seconds=secs).replace(tzinfo="UTC").datetime) noon = (arrow.get(ast_loc.sun()["noon"]).shift( seconds=secs).replace(tzinfo="UTC").datetime) sunset = (arrow.get(ast_loc.sun()["sunset"]).shift( seconds=secs).replace(tzinfo="UTC").datetime) return { "Sunrise": (sunrise, 20), # high "Noon": (noon, 30), # full "Sunset": (sunset, 5), # dim }
def getDayLight(date): city_name = 'SunriverOR' # create astral location object for sunriver Oregon l = astral.Location((city_name, 'USA', 43.8694, -121.4334, 'US/Pacific', 4164)) # name, region, lat, long, timezone, elevation l.sun(date, local=True) # Get Sun information for Location return l
def build_daylength(station_record): ''' ''' l = astral.Location() l.name, l.latitude, l.longitude = station_record data_list = [] dates = build_date_range() for date in dates: try: sun = l.sun(date) sunrise = sun['sunrise'] sunset = sun['sunset'] noon = sun['noon'] daylength = sunset - sunrise daylight_mins = daylength.seconds / 60 data = l.name + ',' + str(date) + ',' + str(daylight_mins) + \ ',' + str(noon) + '\n' data_list.append(data) except: print(l.name, str(date)) continue write_data(data_list)
def add_columns_time(self, df): '''Add columns about the time. Astral class uses average long=lat and elevation is 16m (wiki).''' if self.verbose: print 'Adding enumerations of resolutions to DataFile' location = astral.Location(('SF', 'America', df.Y.mean(), df.X.mean(), 'America/Los_Angeles', 16)) # Time in minutes is better for playing with df['Minutes'] = df.Dates.map(lambda d: time2minutes(d)) df['Month'] = df.Dates.map(lambda d: d.month) df['Year'] = df.Dates.map(lambda d: d.year) sunset = df.Dates.map(lambda d: time2minutes(location.sunset(d))) sunrise = df.Dates.map(lambda d: time2minutes(location.sunrise(d))) dusk = df.Dates.map(lambda d: time2minutes(location.dusk(d))) dawn = df.Dates.map(lambda d: time2minutes(location.dawn(d))) df['Moon'] = df.Dates.map(lambda d: location.moon_phase(d)) # 0 : Day, 1 : Dusk, 2 : Dark, 3 : Dawn df['Darkness'] = \ ((df.Minutes < dusk) & (df.Minutes > sunset)).astype(int) + \ ((df.Minutes < dawn) | (df.Minutes > dusk)).astype(int) * 2 + \ ((df.Minutes > dawn) & (df.Minutes < sunrise)).astype(int) * 3 df['Sunset'] = sunset df['Sunrise'] = sunrise df['Dusk'] = dusk df['Dawn'] = dawn return
def test_Dawn_NeverReachesDepression(): d = datetime.date(2016, 5, 29) with pytest.raises(astral.AstralError): l = astral.Location( ("Ghent", "Belgium", "51°3'N", "3°44'W", "Europe/Brussels")) l.solar_depression = 18 l.dawn(date=d, local=True)
def test_elevations(): june = datetime(2019, 6, 5, tzinfo=UTC) # location = astral.Location(("Perth", "Australia", -31.8584265, 115.769342, "UTC")) location = astral.Location(("Tisnes", "Norway", 69.6, 18.8, "UTC")) failed = [] for j in [astral.SUN_RISING, astral.SUN_SETTING]: for i in range(-90, 90): try: time = location.time_at_elevation(i, direction=j, date=june, local=False) except astral.AstralError: continue elevation = location.solar_elevation(time) # Sunrise not at right time. delta = abs(elevation - i) if delta > 0.05: failed.append((time.isoformat()[:19], j, i, elevation)) min_time = time min_delta = delta for d in range(-360, 360): t = time + timedelta(seconds=d) e = location.solar_elevation(t) d = abs(e - i) if d < min_delta: min_delta = d min_time = t failed.append( ("Closest", min_time.isoformat()[:19], min_delta)) # This fails. assert failed == []
def calc_solar_times(p_pyhouse_obj, p_date=datetime.date.today()): """ @param p_date: is the datetime.date that we want sunrise and sunset for """ l_a = astral.Location(info=(p_pyhouse_obj.House.Name, p_pyhouse_obj.House.Location.Region, p_pyhouse_obj.House.Location.Latitude, p_pyhouse_obj.House.Location.Longitude, p_pyhouse_obj.House.Location.TimeZoneName, p_pyhouse_obj.House.Location.Elevation)) l_a.solar_depression = "civil" if (isinstance(p_date, datetime.datetime)): l_date = p_date.date( ) # convert datetime.datetime to datetime.date else: l_date = p_date # print(PrettyFormatAny.form('{}'.format(l_a), 'AA')) l_sun = l_a.sun(date=l_date, local=True) l_ret = RiseSetData() l_ret.Dawn = l_sun['dawn'] l_ret.SunRise = l_sun['sunrise'] l_ret.Noon = l_sun['noon'] l_ret.SunSet = l_sun['sunset'] l_ret.Dusk = l_sun['dusk'] p_pyhouse_obj.House.Location.RiseSet = l_ret LOG.info('Sunrise/Sunset Calculation') return l_ret
def __init__(self, *args, location=None): """An object inheriting from dict, storing solar hours for a location. Parameters ---------- location : astral.Location or tuple, optional Allows you to provide a location, allowing an automatic getting of solar hours. Must be an 'astral.Location' object or a tuple like '(latitude, longitude, timezone_name, elevation)'. None default, meaning it relies only on manual settings. Although this is mostly intended for manual testing, you can also use one of the capital/city names supported by Astral, like "London" or "Copenhagen". Attributes ---------- location : astral.Location or None The location for which to get solar hours. To manually set solar hours for the present day, do the following: >>> solar_hours[datetime.date.today()] = {...} """ if isinstance(location, astral.Location): self.location = location elif isinstance(location, tuple): self.location = astral.Location(["Location", "Region", *location]) elif isinstance(location, str): self.location = astral.Astral()[location] else: self.location = None super().__init__(*args)
def get_sunrise_sunset(self, date=None): if self.data['sunrise_time'] is not None and self.data[ 'sunset_time'] is not None: if date is None: date = dt_now(self.data['timezone']) sunrise = date.replace( hour=int(self.data['sunrise_time'].strftime("%H")), minute=int(self.data['sunrise_time'].strftime("%M")), second=int(self.data['sunrise_time'].strftime("%S")), microsecond=int(self.data['sunrise_time'].strftime("%f"))) sunset = date.replace( hour=int(self.data['sunset_time'].strftime("%H")), minute=int(self.data['sunset_time'].strftime("%M")), second=int(self.data['sunset_time'].strftime("%S")), microsecond=int(self.data['sunset_time'].strftime("%f"))) solar_noon = sunrise + (sunset - sunrise) / 2 solar_midnight = sunset + ( (sunrise + timedelta(days=1)) - sunset) / 2 else: import astral location = astral.Location() location.name = 'name' location.region = 'region' location.latitude = self.data['latitude'] location.longitude = self.data['longitude'] location.elevation = self.data['elevation'] _LOGGER.debug("Astral location: " + str(location)) if self.data['sunrise_time'] is not None: if date is None: date = dt_now(self.data['timezone']) sunrise = date.replace( hour=int(self.data['sunrise_time'].strftime("%H")), minute=int(self.data['sunrise_time'].strftime("%M")), second=int(self.data['sunrise_time'].strftime("%S")), microsecond=int(self.data['sunrise_time'].strftime("%f"))) else: sunrise = location.sunrise(date) if self.data['sunset_time'] is not None: if date is None: date = dt_now(self.data['timezone']) sunset = date.replace( hour=int(self.data['sunset_time'].strftime("%H")), minute=int(self.data['sunset_time'].strftime("%M")), second=int(self.data['sunset_time'].strftime("%S")), microsecond=int(self.data['sunset_time'].strftime("%f"))) else: sunset = location.sunset(date) solar_noon = location.solar_noon(date) solar_midnight = location.solar_midnight(date) if self.data['sunrise_offset'] is not None: sunrise = sunrise + self.data['sunrise_offset'] if self.data['sunset_offset'] is not None: sunset = sunset + self.data['sunset_offset'] return { SUN_EVENT_SUNRISE: sunrise.astimezone(self.data['timezone']), SUN_EVENT_SUNSET: sunset.astimezone(self.data['timezone']), 'solar_noon': solar_noon.astimezone(self.data['timezone']), 'solar_midnight': solar_midnight.astimezone(self.data['timezone']) }
def lost_productivity_city_participant(time, participant, city): l = astral.Location() l.latitude = city[0] l.longitude = city[1] Ts = l.daylight(date=time, local=False) Tb = utc.localize(time + timedelta(seconds=32400)) Te = utc.localize(time + timedelta(seconds=61200)) if Ts[0] <= Tb and Ts[1] >= Te: Tl = 8.0 elif Ts[0] > Tb and Ts[1] >= Te: Tl = 8.0 - ((Ts[0] - Tb).seconds // 3600) elif Ts[0] <= Tb and Ts[1] < Te: Tl = 8.0 - ((Te - Ts[1]).seconds // 3600) elif Ts[0] > Tb and Ts[1] < Te: Tl = ((Ts[1] - Ts[0]).seconds // 3600) target_datetime = time.replace( tzinfo=timezone(tf.timezone_at(lat=city[0], lng=city[1]))) participant_datetime = time.replace(tzinfo=timezone( tf.timezone_at(lat=location_table[participant[0]]["lat"], lng=location_table[participant[0]]["lng"]))) tz_crossed = target_datetime.astimezone( utc) - participant_datetime.astimezone(utc) if participant_datetime.astimezone(utc) > target_datetime.astimezone(utc): dr1 = round(float(abs(tz_crossed.seconds // 3600) / 1.53)) dr2 = round( float((abs(tz_crossed.seconds // 3600) - 1.53) / ((92.0 + 5.75 * Tl) / 60.0))) C = ((0.07 * (92.0 + 5.75 * Tl)) / 60.0) + 1.0 psum = 0 for d in range(1, 4): if d == 1: psum += (1.0 / (1.10733333333**dr1)) * (1.10733333333**d) else: if d > dr2: d = dr2 psum += (1.0 / (C**dr2)) * (C**d) p = psum / 3 return (1.0 - p) * ((participant[1] / 250) * 3) elif participant_datetime.astimezone(utc) < target_datetime.astimezone( utc): dr1 = round(float(abs(tz_crossed.seconds // 3600) / 0.95)) dr2 = round( float((abs(tz_crossed.seconds // 3600) - 1.53) / ((57.0 + 5.75 * Tl) / 60.0))) C = ((0.07 * (57.0 + 5.75 * Tl)) / 60.0) + 1.0 psum = 0 for d in range(1, 4): if d == 1: psum += (1.0 / (1.0665**dr1)) * (1.0665**d) else: if d > dr2: d = dr2 psum += (1.0 / (C**dr2)) * (C**d) p = psum / 3 return (1.0 - p) * ((participant[1] / 250) * 3) else: return 0
def __init__(self, latitude, longitude, timezone, elevation): self._location = astral.Location(( 'name', 'region', latitude, longitude, timezone, elevation, ))
def get_sunrise_sunset(self, date=None): if self.data['sunrise_time'] is not None and self.data[ 'sunset_time'] is not None: if date is None: utcdate = dt_utcnow() date = as_local(utcdate) sunrise = date.replace( hour=int(self.data['sunrise_time'].strftime("%H")), minute=int(self.data['sunrise_time'].strftime("%M")), second=int(self.data['sunrise_time'].strftime("%S")), microsecond=int(self.data['sunrise_time'].strftime("%f"))) sunset = date.replace( hour=int(self.data['sunset_time'].strftime("%H")), minute=int(self.data['sunset_time'].strftime("%M")), second=int(self.data['sunset_time'].strftime("%S")), microsecond=int(self.data['sunset_time'].strftime("%f"))) solar_noon = sunrise + (sunset - sunrise) / 2 solar_midnight = sunset + ( (sunrise + timedelta(days=1)) - sunset) / 2 else: location = astral.Location() location.latitude = self.data['latitude'] location.longitude = self.data['longitude'] if self.data['sunrise_time'] is not None: if date is None: utcdate = dt_utcnow() date = as_local(utcdate) sunrise = date.replace( hour=int(self.data['sunrise_time'].strftime("%H")), minute=int(self.data['sunrise_time'].strftime("%M")), second=int(self.data['sunrise_time'].strftime("%S")), microsecond=int(self.data['sunrise_time'].strftime("%f"))) else: sunrise = location.sunrise(date) if self.data['sunset_time'] is not None: if date is None: utcdate = dt_utcnow() date = as_local(utcdate) sunset = date.replace( hour=int(self.data['sunset_time'].strftime("%H")), minute=int(self.data['sunset_time'].strftime("%M")), second=int(self.data['sunset_time'].strftime("%S")), microsecond=int(self.data['sunset_time'].strftime("%f"))) else: sunset = location.sunset(date) solar_noon = location.solar_noon(date) solar_midnight = location.solar_midnight(date) if self.data['sunrise_offset'] is not None: sunrise = sunrise + self.data['sunrise_offset'] if self.data['sunset_offset'] is not None: sunset = sunset + self.data['sunset_offset'] return { SUN_EVENT_SUNRISE: sunrise, SUN_EVENT_SUNSET: sunset, 'solar_noon': solar_noon, 'solar_midnight': solar_midnight }
def parse_solar_hours(self, coords=None, astral_location=None, hours=None, moment=None): """ Parses the solar hours, allowing them to be used and displayed. Solar hours can be parsed for any date. Parameters ---------- /!\ Only one of the three following arguments must be given. coords : tuple of two floats, optionnal A set of GPS coordinates (latitude, longitude). astral_location : astral.Astral.Location object, optionnal The astral location of the point. hours : tuple of tuples of integers, optionnal A set of hours of sunrise and sunset. Ex : ((h1, m1), (h2, m2)). moment : datetime.date object, optionnal A date for which to parse the solar hours. Required only when using 'astral_location' or 'coords'. Returns ------- datetime.time object The hour of sunrise. datetime.time object The hour of sunset. """ if not moment: moment = datetime.datetime.now(self.tz) sunrise_time = None sunset_time = None if hours is not None: sunrise_time = datetime.time(hours[0][0], hours[0][1]) sunset_time = datetime.time(hours[1][0], hours[1][1]) elif coords is not None: a_loc = astral.Location(("HOHCity", "HOHRegion", coords[0], coords[1], self.tz.zone, 100)) sunrise_time = a_loc.sun(moment, local=True)["sunrise"].time() sunset_time = a_loc.sun(moment, local=True)["sunset"].time() elif astral_location: sunrise_time = astral_location.sun(moment, local=True)["sunrise"].time() sunset_time = astral_location.sun(moment, local=True)["sunset"].time() else: raise ValueError( "One keyword argument (coords, astral location or " "solar hours) must be given.") sunrise_time = sunrise_time.replace(tzinfo=self.tz) sunset_time = sunset_time.replace(tzinfo=self.tz) for day in self._opening_periods + [self.PH, self.SH]: day._set_solar_hours(sunrise_time, sunset_time) self._solar_hours_parsed = True return sunrise_time, sunset_time
def is_summer(date): loc = astral.Location() loc.longitude = 0 loc.latitude = 60 north_rise = loc.sunrise(date=date) loc.latitude = 30 south_rise = loc.sunrise(date=date) return north_rise < south_rise
def __init__(self, latitude, longitude, **kwargs): location_tuple = (kwargs.get('name'), kwargs.get('region'), latitude, longitude, kwargs.get('timezone'), kwargs.get('elevation')) self.has_elevation = "elevation" in kwargs self.has_timezone = "timezone" in kwargs self.location = astral.Location(location_tuple)
def on_all_values_set(self): tz = tzlocal.get_localzone() tz_name = str(tz) log.debug(f'Local Timezone: {tz_name}') self.astral = _astral.Location() self.astral.name = 'HABApp' self.astral.latitude = self.latitude self.astral.longitude = self.longitude self.astral.elevation = self.elevation self.astral.timezone = tz_name
def sunshine(): location_nandamen = astral.Location( ('Hust', 'China', 30.514722, 114.420023, 'Asia/Shanghai', 0)) today = datetime.now() sunrise = location_nandamen.sunrise(date=today.date(), local=True) # datetime sunset = location_nandamen.sunset(date=today.date(), local=True) tomorrow = today + timedelta(days=1) sunrise_tomorrow = location_nandamen.sunrise(date=tomorrow.date(), local=True) sun = [sunrise, sunset, sunrise_tomorrow] return sun
def solar_times(local): """ Returns the sunrise and sunset times for the current local date """ local = local.replace(hour=12, minute=0) location = astral.Location( ("", "", config.aws_latitude, config.aws_longitude, str(config.aws_time_zone), config.aws_elevation)) solar = location.sun(date=local, local=False) return (solar["sunrise"].replace(tzinfo=None), solar["sunset"].replace(tzinfo=None))
def make_sky(self): self.sky = "" self.dt = pytz.timezone('America/New_York').localize(datetime.now()) self.loc = astral.Location(("New York","New York", 40.7527, -73.9772,"America/New_York","0")) if self.dt >= self.loc.sunrise(self.dt.date()) and self.dt <= self.loc.sunset(self.dt.date()): self.make_daysky() self.get_weather() else: self.make_nightsky() return self.sky
def _get_sun_events(self, date): if self._manual_sunrise is not None and self._manual_sunset is not None: sunrise = self._replace_time(date, "sunrise") sunset = self._replace_time(date, "sunset") solar_noon = sunrise + (sunset - sunrise) / 2 solar_midnight = sunset + ((sunrise + timedelta(days=1)) - sunset) / 2 else: try: location = astral.location.Location() except AttributeError: location = astral.Location() location.name = "name" location.region = "region" location.latitude = self._latitude location.longitude = self._longitude location.elevation = self._elevation if self._manual_sunrise is not None: sunrise = self._replace_time(date, "sunrise") else: sunrise = location.sunrise(date) if self._manual_sunset is not None: sunset = self._replace_time(date, "sunset") else: sunset = location.sunset(date) try: solar_noon = location.noon(date) except AttributeError: solar_noon = location.solar_noon(date) try: solar_midnight = location.midnight(date) except AttributeError: solar_midnight = location.solar_midnight(date) if self._sunrise_offset is not None: sunrise = sunrise + self._sunrise_offset if self._sunset_offset is not None: sunset = sunset + self._sunset_offset datetimes = { SUN_EVENT_SUNRISE: sunrise, SUN_EVENT_SUNSET: sunset, SUN_EVENT_NOON: solar_noon, SUN_EVENT_MIDNIGHT: solar_midnight, } return { k: dt.astimezone(dt_util.UTC).timestamp() for k, dt in datetimes.items() }
def init_sun(self): latitude = self.AD.latitude longitude = self.AD.longitude if -90 > latitude < 90: raise ValueError("Latitude needs to be -90 .. 90") if -180 > longitude < 180: raise ValueError("Longitude needs to be -180 .. 180") elevation = self.AD.elevation self.location = astral.Location( ('', '', latitude, longitude, self.AD.tz.zone, elevation))
def init_sun(self): latitude = self.AD.latitude longitude = self.AD.longitude if latitude < -90 or latitude > 90: raise ValueError("Latitude needs to be -90 .. 90") if longitude < -180 or longitude > 180: raise ValueError("Longitude needs to be -180 .. 180") elevation = self.AD.elevation self.location = astral.Location( ("", "", latitude, longitude, self.AD.tz.zone, elevation))
def __init__(self, mode: str, t: datetime.time, site: dict, tz: datetime.timezone): self.mode = mode self.tz = tz self.dt = datetime.timedelta(hours=t.hour, minutes=t.minute, seconds=t.second) if t > datetime.time( 12, 0, 0): # After noon, so treat as a negative time from 1 day self.dt -= datetime.timedelta(days=1) info = ('site', 'region', site['lat'], site['lon'], site['tz'], site['elev']) self.astral = astral.Location(info) self.astral.solar_depression = 'civil'
def GetSunriseTime(day): a = astral.Astral() a.solar_depression = 'civil' l = astral.Location() l.name = '9WGJ+42 Mountain View California' l.region = 'USA' l.latitude = 37.375313 l.longitude = -122.069938 l.timezone = 'US/Pacific' l.elevation = 42.865 # Finding the next sunrise. sun = l.sun(day, local=True) return sun['sunrise']
def __init__(self, name, region, lat, lon, tz, elevation, population): """ Town initialization :param name: town's name :param region: country, region, province... :param lat: latitude in degrees :param lon: longitude in degrees :param tz: time zone name :param elevation: elevation in metres :param population: population """ self._location = astral.Location((name, region, lat, lon, tz, elevation)) self.population = population self._date = datetime.datetime.today() self._sun = self._location.sun(local=False)
def sunProprieties(self): sunDet = [] loc = astral.Location(('altcv', 'cv', self.__location[0], self.__location[1], 'Europe/Bucharest', 510)) for event, time in loc.sun(date.today()).items(): altitude = get_altitude(self.__location[0], self.__location[1], time) azimuth = get_azimuth(self.__location[0], self.__location[1], time) sunDet.append([event, altitude, azimuth, time]) sortedSunDet = sorted(sunDet, key=lambda x: datetime.datetime.strptime( str(x[3]), '%Y-%m-%d %H:%M:%S+02:00'), reverse=False) self.__sunDet = sortedSunDet
def init_sun(): latitude = conf.latitude longitude = conf.longitude if -90 > latitude < 90: raise ValueError("Latitude needs to be -90 .. 90") if -180 > longitude < 180: raise ValueError("Longitude needs to be -180 .. 180") elevation = conf.elevation conf.tz = pytz.timezone(conf.time_zone) conf.location = astral.Location(('', '', latitude, longitude, conf.tz.zone, elevation))