# -*- coding: utf-8 -*- """ Created on Tue Jun 19 15:28:57 2018 @author: hanye """ import datetime def find_first_day_for_given_start_weekday(year, start_weekday): i = 0 while i<7: dayDi = datetime.date(year, 1, 1) + datetime.timedelta(days=i) if dayDi.weekday()==start_weekday: cal_day1D = dayDi - datetime.timedelta(days=1) break else: cal_day1D = None i += 1 return cal_day1D def cal_week_no_weekday(dayD, cal_year_day1D): if dayD<cal_year_day1D: print('dayD must greater or equal to cal_year_day1D!') return None else: cal_week_no = (dayD-cal_year_day1D).days//7 + 1 cal_weekday = (dayD-cal_year_day1D).days%7 + 1 return (cal_week_no, cal_weekday) def find_week_belongs_to(dayT, week_start_iso_weekday=1): if isinstance(dayT, datetime.datetime): dayD = datetime.date(dayT.year, dayT.month, dayT.day) elif isinstance(dayT, datetime.date): dayD = dayT else: print('Wrong type, input parameter must be instance of datetime.datetime ' 'or datetime.date!') return None calendar_tupe = dayD.isocalendar() param_iso_week_no = calendar_tupe[1] param_iso_weekday = calendar_tupe[2] param_iso_week_year = calendar_tupe[0] if isinstance(week_start_iso_weekday, int) and week_start_iso_weekday>0: if week_start_iso_weekday==1: # iso week, Mon is weekday 1, Sun is weekday 7 cal_week_no = param_iso_week_no cal_week_year = param_iso_week_year cal_weekday = param_iso_weekday return (cal_week_year, cal_week_no, cal_weekday) else: cal_day1D = find_first_day_for_given_start_weekday(dayT.year, week_start_iso_weekday) if dayD>=cal_day1D: cal_week_year = dayD.year cal_week_no, cal_weekday = cal_week_no_weekday(dayD, cal_day1D) return (cal_week_year, cal_week_no, cal_weekday) else: cal_week_year = dayD.year - 1 cal_day1D = find_first_day_for_given_start_weekday(cal_week_year, week_start_iso_weekday) cal_week_no, cal_weekday = cal_week_no_weekday(dayD, cal_day1D) return (cal_week_year, cal_week_no, cal_weekday) else: print('Wrong parameter, must be positive int!') return None def day_by_week_info(week_year, week_no, week_day, week_day_start=1): # find first weekday = week_day_start day1D = find_first_day_for_given_start_weekday(week_year, week_day_start) curr_dayD = day1D + datetime.timedelta(days=(week_no-1)*7+week_day-1) return curr_dayD def test_if_all_week_no_equals_one_on_first_day_in_any_year(): year = 2000 collector = [] while year<=2100: print(year) dayD = datetime.date(year, 1, 1) week_no = dayD.isocalendar()[1] if week_no!=1: print('Week number of the first day in the year %d is not ONE! It\'s %d' % (year, week_no)) collector.append(year) year += 1 return collector # test if __name__=='__main__': i = 1 dayT = datetime.date(2015, 1, 1) dayT1 = datetime.datetime(2015, 1, 1) while dayT1<datetime.datetime(2017,1,31): r = find_week_belongs_to(dayT1) r2 = find_week_belongs_to(dayT1, week_start_iso_weekday=2) print('%s, when week starts from 1: %s; when week starts from 2:%s' %(dayT1, r, r2)) dayT1 += datetime.timedelta(days=i) print('%s is week_year %d, week_no %d, and week_day %d ' 'when week starts from weekday %d,' % (datetime.date(2016, 12, 24), 2016, 47, 3, 2), 'can be restored by function day_by_week_info(%d, %d, %d, %d): %s' % (2016, 47, 3, 2, day_by_week_info(2016, 47, 3, 2)))