def is_even_week(actual_date: datetime = datetime.now(), study_start_date: datetime = None): if study_start_date is None: study_start_date = date(datetime.now().year, 9, 1) weeks = actual_date.isocalendar()[1] - study_start_date.isocalendar( )[1] - 1 return not weeks & 1
def find_full_weeks_in_period(_start: datetime, _end: datetime) -> list: """ | This function takes two arguments start of period and end of period | It returns list of tuples (start_week, end_week, string = 'year/week number') """ def _find_weeks_cells(start: datetime, end: datetime) -> list: """ |This function takes two arguments start of period and and of period |It is used to find number of separate weeks in the provided timespan |It make 7 days (week) steps to find 'week cell' |'week cells' then are used in another function to find start and end | dates of the weeks """ _dates = [start] cur = start while True: cur = cur + timedelta(days=7) if cur >= end: break _dates.append(cur) if _dates[-1].isocalendar()[1] != end.isocalendar()[1]: _dates.append(end) return _dates if _end < _start: raise ValueError( f"end date {_end} should be later then start date: {_start}") if _start.isocalendar()[1] == _end.isocalendar()[1]: # the error is here return [( _start, _end + timedelta(seconds=86399), str(_start.year) + "/" + str(_start.isocalendar()[1]), )] cells = _find_weeks_cells(_start, _end) result = [] for cell in cells: w_start = cell - timedelta(days=cell.weekday()) w_end = w_start + timedelta(days=6) if w_start <= _start: w_start = _start if w_end >= _end: w_end = _end result.append(( w_start, w_end + timedelta(seconds=86399), str(w_start.year) + "/" + str(w_start.isocalendar()[1]), )) return result
def _find_best_spanning_ticket(start_date_time: datetime, last_date_time: datetime) -> Optional[Ticket]: delta = last_date_time - start_date_time if delta.days == 0 and start_date_time.day == last_date_time.day: return TICKETS['one_day'] for hour_constrained_ticket in HOUR_CONSTRAINED_TICKETS: if delta.days < (hour_constrained_ticket.validity_duration / 24): return hour_constrained_ticket _, start_date_time_week, _ = start_date_time.isocalendar() _, last_date_time_week, _ = last_date_time.isocalendar() if delta.days <= TICKETS[ 'one_week'].validity_duration and start_date_time_week == last_date_time_week: return TICKETS['one_week'] return None
def generate_week_plan(date: dt.datetime) -> str: day = partial(day_link, date, link_fmt="%A %Y-%m-%d") week = week_label(date) week_num = date.isocalendar()[1] year = date.year return utils.trim( f""" --- created: {dt.datetime.utcnow():%Y-%m-%dT%H:%M:%S}Z type: note/plan/week top_level: "#{week}" alias: ["{week}"] --- # {year} Week {week_num} **Quarter:** {quarter_link(date)} **Previous:** {week_link(date - dt.timedelta(days=7))} **Next:** {week_link(date + dt.timedelta(days=7))} ## Week Plan ### TODO ### Habits ## Action Plans - {day(0)} - {day(1)} - {day(2)} - {day(3)} - {day(4)} - {day(5)} - {day(6)} """ )
def get_datetime_prop(dt: datetime, month_anchor: bool, prop: str) -> int: if prop == "week": return dt.day // 7 + 1 if month_anchor else dt.isocalendar()[1] elif prop == "day": return dt.day - 1 if month_anchor else dt.weekday() elif prop == "month": return dt.month - 1 return getattr(dt, prop)
def get_current_building(date: datetime.datetime): _, week_number, day_number = date.isocalendar() if day_number not in [1, 3, 5]: return 0 order = [2, 3, 1, 4] return order[(order.index( (order[2:4][::-1] + order[0:2][::-1])[(week_number - 1) % 4]) + (day_number - 1) // 2) % 4]
def __init__(self, word: Word, user: User, date: datetime, score, search_count): self.word_id = word.id self.user_id = user.id self.year = date.year self.month = date.month self.day = date.day self.week = date.isocalendar()[1] self.day_of_week = date.isoweekday() self.score = score self.search_count = search_count
def reportGeneration(startDate: dt.datetime, endDate: dt.datetime, configDict: dict) -> None: """function that generate weekly Mis Report Args: startDate (dt.datetime): start date of weekly report endDate (dt.datetime): start date of weekly report configDict (dict): app configuration dictionary """ year = startDate.isocalendar()[0] week_number = startDate.isocalendar()[1] con_string = configDict['con_string_mis_warehouse'] #creating instance of each classes obj_dictMerger = ContextCreator(year, week_number, startDate, endDate) obj_fetchDerivedFrequency = FetchDerivedFrequency(con_string) obj_fetchDerivedVoltage = FetchDerivedVoltage(con_string) obj_fetchDerivedVDI = FetchDerivedVDI(con_string) derivedFrequencyDict = obj_fetchDerivedFrequency.fetchDerivedFrequency( startDate, endDate) derivedVoltageDict = obj_fetchDerivedVoltage.fetchDerivedVoltage( startDate, endDate) derivedVDIDict = obj_fetchDerivedVDI.fetchDerivedVDI(startDate) context = obj_dictMerger.contextCreator( derivedFrequencyDict['rows'], derivedFrequencyDict['weeklyFDI'], derivedVDIDict['VDIRows400Kv'], derivedVDIDict['VDIRows765Kv'], derivedVoltageDict['table1'], derivedVoltageDict['table2'], derivedVoltageDict['table3'], derivedVoltageDict['table4']) definedTemplatePath = configDict[ 'template_path'] + '\\freq_volt_profile_raw_template.docx' templateSavePath = configDict[ 'template_path'] + '\\07-- sept-2020_weekly-report.docx' doc = DocxTemplate(definedTemplatePath) doc.render(context) doc.save(templateSavePath)
def get_current_building(date: datetime.datetime) -> int: ''' Main function of schedule. Logic of the function affects on logic of notification Return number of current building, -1 otherwise ''' _, week_number, day_number = date.isocalendar() if day_number not in [1, 3, 5]: return -1 order = [3, 1, 4, 2] return order[(order.index( (order[2:4][::-1] + order[0:2][::-1])[(week_number - 1) % 4]) + (day_number - 1) // 2) % 4]
def get_current_interval(self, time: datetime): interval_setting = self.settings["randomization_interval"] if interval_setting == 0: return time.hour elif interval_setting == 1: return time.day elif interval_setting == 2: return time.isocalendar()[1] # week number elif interval_setting == 3: return time.month else: self.logger.error( "unknown color randomization interval: {}".format( interval_setting))
def get_date_week_even(dt: datetime): """ Возвращает 0 если неделя нечетная, и 1 если неделя четная """ if dt.month >= 9: september_1st = datetime(dt.year, 9, 1) else: september_1st = datetime(dt.year - 1, 9, 1) wk = dt.isocalendar()[1] september_1st_week = september_1st.isocalendar()[1] if dt.year == september_1st.year: return (wk - september_1st_week) % 2 else: return (52 - september_1st_week + wk) % 2
def _get_number_week(day_today: datetime) -> int: """Получение номера недели. Parameters ---------- day_today: datetime сегодняшняя дата Return ---------- number: int номер недели """ first_week = Config.get_weeks_info()["start_week"].isocalendar()[1] current_week = day_today.isocalendar()[1] number = current_week - first_week + 1 return number
def update_sales_summary(date_obj: datetime, qty: int, beer: str): """ This function updates the sales_summary dictionary. :param date_obj: a datetime of the date of the invoice order. :param qty: an integer representing number of bottle. :param beer: a string representing the beer. """ errorLogger.info("Updating the sales summary list.") # Calculate year sales sale_qty_year = get_value_by_key(sales_summary, SALES_PER_YEAR) if not sale_qty_year: sale_qty_year = 0 sale_qty_year = sale_qty_year + qty sales_summary.update({SALES_PER_YEAR: sale_qty_year}) # Calculate each month sales month = date_obj.strftime('%B') sale_qty_month = get_value_by_key(sales_summary, month) if not sale_qty_month: sales_summary.update({month: {}}) sale_qty_month = sales_summary[month] months.append(month) sale_beers_qty_month = get_value_by_key(sale_qty_month, beer) if beer not in sale_qty_month: sale_qty_month.update({beer: 0}) sale_beers_qty_month = sale_qty_month[beer] tmp_qty = sale_beers_qty_month + qty sale_qty_month.update({beer: tmp_qty}) sales_summary.update({month: sale_qty_month}) # Calculate each week sales # gets the week number from the date week_no = date_obj.isocalendar()[1] # formatting the week string week = SALES_PER_WEEK.format(wk=week_no) sale_qty_week = get_value_by_key(sales_summary, week) if not sale_qty_week: sales_summary.update({week: {}}) sale_qty_week = sales_summary[week] weeks.append(week) sale_beers_qty_week = get_value_by_key(sale_qty_week, beer) if beer not in sale_qty_week: sale_qty_week.update({beer: 0}) sale_beers_qty_week = sale_qty_week[beer] tmp_qty = sale_beers_qty_week + qty sale_qty_week.update({beer: tmp_qty}) sales_summary.update({week: sale_qty_week})
def _find_weeks_cells(start: datetime, end: datetime) -> list: """ |This function takes two arguments start of period and and of period |It is used to find number of separate weeks in the provided timespan |It make 7 days (week) steps to find 'week cell' |'week cells' then are used in another function to find start and end | dates of the weeks """ _dates = [start] cur = start while True: cur = cur + timedelta(days=7) if cur >= end: break _dates.append(cur) if _dates[-1].isocalendar()[1] != end.isocalendar()[1]: _dates.append(end) return _dates
def scheduled_for_message(when: datetime) -> str: today = datetime.now().date() at = when.strftime("%H:%M") if when.date() == today: label = "today" return "{} {}".format(label, at) tomorrow = today + timedelta(days=1) if when.date() == tomorrow: label = "tomorrow" return "{} {}".format(label, at) current_week = today.isocalendar()[1] if when.isocalendar()[1] == current_week: label = when.strftime("%A") return "{} {}".format(label, at) return when.strftime("%d.%m.%Y %H:%M")
def datetime_to_intervalstr(date: datetime.datetime, freq: Frequency) -> Optional[str]: if date is None: return None if freq == Frequency.DAILY: return f"{date.year}-{date.month:02d}-{date.day:02d}" if freq == Frequency.WEEKLY: # Note: weekyear may differ from actual year for week numbers 1,52,53. (weekyear, week, _) = date.isocalendar() return f"{weekyear}-W{week:02d}" if freq == Frequency.MONTHLY: return f"{date.year}-{date.month:02d}" if freq == Frequency.QUARTERLY: return f"{date.year}-Q{1 + (date.month-1)//3}" if freq == Frequency.YEARLY: return f"{date.year}" # Using isoformat if frequency is none of the listed instead of error. return date.isoformat()
def match_week(s: str, now: datetime) -> List[Dict[str, Any]]: groups = re.findall(R_WEEK, s) res = [] for group in groups: date_parts = {'match': group, 'date_parts': []} if 'ez' in group: y, w = now.isocalendar()[0:2] date_parts['date_parts'].extend([Year(y, 'week'), Week(w, 'week')]) elif 'jovo' in remove_accent(group): y, w = (now + timedelta(days=7)).isocalendar()[0:2] date_parts['date_parts'].extend([Year(y, 'week'), Week(w, 'week')]) elif 'mult' in remove_accent(group) or 'elozo' in remove_accent(group): y, w = (now - timedelta(days=7)).isocalendar()[0:2] date_parts['date_parts'].extend([Year(y, 'week'), Week(w, 'week')]) res.append(date_parts) return res
def get_year_week(date: dt) -> Tuple[int, int]: """ get_year_week [summary] Args: date (dt): [description] Returns: Tuple[int, int]: [description] """ week_num = date.isocalendar()[1] year = date.year if week_num == 1 and date.month == 12: year += 1 elif week_num == 53 and date.month == 1: year -= 1 # Year comes first so dataframe is sorted chronologically return (year, week_num)
def get_rank(cls, cur_time: datetime.datetime, prev_week: int = 1, re_build: bool = False) -> dict: """ 根据日期,返回日期所在的周(或者往前推几周)的排行字典,请调用此函数,有缓存 :param cur_time: :param prev_week:往前提前几周?默认是1,也就是上一周的排行,0就是取本周的排行 :param re_build:强制重新生成排行榜? :return:{t_id: {"rank": rank, "win": win},...} """ y, w, d = cur_time.isocalendar() # 年, 全年的第几周? 这天是星期几? key = "week_rank_{}_{}_{}".format(y, w, prev_week) res = simple_cache.get(key) if res is None or re_build: res = cls._get_rank(cur_time=cur_time, prev_week=prev_week, re_build=re_build) simple_cache.set(key=key, value=res, timeout=3600) return res
def get_schedule(self, office: str, week: datetime, selector: List[Dict]) -> List: session_id = self.__get_session_id() if not session_id: return [] headers = { 'authority': 'migri.vihta.com', 'accept': 'application/json, text/plain, */*', 'vihta-session': session_id, 'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 11_0_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.111 Safari/537.36', 'content-type': 'application/json;charset=UTF-8', 'origin': 'https://migri.vihta.com', 'sec-fetch-site': 'same-origin', 'sec-fetch-mode': 'cors', 'sec-fetch-dest': 'empty', 'referer': 'https://migri.vihta.com/public/migri/', 'accept-language': 'ru,en;q=0.9' } year = week.year calendar_week = week.isocalendar()[1] url = f'https://migri.vihta.com/public/migri/api/scheduling/offices/{office}/{year}/w{calendar_week}' print(f'Loading schedule for week {calendar_week}') mirgri_request = dict(serviceSelections=selector, extraServices=[]) response = self.__session.post(url, params=dict(start_hours=0, end_hours=24), headers=headers, data=json.dumps(mirgri_request)) if response.ok: try: data = response.json() return data['dailyTimesByOffice'] except: print(response.text) return [] else: print(f'Failed to load schedule: status code = {response.status_code}') return []
def week_label(date: dt.datetime) -> str: week_num = date.isocalendar()[1] return f"{date.year}W{week_num:02d}"
def get_iso_week(dt: datetime): year, week, day = dt.isocalendar() return year, week
def week_of_year(date: datetime) -> int: return date.isocalendar()[1]
def _format_token(self, dt: datetime, token: Optional[str]) -> Optional[str]: if token and token.startswith("[") and token.endswith("]"): return token[1:-1] if token == "YYYY": return self.locale.year_full(dt.year) if token == "YY": return self.locale.year_abbreviation(dt.year) if token == "MMMM": return self.locale.month_name(dt.month) if token == "MMM": return self.locale.month_abbreviation(dt.month) if token == "MM": return f"{dt.month:02d}" if token == "M": return f"{dt.month}" if token == "DDDD": return f"{dt.timetuple().tm_yday:03d}" if token == "DDD": return f"{dt.timetuple().tm_yday}" if token == "DD": return f"{dt.day:02d}" if token == "D": return f"{dt.day}" if token == "Do": return self.locale.ordinal_number(dt.day) if token == "dddd": return self.locale.day_name(dt.isoweekday()) if token == "ddd": return self.locale.day_abbreviation(dt.isoweekday()) if token == "d": return f"{dt.isoweekday()}" if token == "HH": return f"{dt.hour:02d}" if token == "H": return f"{dt.hour}" if token == "hh": return f"{dt.hour if 0 < dt.hour < 13 else abs(dt.hour - 12):02d}" if token == "h": return f"{dt.hour if 0 < dt.hour < 13 else abs(dt.hour - 12)}" if token == "mm": return f"{dt.minute:02d}" if token == "m": return f"{dt.minute}" if token == "ss": return f"{dt.second:02d}" if token == "s": return f"{dt.second}" if token == "SSSSSS": return f"{dt.microsecond:06d}" if token == "SSSSS": return f"{dt.microsecond // 10:05d}" if token == "SSSS": return f"{dt.microsecond // 100:04d}" if token == "SSS": return f"{dt.microsecond // 1000:03d}" if token == "SS": return f"{dt.microsecond // 10000:02d}" if token == "S": return f"{dt.microsecond // 100000}" if token == "X": return f"{dt.timestamp()}" if token == "x": return f"{dt.timestamp() * 1_000_000:.0f}" if token == "ZZZ": return dt.tzname() if token in ["ZZ", "Z"]: separator = ":" if token == "ZZ" else "" tz = dateutil_tz.tzutc() if dt.tzinfo is None else dt.tzinfo # `dt` must be aware object. Otherwise, this line will raise AttributeError # https://github.com/arrow-py/arrow/pull/883#discussion_r529866834 # datetime awareness: https://docs.python.org/3/library/datetime.html#aware-and-naive-objects total_minutes = int( cast(timedelta, tz.utcoffset(dt)).total_seconds() / 60) sign = "+" if total_minutes >= 0 else "-" total_minutes = abs(total_minutes) hour, minute = divmod(total_minutes, 60) return f"{sign}{hour:02d}{separator}{minute:02d}" if token in ("a", "A"): return self.locale.meridian(dt.hour, token) if token == "W": year, week, day = dt.isocalendar() return f"{year}-W{week:02d}-{day}"
def _is_tomorrow_price(ts: datetime, ref: datetime) -> bool: return any( map(lambda x: x[0] > x[1], zip(ts.isocalendar(), ref.isocalendar())))
def get_weekday_from_ts(ts: datetime) -> int: """ Returns the number of the weekday from a ts """ return ts.isocalendar()[2]
def get_week_from_ts(ts: datetime) -> int: """Returns the integer value of the week for the given time slot""" return ts.isocalendar()[1]
def get_value(self, dateval: datetime) -> int: return dateval.isocalendar()[1]
def _get_week_number(self, date: datetime) -> str: return str(date.isocalendar()[1])
def find_candidate_date(self, day1: datetime) -> datetime: """Find the next possible date starting from day1, only based on calendar, not lookimg at include/exclude days""" day1 = day1 week = day1.isocalendar()[1] weekday = day1.weekday() year = day1.year if self.__frequency in [ "weekly", "even-weeks", "odd-weeks", "every-n-weeks" ]: # Everything except montthly # convert to every-n-weeks if self.__frequency == "weekly": period = 1 first_week = 1 elif self.__frequency == "even-weeks": period = 2 first_week = 2 elif self.__frequency == "odd-weeks": period = 2 first_week = 1 else: period = self.__period first_week = self.__first_week offset = -1 if (week - first_week) % period == 0: # Collection this week for day_name in self.__collection_days: day_index = WEEKDAYS.index(day_name) if day_index >= weekday: # Collection still did not happen offset = day_index - weekday break if offset == -1: # look in following weeks in_weeks = period - (week - first_week) % period offset = (7 * in_weeks - weekday + WEEKDAYS.index(self.__collection_days[0])) return day1 + timedelta(days=offset) elif self.__frequency == "monthly": # Monthly for monthly_day_order_number in self.__monthly_day_order_numbers: candidate_date = nth_weekday_date( monthly_day_order_number, day1, WEEKDAYS.index(self.__collection_days[0]), ) # date is today or in the future -> we have the date if candidate_date.date() >= day1.date(): return candidate_date if day1.month == 12: next_collection_month = datetime(year + 1, 1, 1).astimezone() else: next_collection_month = datetime(year, day1.month + 1, 1).astimezone() return nth_weekday_date( self.__monthly_day_order_numbers[0], next_collection_month, WEEKDAYS.index(self.__collection_days[0]), ) elif self.__frequency == "annual": # Annual if self.__date is None: _LOGGER.error( "(%s) Please configure the date for annual collection frequency.", self.__name, ) return None conf_date = datetime.strptime(self.__date, "%m/%d") candidate_date = datetime(year, conf_date.month, conf_date.day).astimezone() if candidate_date.date() < day1.date(): candidate_date = datetime(year + 1, conf_date.month, conf_date.day).astimezone() return candidate_date elif self.__frequency == "group": if self.__entities is None: _LOGGER.error("(%s) Please add entities for the group.", self.__name) return None candidate_date = None for entity in self.__entities: d = self.hass.states.get(entity).attributes.get(ATTR_NEXT_DATE) if candidate_date is None or d.date() < candidate_date.date(): candidate_date = d return candidate_date else: _LOGGER.debug( f"({self.__name}) Unknown frequency {self.__frequency}") return None
def week_of_year(date: datetime) -> int: """Iso week number of a given date""" return date.isocalendar()[1]