Пример #1
0
def parse_datetime(parse_str: str,
                   timezone: pytz.timezone = pytz.utc) -> datetime.datetime:
    if parse_str.lower() == 'now':
        return pytz.utc.localize(datetime.datetime.utcnow())

    try:
        default_time = (pytz.utc.localize(datetime.datetime.utcnow()).astimezone(timezone))\
            .replace(tzinfo=None, hour=0, minute=0, second=0, microsecond=0)
        dateutil_parse = parser.parse(parse_str,
                                      default=default_time,
                                      fuzzy=True,
                                      dayfirst=False,
                                      yearfirst=False)
        if 'tomorrow' in parse_str:
            return timezone.localize(dateutil_parse +
                                     datetime.timedelta(days=1)).astimezone(
                                         pytz.utc)
        else:
            return timezone.localize(dateutil_parse).astimezone(pytz.utc)
    except ValueError:
        raise necrobot.exception.ParseException(
            'Couldn\'t parse {0} as a time.'.format(parse_str))
    except OverflowError:
        raise necrobot.exception.ParseException(
            'That date is really just too big. (Like, so big it doesn\'t fit in an int value on this system.) '
            'Congratulations! Please try again.')
Пример #2
0
    def _get_timedelta_from_timezones(tz1: timezone, tz2: timezone) -> float:
        """Method to get timedelta in hours (float) from two timezones

        :param tz1:
        :param tz2:
        :return:
        """
        dt_1970 = datetime.datetime(1970, 1, 1)

        dt_1970_tz1 = tz1.localize(dt_1970)
        dt_1970_tz2 = tz2.localize(dt_1970).astimezone(tz1)

        dt_diff = dt_1970_tz1 - dt_1970_tz2

        return dt_diff.days * 24 + dt_diff.seconds / 3600
Пример #3
0
    def _html_to_ics(self, markup: str, timezone: pytz.timezone) -> Calendar:
        soup = BeautifulSoup(markup, "lxml")
        monthly_prayers = soup.find("div", {"id": "tab-1"}).table
        headers = [i.text for i in monthly_prayers.thead.tr.find_all('th')][1:]
        data = [[i.text for i in tr.find_all('td')]
                for tr in monthly_prayers.tbody.find_all('tr')]
        calendar = Calendar(creator=app.config['APPLICATION_ID'])
        for day_record in data:
            events_starts = [
                timezone.localize(
                    datetime.strptime(day_record[0] + ' ' + _time,
                                      '%d.%m.%Y %H:%M'))
                for _time in day_record[1:]
            ]
            for i in range(len(headers)):
                display_alarm = DisplayAlarm(trigger=events_starts[i],
                                             display_text=headers[i])
                audio_alarm = AudioAlarm(trigger=events_starts[i])
                audio_alarm.sound = ContentLine('ATTACH',
                                                {'FMTTYPE': ['audio/mpeg']},
                                                app.config['ADHAN_AUDIO'])

                calendar.events.add(
                    Event(name=headers[i],
                          begin=events_starts[i],
                          duration=timedelta(minutes=1),
                          alarms=[audio_alarm, display_alarm]))
        return calendar
Пример #4
0
 def parse_time(cls, time_obj: Union[str, datetime], tz: pytz.timezone = None) -> datetime:
     assert isinstance(time_obj, (str, datetime)), (type(time_obj), time_obj)
     if isinstance(time_obj, str):
         time_obj = dateutil.parser.parse(time_obj)
     if not time_obj.tzinfo:
         assert tz, '{} is naive. tz must set'.format(time_obj)
         time_obj = tz.localize(time_obj)
     else:
         time_obj = time_obj.astimezone(tz)
     return time_obj
Пример #5
0
def _make_iso_time(time: datetime, date: datetime,
                   time_zone: pytz.timezone) -> str:
    """
    Combine time and date and timezone
    :param time: a time (without a date)
    :param date: a date
    :param time_zone: pytz timezone
    :return: iso 8601 time string
    """
    time_combined = time.replace(year=date.year,
                                 month=date.month,
                                 day=date.day)
    return time_zone.localize(time_combined).isoformat()
Пример #6
0
 def delocalizeAllTimestamps(self, toTimezone):
     tz = TimeZone(toTimezone)
     newDateObj = {}
     for timeObj in self.tsData:
         print('Old time: ' + str(timeObj))
         if timeObj.tzinfo is not None:
             print('No need to convert time...already localized')
             newDateObj[str(timeObj)] = self.tsData[timeObj]
             continue
         localDateObj = tz.localize(timeObj)
         utcDateObj = localDateObj.astimezone(pytz.utc)
         print('New time: ' + str(utcDateObj))
         newDateObj[str(utcDateObj)] = self.tsData[timeObj]
     self.tsData = newDateObj
Пример #7
0
 def delocalizeAllTimestamps(self, toTimezone):
     tz = TimeZone(toTimezone)
     newDateObj = {}
     for timeObj in self.tsData:
         print 'Old time: ' + str(timeObj)
         if timeObj.tzinfo is not None:
             print 'No need to convert time...already localized'
             newDateObj[str(timeObj)] = self.tsData[timeObj]
             continue
         localDateObj = tz.localize(timeObj)
         utcDateObj = localDateObj.astimezone(pytz.utc)
         print 'New time: ' + str(utcDateObj)
         newDateObj[str(utcDateObj)] = self.tsData[timeObj]
     self.tsData = newDateObj
Пример #8
0
def convert_naive_to_db(naive: datetime, local_tz: pytz.timezone) -> datetime:
    """
    This function inputs a naive datetime, attaches the given (local) timezone to it,
    then converts it to the database timezone

    Returns: a database timezone datetime
    """

    # attach proper timezone for the date (fayetteville.gov for example uses America/Chicago)
    dt = local_tz.localize(naive)

    # convert to database timezone
    dt = dt.astimezone(app.config['TIMEZONE'])
    return dt
Пример #9
0
def get_arrival_history(as_of_date: datetime, time_zone: pytz.timezone,
                        increment: timedelta, agency: str, route_ids: list,
                        start_hour: int, continue_index):
    start_dt = time_zone.localize(
        datetime(as_of_date.year,
                 as_of_date.month,
                 as_of_date.day,
                 hour=start_hour))
    end_dt = start_dt + increment

    start_time = int(start_dt.timestamp())
    end_time = int(end_dt.timestamp())

    print(f"time = [{start_dt}, {end_dt})")

    t1 = time.time()

    state = trynapi.get_state(agency, as_of_date, start_time, end_time,
                              route_ids)

    print(f'retrieved state in {round(time.time()-t1,1)} sec')

    for i, route_id in enumerate(route_ids):
        if continue_index is not None and i < continue_index:
            continue

        route_state = state.get_for_route(route_id)

        if route_state is None:
            print(f'no state for route {route_id}')
            continue

        route_config = nextbus.get_route_config(agency, route_id)

        t1 = time.time()

        arrivals_df = eclipses.find_arrivals(route_state, route_config,
                                             as_of_date, time_zone)

        history = arrival_history.from_data_frame(agency, route_id,
                                                  arrivals_df, start_time,
                                                  end_time)

        print(f'{route_id}: {round(time.time()-t1,1)} saving arrival history')

        arrival_history.save_for_date(history, d, args.s3)

        print(f'{route_id}: {round(time.time()-t1,2)} done')
Пример #10
0
def get_localized_datetime(d: date, time_str: str, tz: pytz.timezone):

    time_str_parts = time_str.split('+')  # + number of days

    if len(time_str_parts[0].split(':')) == 2:
        format = "%Y-%m-%d %H:%M"
    else:
        format = "%Y-%m-%d %H:%M:%S"

    dt_str = f"{d.isoformat()} {time_str_parts[0]}"

    dt = datetime.strptime(dt_str, format)
    if len(time_str_parts) > 1:
        dt = dt + timedelta(days=int(time_str_parts[1]))

    return tz.localize(dt)
Пример #11
0
def as_local_tz(date_time: Optional[str],
                tz: pytz.timezone = BERLIN) -> Optional[dt.datetime]:
    """Add timezone info to timezone naive isoformat date/time string.

    Args:
        date_time (Optional[str]): String containing timezone naive isoformat date/time
            string.
        tz (pytz.timezone, optional): Timezone to add to naive string. Defaults to
            BERLIN.

    Returns:
        Optional[dt.datetime]: dt.datetime object with tz timezone. Returns None if
            input date_time is None.
    """
    if date_time is not None:
        return tz.localize(dt.datetime.fromisoformat(date_time))
    else:
        return None
Пример #12
0
def dt_series(tz: timezone = timezone("UTC")) -> List[datetime]:
    """
        Generate a datetime series

    """
    end = dt_floor(tz.localize(datetime.now()))

    start = end - timedelta(days=7)
    interval = timedelta(minutes=5)

    dc_current = start
    series = []

    while dc_current <= end:
        series.append(dc_current)
        dc_current += interval

    return series
Пример #13
0
 def __init__(self, timestamp: datetime, tz: timezone = utc):
     """
     Creates a wiki date-time object
     :param timestamp: a datetime object
     :param tz: optional, a timezone. if not provided, utc will be assumed.
     """
     if timestamp.tzinfo is None:
         timestamp = tz.localize(timestamp)
     self.pst_object = timestamp.astimezone(self.pst)
     self.cet_object = timestamp.astimezone(self.cet)
     self.kst_object = timestamp.astimezone(self.kst)
     self.pst_date = self.pst_object.strftime('%Y-%m-%d')
     self.cet_date = self.cet_object.strftime('%Y-%m-%d')
     self.kst_date = self.kst_object.strftime('%Y-%m-%d')
     self.pst_time = self.pst_object.strftime('%H:%M')
     self.cet_time = self.cet_object.strftime('%H:%M')
     self.kst_time = self.kst_object.strftime('%H:%M')
     self.dst = self._determine_dst()
Пример #14
0
def tupleToDateTime(dtTuple: tuple, tzone: timezone) -> datetime:
    """
    Converts a given typle representation of a datetime into a datatime object.

    Parameterrs:
        dtTuple (tuple): A tuple representation of the datetime (YYYY, m, d, H, M, S)
        tzone (timezone): The timezone of the datetime represented by the tuple

    Returns:
        datetime: timezone aware representationn of the given tuple
    """

    if (len(dtTuple) != 6):
        raise ValueError(
            "Tuple must contain 6 items (year, month, day, hour, minute, second)"
        )

    # TODO: validation of each item in the tuple to ensure it is in the acceptable range for a datatime
    year = dtTuple[0]
    if (year < MINYEAR or MAXYEAR < year):
        raise ValueError("YEAR must be between (inclusive) " + MINYEAR +
                         " and " + MAXYEAR)
    month = dtTuple[1]
    if (month < 1 or 12 < month):
        raise ValueError("MONTH must be between (inclusive) 1 and 12")
    day = dtTuple[2]
    if (day < 1 or 31 < day):
        raise ValueError("DAY must be between (inclusive) 1 and 31")
    hour = dtTuple[3]
    if (hour < 0 or 23 < hour):
        raise ValueError("HOUR must be between (inclusive) 0 and 23")
    minute = dtTuple[4]
    if (minute < 0 or 59 < minute):
        raise ValueError("MINUTE must be between (inclusive) 0 and 59")
    second = dtTuple[5]
    if (second < 0 or 59 < second):
        raise ValueError("SECOND must be between (inclusive) 0 and 59")

    return tzone.localize(datetime(year, month, day, hour, minute, second))
Пример #15
0
def compute_arrivals_for_date(d: date, start_hour: int, tz: pytz.timezone,
                agency: str, route_ids: list,
                s3=False):

    start_dt = tz.localize(datetime(d.year, d.month, d.day, hour=start_hour))
    end_dt = start_dt + timedelta(days=1)

    start_time = int(start_dt.timestamp())
    end_time = int(end_dt.timestamp())

    print(f"time = [{start_dt}, {end_dt})")

    t1 = time.time()

    state = trynapi.get_state(agency, d, start_time, end_time, route_ids)

    print(f'retrieved state in {round(time.time()-t1,1)} sec')

    for i, route_id in enumerate(route_ids):
        route_state = state.get_for_route(route_id)

        if route_state is None:
            print(f'no state for route {route_id}')
            continue

        route_config = nextbus.get_route_config(agency, route_id)

        t1 = time.time()

        arrivals_df = eclipses.find_arrivals(route_state, route_config, d, tz)

        history = arrival_history.from_data_frame(agency, route_id, arrivals_df, start_time, end_time)

        print(f'{route_id}: {round(time.time()-t1,1)} saving arrival history')

        arrival_history.save_for_date(history, d, s3)

        print(f'{route_id}: {round(time.time()-t1,2)} done')
Пример #16
0
def dt_to_other_timezone(dt: datetime,
                         destination_timezone_name: str,
                         origin_timezone_name: str = 'UTC') -> datetime:
    """
    The only, safest, way I know to convert datetime object from one timezone to
    another while accounting for things like Daylight Saving Time
    (also known as "Summer Time") and "leap" stuff.

    Tried many many other ways and anything that work with pure offsets is plain bad.
    Must work with proper tx names and pytz is the best way on Python.

    Offsets plainly don't work because DST-vs-no-DST varies based on specific locale.

    For example, US state of Arizona, while being part of `US/Mountain` time zone
    does NOT observe Daylight Saving Time, like rest of that time zone. As a result,
    it's effectively on US Mountain time zone in the winter and in US Pacific (right?)
    for most of rest of the year.

    Then, add to that the fact that Summer Time starts and ends on different dates
    depending on a country and, as a result, noon in San Diego, California is not
    guaranteed to be noon in Tijuana - a city only 30 kilometers *South*

    As a result of all the above, learned to specify timezone names as specifically
    as possible. Say, "America/Los_Angeles" vs "US/Pacific" and work only with
    time-zone-aware datetimes and only with timezones that are timezone-name aware
    and support something like Olson timezone DB (https://en.wikipedia.org/wiki/Tz_database)

    :param datetime.datetime dt:
        Some datetime object. May be timezone-naive, in which case origin timezone
        name is required and is used to localize the incoming dt before tz conversion.
    :param str destination_timezone_name:
        'UTC' or some standard tz name string like "America/Los_Angeles"
    :param str origin_timezone_name:
        'UTC' (default) or some standard tz name string like "Europe/Paris"
    :return:
    """
    from pytz import UTC, timezone as Timezone
    from pytz.tzinfo import DstTzInfo

    if dt.tzinfo is None:
        assert origin_timezone_name
        origin_tz = Timezone(origin_timezone_name)
        # this step properly bakes together origin tz and dt
        tz_local_dt = origin_tz.localize(dt)
    elif dt.tzinfo == UTC or isinstance(dt.tzinfo, DstTzInfo):
        # this is an easy way out. These TZs properly react to
        # .normalize() method so no need to do anything with dt
        tz_local_dt = dt
    else:
        # We are here if tzinfo is set on dt,
        # but we don't know what the implementation is
        # (possibly some offset-based thing)
        # and, thus don't trust it to do the right thing
        # Hence, flipping it to UTC-based safe intermediate state
        # which does not have daylight saving time issues.
        tz_local_dt = dt.astimezone(UTC)

    destination_tz = Timezone(destination_timezone_name)

    # this step properly (with account for Daylight saving time) moves
    # dt to other timezone.
    return destination_tz.normalize(tz_local_dt)
Пример #17
0
 def localize(self, local_tz: timezone) -> None:
     """Convert the modify timestamp into a timezone aware one."""
     self.modify = local_tz.localize(self.modify)
Пример #18
0
def timestamp_from_datetime(datetime_instance: datetime, tz: timezone = utc):
    if not datetime_instance.tzinfo:
        datetime_instance = tz.localize(datetime_instance)

    return calendar.timegm(datetime_instance.astimezone(utc).timetuple())
Пример #19
0
def get_clearsky_irradiance(start_time: datetime.datetime = None,
                            end_time: datetime.datetime = None,
                            timezone: pytz.timezone = None,
                            latitude: float = None,
                            longitude: float = None,
                            sun_zenith: pd.DataFrame = None,
                            granularity: int = 60,
                            clearsky_estimation_method: str = 'pysolar',
                            google_api_key: str = None):

    if (clearsky_estimation_method == 'pysolar' or google_api_key == None):

        ##################################################################################
        #
        # Pandas .apply based code, but it is slower than while loop
        # from helpers import granularity_to_freq
        #
        # datetime_series = pd.date_range(start_time, end_time, freq=granularity_to_freq(granularity))
        # datetime_series_localized = datetime_series.tz_localize(timezone)
        # data = pd.DataFrame({'time':datetime_series_localized})
        # data['altitude_deg'] = data['time'].apply(lambda timestamp: pysolar.solar.get_altitude(latitude, longitude, timestamp))
        # data['clearsky'] = data.apply(lambda row: pysolar.solar.radiation.get_radiation_direct(row['time'], row['altitude_deg']), axis=1)
        # data['time'] = data['time'].apply(lambda x: x.replace(tzinfo=pytz.utc).replace(tzinfo=None))
        ##################################################################################

        # localizing the datetime based on the timezone
        start: datetime.datetime = timezone.localize(start_time)
        end: datetime.datetime = timezone.localize(end_time)

        # create arrays to store time and irradiance
        clearsky: List[int] = []
        time_: List[datetime.datetime] = []

        # go through all the hours between the two dates
        while start <= end:

            # get the altitude degree for the given location
            altitude_deg: float = pysolar.solar.get_altitude(
                latitude, longitude, start)

            # get the clearsky based on the time and altitude
            clear_sky: float = pysolar.solar.radiation.get_radiation_direct(
                start, altitude_deg)

            # removing the timezone information
            dt: datetime.datetime = start.replace(tzinfo=pytz.utc).replace(
                tzinfo=None)

            # saving the data in the lists
            clearsky.append(clear_sky)
            time_.append(dt)

            # increasing the time by 1 hrs, normazlizing it to handle DST
            start = timezone.normalize(start +
                                       datetime.timedelta(seconds=granularity))

        # create dataframe from lists
        irradiance: pd.DataFrame = pd.DataFrame({
            'time': time_,
            'clearsky': clearsky
        })

    elif (clearsky_estimation_method == 'lau_model'
          and google_api_key != None):

        # use google maps python api to get elevation
        gmaps = googlemaps.Client(key=google_api_key)
        elevation_api_response: list = gmaps.elevation((latitude, longitude))
        elevation_km: float = elevation_api_response[0]['elevation'] / 1000

        # create a date_range and set it as a time column in a dataframe
        datetime_series = pd.date_range(start_time,
                                        end_time,
                                        freq=granularity_to_freq(granularity))
        # datetime_series_localized = datetime_series.tz_localize(timezone)
        irradiance = pd.DataFrame({'time': datetime_series})

        # based on "E. G. Laue. 1970. The Measurement of Solar Spectral Irradiance at DifferentTerrestrial Elevations.Solar Energy13 (1970)",
        # Check details on this model on Section 2.4 on PVeducation.org
        irradiance['air_mass'] = 1 / (
            np.cos(sun_zenith) +
            0.50572 * pow(96.07995 - np.rad2deg(sun_zenith), -1.6364))
        irradiance['clearsky_direct'] = 1.361 * (
            (1 - 0.14 * elevation_km) * pow(0.7, irradiance['air_mass']**0.678)
            + 0.14 * elevation_km)
        irradiance['clearsky'] = 1000 * 1.1 * irradiance['clearsky_direct']

        # replace nan with 0 and keep only time and clearsky columns
        irradiance['clearsky'] = irradiance['clearsky'].fillna(0)
        irradiance = irradiance[['time', 'clearsky']]

    else:
        raise ValueError(
            'Invalid argument for clearsky_estimation_method or google_api_key.'
        )

    return irradiance