def table_to_csvs(table: Table, start: datetime, end: datetime) -> list: """Take a feature of interest table and split it into a bunch of csv files that are grouped by node. Return the names of all the files it made. """ files = {} writers = {} file_names = [] query = redshift_session.query(table) \ .filter(table.c.datetime >= start) \ .filter(table.c.datetime < end) \ .yield_per(1000) for row in query: node = row.node_id if node not in files: file = '{}.{}.{}.{}.csv' feature = table.name.split('__')[1] file = file.format(node, feature, start.date(), end.date()) file_names.append(file) files[node] = open('/tmp/' + file, 'w') writers[node] = csv.writer(files[node]) writers[node].writerow(row.keys()) writers[node].writerow(row) for file in files.values(): file.seek(0) file.close() return file_names
def format_date(dat: datetime, tz=None): today = datetime.now(tz=tz).date() if dat.date() == today: return '今天{0:%H}:{0:%M}'.format(dat) elif dat.date() == today + timedelta(days=1): return '明天{0:%H}:{0:%M}'.format(dat) elif dat.date() == today + timedelta(days=2): return '后天{0:%H}:{0:%M}'.format(dat) elif dat.date() == today - timedelta(days=1): return '昨天{0:%H}:{0:%M}'.format(dat) elif dat.year == today.year: return '{0:%m}月{0:%d}日{0:%H}:{0:%M}'.format(dat) else: return '{0:%Y}年{0:%m}月{0:%d}日{0:%H}:{0:%M}'.format(dat)
def get_daily_limit(self, dt: datetime) -> Decimal: budget = self.days[dt.date()].budget cost = self.days[dt.date()].cost matched_time = next( (time for time in sorted(budget.items.keys()) if dt.time() >= time), None) if matched_time is None: prev_date = dt.date() - timedelta(days=1) cur_budget = self.days[prev_date].budget.maximum else: cur_budget = budget.items[matched_time] return cur_budget * Decimal(DAILY_BUDGET_FACTOR) - cost.total
def get_date_range_str(since: datetime, until: datetime, args: Namespace) -> str: if args.day: return '昨日' if args.week: return '先週' if args.month: return '先月' if args.this_month: return '今月' if (until - since).days == 1: return since.date().isoformat() return '{}〜{}'.format(since.date().isoformat(), (until - timedelta(days=1)).date().isoformat())
async def async_get_events(self, hass: HomeAssistant, start_date: datetime, end_date: datetime) -> list[CalendarEvent]: """Return calendar events within a datetime range.""" events: list[CalendarEvent] = [] for waste_type, waste_dates in self.coordinator.data.items(): events.extend( CalendarEvent( summary=WASTE_TYPE_TO_DESCRIPTION[waste_type], start=waste_date, end=waste_date, ) for waste_date in waste_dates if start_date.date() <= waste_date <= end_date.date()) return events
def get_date_records(self, date: datetime) -> list: records = [ time for time in self._timestamps if time.date() == date.date() ] if len(records) == 0: for time in self.api.get_employee_record_by_date( self.user_id, date): self._timestamps.append(time) self._timestamps.sort() records = [ time for time in self._timestamps if time.date() == date.date() ] return records
def create(when: datetime, product_id: int, titles_and_severities: List[Tuple[str, str]]): with patch('django.db.models.fields.timezone.now') as mock_now: mock_now.return_value = when engagement = Engagement.objects.create(product_id=product_id, target_start=when.date(), target_end=when.date()) test = Test.objects.create(engagement=engagement, test_type_id=120, target_start=when, target_end=when) Finding.objects.bulk_create( (Finding(title=title, test=test, severity=severity, verified=False) for title, severity in titles_and_severities))
def export_command( start: datetime = start_argument, end: datetime = end_argument, user: str = typer.Argument(..., help="Username to attempt to login with"), output_dir: Path = typer.Option( "./", exists=True, file_okay=False, dir_okay=True, writable=True, help="Directory to write usage data files to, (default: ./)" ) ) -> None: data.export(user, start.date(), end.date(), output_dir)
def get_date_string(then: datetime, now: datetime = datetime.now(timezone.utc)): _, week_number_now, _ = get_meta_data(now) day_then, week_number_then, _ = get_meta_data(then) time = then.strftime("%I:%M %p") time_fallback = then.strftime("%b %d, %y at %I:%M %p") past = False future = False if then.date() == now.date(): return f"Today at {time}" else: if then.date() > now.date(): future = True elif then.date() < now.date(): past = True if past: if is_yesterday(then.date()): return f"Yesterday at {time}" elif week_number_now == week_number_then: return f"{day_then} at {time}" elif week_number_then + 1 == week_number_now: return f"Last {day_then} at {time}" elif future: if is_tomorrow(then.date()): return f"Tomorrow at {time}" elif week_number_now == week_number_then: return f"{day_then} at {time}" elif week_number_then == week_number_now + 1: return f"Next {day_then} at {time}" return f"{time_fallback}"
def _rfcGetSmonAnalysisByRunId(self, connection: Connection, guid: str, startDateTime: datetime, endDateTime: datetime): rfcName = '/SDF/SMON_ANALYSIS_READ' result = None if not guid: raise ValueError( ("argument error for rfc %s for hostname: %s, guid: %s, " "expected start (%s) and end time (%s) to be same day") % (rfcName, self.sapHostName, guid, startDateTime, endDateTime)) # validate that start and end time are the same day, since thaty is what RFC expects if (startDateTime.date() != endDateTime.date()): raise ValueError( ("argument error for rfc %s for hostname: %s, guid: %s, " "expected start (%s) and end time (%s) to be same day") % (rfcName, self.sapHostName, guid, startDateTime, endDateTime)) self.tracer.info( "[%s] invoking rfc %s for hostname=%s with guid=%s, datum=%s, start_time=%s, end_time=%s", self.logTag, rfcName, self.sapHostName, guid, startDateTime.date(), startDateTime.time(), endDateTime.time()) try: result = connection.call(rfcName, GUID=guid, DATUM=startDateTime.date(), START_TIME=startDateTime.time(), END_TIME=endDateTime.time()) return result except CommunicationError as e: self.tracer.error( "[%s] communication error for rfc %s with hostname: %s (%s)", self.logTag, rfcName, self.sapHostName, e, exc_info=True) except Exception as e: self.tracer.error( "[%s] Error occured for rfc %s with hostname: %s (%s)", self.logTag, rfcName, self.sapHostName, e, exc_info=True) return None
def create_time_series(data: pd.Series, series_length_years: int, start_date: datetime.datetime = None, last_date: datetime.datetime = None, equal_series: bool = True): """Creates a list of time series of the given length from the data provided. Args: data (pd.Series): pandas series with all the data, indexed with the timestamp. series_length_years (int): length of each series in the list to be created. start_date (datetime.datetime, optional): Date the first time series should start from. If None, '2002-01-01' is used. Defaults to None. last_date (datetime.datetime, optional): Date the last time series should end on. If None, last date found in `data` will be used. Defaults to None. equal_series (bool): if True, all series created will be of equal length. last series created will be removed if it is shorter than the others. Returns: (list of pd.Series): python list containing all the time series created. """ # Updating dictionaries. if start_date is None: start_date = datetime.datetime(2002, 1, 1) if last_date is None: last_date = max(data.index.date) else: last_date = last_date.date() start_date = start_date.date() time_series_list = [] while start_date < last_date: end_date = start_date + pd.DateOffset( years=series_length_years) - pd.DateOffset(days=1) time_series_list.append(data.loc[start_date:end_date]) start_date = end_date + pd.DateOffset(days=1) is_last_equal = str(max(time_series_list[0].index.date))[5:10] == str( max(time_series_list[-1].index.date))[5:10] if equal_series and not is_last_equal: time_series_list = time_series_list[:-1] print(f'Number of series created: {len(time_series_list)}') print(f'Last series removed: {not is_last_equal}') print(f'Last series end date: {max(time_series_list[-1].index.date)}') return time_series_list
def updated_train_date_msg(self, addresse, old_date: datetime, training): try: server = self.run_local() subject = "Subject: Training on {} rescheduled\n\n".format( str(old_date.date())) message = "Training of id {} rescheduled from {} to {}".format( training.id, str(old_date.date()), str(training.date.date())) server.sendmail(self.sender, addresse, subject + message) self.log_mail(addresse, subject, message) except Exception as e: server = None print("updated_train_date_msg: {}".format(str(e))) finally: if server is not None: server.close()
async def get_earnings_calendars(self, symbol: str, _from: datetime.datetime, _to: datetime.datetime): path = "/calendar/earnings" params = { "symbol": symbol, "from": _from.date().isoformat(), "to": _to.date().isoformat(), "token": self.apikey } async with await self.make_request("GET", self.url + path, params=params) as response: result = (await response.json())["earningsCalendar"] for res in result: res["date"] = self.__transform_date(res.get("date", "")) del res["symbol"] del res["year"] return [res for res in result if all(v is not None for _, v in res.items())]
def payment_term(project_end_date: datetime) -> str: """ コンビニ/Pay-easy決済の支払い期限計算 :param project_end_date: プロジェクト終了日 :return: 支払い期限日 """ today = datetime.today() if project_end_date.date() == today.date(): return None add_days = min(7, (project_end_date.date() - today.date()).days) payment_term_ = date.today() + timedelta(days=add_days - 1) weekday = ('(月)', '(火)', '(水)', '(木)', '(金)', '(土)', '(日)') return payment_term_.strftime('%Y年%m月%d日' + weekday[payment_term_.weekday()])
def resolved_timetable_of(self, dt: datetime) -> List[ResolvedTimetableSlot]: """Return a list of ResolvedTimetableSlot objects for the provided dt""" return [ ResolvedTimetableSlot.fromslot(slot, dt.date()) for slot in self._timetables[dt.weekday()] ]
def since_date(self, date_since: datetime, include_today: bool=False): if isinstance(date_since, datetime): date_since = date_since.date() rate_dict = self.historical(date_since, None, include_today) return rate_dict
def get_schedule(self, date: datetime): """ Returns schedule for one day :param date: date to show schedule :return: list of dictionary {'datetime': XXX, 'title': 'Movie title', 'movie_id': 'ID'} """ res = list() sess = self._session q = sess.\ query(ShowTime, Movie).\ filter(func.date_trunc('day', ShowTime.date) == date.date()).\ join(Movie, Movie.id == ShowTime.movie_id).\ order_by(ShowTime.date).all() for el in q: el = el._asdict() res.append({ 'id': el.get('ShowTime').id, 'movie_id': el.get('ShowTime').movie_id, 'title': el.get('Movie').name, 'datetime': el.get('ShowTime').date, 'genre': el.get('Movie').genre }) return res
def _store_bars(data: list, end: dt, path: str, symbol: str, channel: str, bar: str, header: dt): """ Stores the data as .csv files on a pre-defined (see README.md) directory structure. Note: On the first time this function is called, 'header' will be of type None, subsequently it will be of type datetime. """ for row in data: date = parse(row["timestamp"]).date() if date > end.date(): return location = f"{path}/{symbol}/{channel}/{bar}/{date.year}/{date.month}" if not os.path.isdir(location): os.makedirs(location) d = date.strftime("%Y%m%d") _file = f"{location}/{d[:4]}-{d[4:6]}-{d[6:]}.csv" new = True if date != header else False if new: _delete_old(_file) with open(_file, "a", newline="") as f: writer = csv.DictWriter(f, fieldnames=_headers[channel]) # "header" starts as None but from the 2nd iteration on it equals the last # date. If the actual date (not datetime) is different than the previous one, # a new header is written (on a new file). if header != date: writer.writeheader() header = date writer.writerow(row) return header
async def handle_vote(self, context: Context, date: datetime, time: datetime, message: str): data = await self.get_message_data(message) if data is None or not data.is_valid(): await context.message.channel.send(messages.Messages.vote_format) return if date is None: data.date = time else: if time is None: data.date = date else: data.date = datetime.combine(date.date(), time.time()) if data.date is not None and data.date < datetime.now(): await context.message.channel.send(messages.Messages.vote_bad_date) return for o in data.options: try: await context.message.add_reaction(o[0]) except HTTPException: await context.message.channel.send( messages.Messages.vote_not_emoji.format(not_emoji=o[0])) await context.message.channel.send(messages.Messages.vote_none) if data.date is not None: sec = (data.date - datetime.now()).total_seconds() asyncio.ensure_future( self.send_winning_msg(context.channel.id, context.message.id, sec))
async def get_splits(self, symbol: str, _from: datetime.datetime, _to: datetime.datetime): path = "/stock/split" params = { "symbol": symbol, "from": _from.date().isoformat(), "to": _to.date().isoformat(), "token": self.apikey } async with await self.make_request("GET", self.url + path, params=params) as response: result = await response.json() for res in result: res["date"] = self.__transform_date(res.get("date", "")) res["fromFactor"] = float(res["fromFactor"]) res["toFactor"] = float(res["toFactor"]) del res["symbol"] return result
async def get_historical_bid_ask(self, symbol: str, date: datetime.datetime, limit: int, skip: int): path = "/stock/bbo" params = { "symbol": symbol, "date": date.date().isoformat(), "limit": limit, "skip": skip, "format": "csv", "token": self.apikey } async with await self.make_request("GET", self.url + path, params=params) as response: result = await response.json() data = [{ "ask": result["a"][i], "ask_volume": result["av"][i], "ask_exchange": result["ax"][i], "bid": result["b"][i], "bid_volume": result["bv"][i], "bid_exchange": result["bx"][i], "date": self.__transform_date(result["t"][i] / 1000.0) } for i in range(len(result["t"])) ] return data, result["total"]
def create_prescription( subject_identifier: str, report_datetime: datetime, randomizer_name: str, medication_name: str, ): medication_model_cls = django_apps.get_model("edc_pharmacy.medication") rx_model_cls = django_apps.get_model("edc_pharmacy.rx") action = PrescriptionAction(subject_identifier=subject_identifier) try: medication = medication_model_cls.objects.get( name__iexact=medication_name) except ObjectDoesNotExist: medication = medication_model_cls.objects.create(name=medication_name) try: rx_model_cls.objects.get(action_identifier=action.action_identifier) except ObjectDoesNotExist: rx_model_cls.objects.create( action_identifier=action.action_identifier, subject_identifier=subject_identifier, report_datetime=report_datetime, rx_date=report_datetime.date(), medication=medication, randomizer_name=randomizer_name, )
def get_start_end_dates(jmt_report: dict, timestamp: datetime) -> Tuple[str, str]: """ Choose the date range to look for permits. Start date must be greater than or equal to: - START_DATE defined at top of script - first date in the JMT report - last report date + MIN_RESERVE_DAYS (currently 2) - JMT trailhead opening date (currently June 15) End date must be less than or equal to: - END_DATE defined at top of script - last date in the JMT report - last report date + MAX_RESERVE_DAYS (currently 168) - JMT trailhead close date (currently September 30) :param jmt_report: dictionary of reserved permits (output of get_jmt_report) :param timestamp: timestamp of the last report update :return: start date and end date in YYYY-MM-DD format """ min_found_date = min(jmt_report) max_found_date = max(jmt_report) report_date = timestamp.date() min_reserve_date = (report_date + timedelta(days=config.MIN_RESERVE_DAYS)).strftime("%Y-%m-%d") max_reserve_date = (report_date + timedelta(days=config.MAX_RESERVE_DAYS)).strftime("%Y-%m-%d") open_date = f"{report_date.year}-{config.OPEN_DATE}" close_date = f"{report_date.year}-{config.CLOSE_DATE}" start_date = max(config.START_DATE, min_found_date, min_reserve_date, open_date) end_date = min(config.END_DATE, max_found_date, max_reserve_date, close_date) return start_date, end_date
def loadDayPosts(self, day: dt.datetime): # check if folder exists if not os.path.isdir(self.fpathPosts): print('The folder for {}/posts does not exist'.format(self.subreddit)) return pd.DataFrame() else: # get name of file for the date fname = '{}.csv'.format(day.date()) loadpath = os.path.join(self.fpathPosts, fname) # check for file if os.path.exists(loadpath): return pd.read_csv(loadpath) else: print("\033[31m{}\033[37m does not exist in {}/posts".format(day.date(), self.subreddit)) return pd.DataFrame()
def edit(reservation_num, new_start: datetime, new_end=sentinel): """ Function for editing a current reservation to a new time. :param reservation_num: The unique ID of the reservation to edit. :param newDate: The proposed new date of the reservation. :param new_start: The proposed new start time of the reservation. :param new_end: The proposed new end time of the reservation, which has a default of two hours after new_start. :return: Returns a bool indicating the success of the edit. """ if new_end is sentinel: new_end = new_start + timedelta(hours=2) newDate = new_start.date() validity_tuple = isValidNewReservation(new_start, new_end, newDate, reservation_num) print(validity_tuple[0]) if validity_tuple[0]: rezzy = models.Reservation.objects.get(id=reservation_num) rezzy.start_date_time = new_start # Todo In Reservations: change date and time. In Table: Remove res for old table, add res for new table. rezzy.end_date_time = new_end rezzy.created_date = datetime.now() rezzy.table = validity_tuple[1] rezzy.save() return True else: # Todo give a error to user which says the changes could not be made. return False
def dt2ed(dt: datetime.datetime) -> int: """ Converts a datetime to number of complete days since epoch :param dt: The datetime to convert :return: An integer of the number of full days since epoch. """ return (dt.date() - EPOCH_DT).days
def zodiac_date_verifier(self, query_date: datetime) -> str: """Returns zodiac sign by checking date.""" for zodiac_name, zodiac_data in self.zodiac_fact.items(): if zodiac_data["start_at"].date() <= query_date.date( ) <= zodiac_data["end_at"].date(): log.trace("Zodiac name sent.") return zodiac_name
def get_next_scheduling_datetime( self, now: datetime.datetime) -> T.Optional[datetime.datetime]: """Returns a datetime object with the time at which the next re-scheduling should be done. now should be a datetime object containing the current date and time. SubScheduleRule objects and their rules are considered as well. None is returned in case there are no rules in the schedule which are not universally valid anyway.""" times = self.get_scheduling_times() if not times: # no constrained rules in schedule return None current_time = now.time() today = now.date() tomorrow = today + datetime.timedelta(days=1) def map_func(_time: datetime.time) -> datetime.datetime: """Maps a time object to a datetime containing the next occurrence of that time. Midnight transitions are handled correctly.""" if _time < current_time: # midnight transition return datetime.datetime.combine(tomorrow, _time) return datetime.datetime.combine(today, _time) return min(map(map_func, times))
def create_register(self, start: datetime, end: datetime): if start.date() in self.holidays: return False data = { 'userId': self.user_id, '_id': 'new', 'timezone': '+0000', 'timezoneName': 'hora de verano de Europa central', 'type': 'work', 'commentary': '', 'start': start.strftime('%Y-%m-%dT%H:%M:%SZ'), 'end': end.strftime('%Y-%m-%dT%H:%M:%SZ'), 'trace': [] } body = json.dumps(data).encode('utf8') req = urllib.request.Request(f'{self.BASE_URL}/v2/timespans/create', data=body, headers={'content-type': 'application/json', 'x-vacationtoken': self.token}) try: with urllib.request.urlopen(req): pass except urllib.error.URLError as e: message = e.read().decode('utf-8') if e.code == 412 and message == 'Los registros no se pueden solapar': print(f'Day {self.day} has register hours') return False else: print(f'Error code {e.code} with message {message}') raise return True
def _get_applicable_entry(when: datetime) -> Optional[AthleteData]: """ Get the athlete data entry that's applicable for a certain date. Args: when: The data whose entry we want. Returns: Optional[AthleteData]: The athlete data, if found. """ # Make sure we've got athlete data _get_athlete_data() # Burn any timezone we've got when = when.replace(tzinfo=None) # Find the athlete data entry with the latest date equal to or before # the provided date selected_entry: AthleteData = None for data in ATHLETE_DATA_LIST: if data.start_date.date() < when.date(): selected_entry = data # Done return selected_entry
def generate_orders(self, state: dt.datetime, backtest: PredefinedAssetBacktest = None) -> list: date = state.date() contract = Security(ric='TestRic') orders = [] units_to_trade = 1 """ enter trade is a TWAP order between 10 and 10:30 """ exec_start = dt.datetime.combine(date, dt.time(10)) exec_end = dt.datetime.combine(date, dt.time(10, 30)) orders.append( OrderTWAP(instrument=contract, quantity=units_to_trade, generation_time=state, window=TimeWindow(start=exec_start, end=exec_end), source=str(self.__class__))) """ exit the intraday quantity at TWAP between 14 and 14:30 """ twap_start = dt.datetime.combine(date, dt.time(14)) twap_end = dt.datetime.combine(date, dt.time(14, 30)) orders.append( OrderTWAP(instrument=contract, quantity=units_to_trade * -1, generation_time=state, window=TimeWindow(start=twap_start, end=twap_end), source=str(self.__class__))) return orders
def isCurrentOn(self, dt: datetime.datetime): pyDateDays = [ #py datetime.date -- 0 == monday, 6 == sunday DayOfWeek.Monday, DayOfWeek.Tuesday, DayOfWeek.Wednesday, DayOfWeek.Thursday, DayOfWeek.Friday, DayOfWeek.Saturday, DayOfWeek.Sunday ] #log.debug("checking if event current on %s" % str(dt)) if self.day() != DayOfWeek.Any: if pyDateDays[dt.date().weekday()] != self.day(): #log.debug("Not today") return False if self.isAllDay(): return True # any day, or this day, check times tmVal = dt.time() if tmVal >= self.startTime() and tmVal <= self.endTime(): return True return False
def get_next_run_time(self, now: datetime, previous_run_time: datetime = None) -> Optional[datetime]: # Determine the starting point of the calculations today = now.date() if previous_run_time: previous_date = previous_run_time elif today > self.start_date: previous_date = self.start_date else: previous_date = None while True: if previous_date: year, month = previous_date.year, previous_date.month next_date = None while not next_date or next_date < today: month += self.months year += self.years + month // 12 month %= 12 try: next_date = date(year, month, previous_date.day) except ValueError: pass # Nonexistent date else: next_date += timedelta(self.days + self.weeks * 7) break else: next_date = self.start_date # Don't return any date past end_date if self.end_date and next_date > self.end_date: return None next_time = datetime.combine(next_date, self.time) try: next_time = self.timezone.localize(next_time, is_dst=None) except AmbiguousTimeError: # This datetime occurs twice (with and without DST), so return the first of them # that is still equal to or later than "now". If both times have passed already, # move on to the next date. times = sorted(self.timezone.localize(next_time, is_dst=is_dst) for is_dst in (False, True)) if times[0] >= now: return times[0] elif times[1] >= now: return times[1] except NonExistentTimeError: # This datetime does not exist (the DST shift jumps over it) pass else: if previous_run_time or next_time >= now: return next_time previous_date = next_date
def generate_chart_interval_datetimes(start_datetime:dt.datetime,end_datetime:dt.datetime,interval_seconds:int): values = [] marketopen = get_market_opening_time(get_google_data('ZVZZT',interval_seconds,1)) marketclosed = get_market_closing_time(get_google_data('ZVZZT',interval_seconds,1)) start_datetime.combine(date=start_datetime.date(),time=marketopen) market_duration = dt.datetime.combine(dt.datetime.today(),marketclosed) - dt.datetime.combine(dt.datetime.today(),marketopen) input_days_difference = end_datetime.day - start_datetime.day market_trading_seconds_per_day = market_duration.total_seconds() input_trading_day_seconds = input_days_difference * market_trading_seconds_per_day input_hours_difference = end_datetime.hour - start_datetime.hour input_hours_seconds = input_hours_difference * 3600 input_minutes_difference = end_datetime.minute - start_datetime.minute input_minutes_seconds = input_minutes_difference * 60 input_seconds_difference = end_datetime.second - start_datetime.second total_seconds = input_trading_day_seconds + input_hours_seconds + input_minutes_seconds + input_seconds_difference total_intervals = total_seconds // interval_seconds print(total_intervals) for i in range(0,int(total_intervals)): amount_to_add = dt.timedelta(hours=marketopen.hour,minutes=marketopen.minute) + dt.timedelta(seconds=interval_seconds)*i basevalue = start_datetime + amount_to_add value = basevalue # advance to next day if value.time() > marketclosed: print("Advanced TO Next Day") value + dt.timedelta(days=1) value.combine(value.date(),marketopen) # in case its a saturday if value.weekday() == 5: value + dt.timedelta(days=2) value.combine(value.date(),marketopen) # in case its a sunday if value.weekday() == 6: value + dt.timedelta(days=1) value.combine(value.date(),marketopen) print(value.time()) print(marketclosed) print(value.time() > marketclosed) print(value.date()) print(value.date().weekday()) values.append(value) print(marketclosed) return values
def historical(self, start: datetime, end: datetime=None, include_today: bool=False): if isinstance(start, datetime): start = start.date() if isinstance(end, datetime): end = end.date() today = current_utc_date() end = end or today # Validate dates assert start <= end, "'start' date must <= 'end' date'!" self._validate_historical_date(start) self._validate_historical_date(end) # If start date is today, return only current BPI if start == today: current = self.bpi(self.currency).current() current['bpi'] = { str(today): current['bpi'][self.currency]['rate_float']} return current # Normal call for historical BPI response = self.get('bpi/historical/close.json', params={ 'currency': self.currency, 'start': start, 'end': end, }) # If end date is today, add current BPI if end == today and include_today: response['bpi'][str(today)] = ( self.rate(self.currency).current()) # Validate response historical_bpi = response['bpi'] for d in date_range(start, end): assert historical_bpi[str(d)], ( f'{d} is not present in BPI!') return response
def get_trips_from_to(from_code: str, to_code: str, when: datetime.datetime = None): """ Searches daily GTFS data (Pandas DataFrame) for trips :param when: Timestamp around which to search +- 1 hour :param from_code, to_code: Station code from GTFS data (different from GTFS id stored in db) :return: array of results """ when = when or datetime.datetime.now() date = when.date() df = get_or_create_daily_trips(date) stops_departure = df[df.stop_code == from_code] stops_arrival = df[df.stop_code == to_code] merge_stops = stops_departure.merge(stops_arrival, on="trip_id") daily_stops_from_to = merge_stops[merge_stops.stop_sequence_y > merge_stops.stop_sequence_x] time_since_midnight = 3600 * when.hour + 60 * when.minute + when.second start_seconds = time_since_midnight - 3600 end_seconds = time_since_midnight + 3600 delta_stops_from_to = daily_stops_from_to[(daily_stops_from_to.departure_time_x > start_seconds) & (daily_stops_from_to.departure_time_x < end_seconds)] delta_stops_from_to_sorted = delta_stops_from_to.sort_values('departure_time_x') results = [{ 'from': { 'stop_code': row.stop_code_x, 'stop_name': row.stop_name_x, 'departure_time': midnight_sec_to_time(row.departure_time_x) }, 'to': { 'stop_code': row.stop_code_y, 'stop_name': row.stop_name_y, 'departure_time': midnight_sec_to_time(row.departure_time_y) }, 'trip': { 'description': row.route_long_name_x, 'route_id': row.route_id_x, 'trip_id': row.trip_id, }, } for idx, row in delta_stops_from_to_sorted.iterrows()] logger.info('gtfs: get_trips_from_to: {}'.format(results)) return results
def parse_arrival(now: datetime, line_id: int, station_id: int, arrival: str) -> Arrival: """ Parse arrival time from a string of the form "hh:mm", "mm min.", ">>". Parameters ---------- now current time in Europe/Bucharest timezone, for calculating minutes until arrival for absolute timestamps line_id line ID station_id station ID arrival arrival string Returns ------- Parsed arrival time """ minutes_left = -1 # type: int real_time = False # type: bool estimate = parse_arrival.estimate_re.match(arrival) if estimate: minutes_left, real_time = int(estimate.group(1)), True arrival = arrival.strip('.') else: scheduled = parse_arrival.schedule_re.match(arrival) if scheduled: scheduled = time(hour=int(scheduled.group(1)), minute=int(scheduled.group(2))) scheduled = now.tzinfo.localize(datetime.combine(now.date(), scheduled)) if scheduled < now: scheduled = now.tzinfo.normalize(scheduled + timedelta(days=1)) minutes_left, real_time = int((scheduled - now).total_seconds()) // 60, False else: if parse_arrival.in_station_re.match(arrival): minutes_left, real_time = 0, True arrival = arrival.strip() return Arrival(line_id, station_id, arrival, minutes_left, real_time)
def report_user_time(self, project_id: int, user_id: int, duration: float, date: datetime, comment): project = self.project_service.get_project_by_id(project_id) if project is None: _raise_project_not_exist() user_project = project.project_users.filter( user_id == UserProject.user_id).first() if user_project is None: user_project = UserProject(project_id=project.project_id, user_id=user_id) report_date = date.date() user = user_project.user duration_timedelta = timedelta(seconds=duration) _validate_reported_amount_of_time( user, duration_timedelta, report_date) _validate_report_date(report_date) time_entry = self.project_service.report_user_time( project, user, duration, comment) return _create_time_entry_json(time_entry)
class Shift(object): @classmethod def from_datetime(cls, position, datetime): """ Create a shift from a datetime. @param position: a L{Values} container corresponding to the position the shift is for. @param datetime: a L{DateTime} during the shift. """ return cls( position = position, date = datetime.date(), name = position.shiftForTime(datetime.time()), ) def __init__(self, position, date, time=None, name=None): """ One or both of C{time} and C{name} are required. If both are provided, they must match (meaning C{time == name.value}). @param position: a L{Values} container corresponding to the position the shift is for. @param date: the L{Date} for the shift. @param time: the L{Time} for the shift. @param name: the L{ValueConstant} from the C{position} container corresponding to the time of the shift. """ if time is None: if name is None: raise ValueError("Both time and name may not be None.") else: time = name.value if name is None: name = position.lookupByValue(time) elif name.value != time: raise ValueError("time and name do not match: {0} != {1}".format(time, name)) self.position = position self.start = DateTime(year=date.year, month=date.month, day=date.day, hour=time.hour) self.name = name def __hash__(self): return hash((self.position, self.name)) def __eq__(self, other): return ( self.position == other.position and self.start == other.start ) def __lt__(self, other): return self.start < other.start def __str__(self): return "{self.start} {self.name.name}".format(self=self) @property def end(self): return (self.start.time() + TimeDelta(hours=self.position.length)) def next_shift(self): return self.__class__( position = self.position, date = self.start.date(), time = self.end, )
def _days_since(self, now: datetime.date, dt: datetime.datetime): return (now-dt.date()).days
def kuro_shift(d: datetime.datetime): if d.hour<3: return (d-datetime.timedelta(days=1)).date(), d.hour+24-3 else: return d.date(),d.hour-3
def _round_up_day(self, dt: datetime.datetime): return dt.date()+datetime.timedelta(days=1)
def _match_key(self, item: datetime) -> datetime: """Match the key without the time of the datetime""" for key in self.keys(): if key.date() == item.date(): return key return item # Create new key
def __contains__(self, item: datetime) -> bool: """Determine whether this dictionary contains the key""" for key in self.keys(): if key.date() == item.date(): return True return False
def __init__(self, when: datetime, op: str, params: SearchParams) -> None: super().__init__(params) self.when = when.date() self.op = op
def for_date(self, date_for: datetime): if isinstance(date_for, datetime): date_for = date_for.date() rate_dict = self.historical(start=date_for, end=date_for) rate = rate_dict[str(date_for)] return rate
def get_object(self, _, timestamp: datetime.datetime): return timestamp.date().isoformat()