odoo 11 / Python 3: How to find expiry date of subscription if some weekdays are excluded












4















I am working on Subscription Management system. I have issue calculating Subscription Expiry Date. The scenario is as follows,
If a person subscribe for 1 month say 1/11/2018 to 30/11/2018 [DD/MM/YYYY] total 30 days but he want to exclude Friday & Saturday from each week of 30 days. So how should I calculate the Expiry Date?





Logic is : Say End Date = Expiry Date then find Fri/Sat from 1/11/2018 to 30/11/2018 which comes out 5 Fri & 4 Sat = 9 days. Add to Expiry Date which will be 09/12/2018. Now search Fur & Sat between End Date & Expiry Date which comes out 1 Fri & 2 Sat = 3 days. Now End Date = Expiry Date and Expiry Date + 3 Days = 12/12/2018. Search between End Date & Expiry Date for Fri & Sat which is 0 so the Expiry Date is 12/12/2018 return value <<





Following code does this but method returns 09/12/2018 instead 12/12/2018. What is wrong in this??



@api.one
def get_expiry_date(self, start, end, day_selection):
print("i am in 2nd", start, end, day_selection)
dayformat = '%Y-%m-%d'
current_date = datetime.now().date()
if start:
start = datetime.strptime(str(start), dayformat).date()
if end:
end = datetime.strptime(str(end), dayformat).date()
if day_selection:
selected_days = day_selection
if start < current_date:
start = datetime.strptime(str(start), dayformat).date()
weekdays = self.weekday_count(start,end)
print("days for start and end date",start,end, day_selection)
adddays = 0
if weekdays:
for i in range(len(day_selection)):
for item in weekdays[0]:
weekdays_dict = item
print("dict", type(weekdays), type(weekdays[0]), weekdays_dict)
print("compare", selected_days[i], weekdays_dict, selected_days[i] == weekdays_dict)
if selected_days[i] == item:
adddays = adddays + weekdays[0].get(item)
new_start = end
end = datetime.strptime(str(end), dayformat).date() + timedelta(days=adddays)
start = new_start
print("New Expiry Date", start, end, adddays)
if adddays > 0:
self.get_expiry_date(start, end, day_selection)
print("type of end is ", type(end))
print("selected days are", selected_days[i],weekdays[0], weekdays[0].get(item), adddays)
print("last returned values is",end)


return end










share|improve this question



























    4















    I am working on Subscription Management system. I have issue calculating Subscription Expiry Date. The scenario is as follows,
    If a person subscribe for 1 month say 1/11/2018 to 30/11/2018 [DD/MM/YYYY] total 30 days but he want to exclude Friday & Saturday from each week of 30 days. So how should I calculate the Expiry Date?





    Logic is : Say End Date = Expiry Date then find Fri/Sat from 1/11/2018 to 30/11/2018 which comes out 5 Fri & 4 Sat = 9 days. Add to Expiry Date which will be 09/12/2018. Now search Fur & Sat between End Date & Expiry Date which comes out 1 Fri & 2 Sat = 3 days. Now End Date = Expiry Date and Expiry Date + 3 Days = 12/12/2018. Search between End Date & Expiry Date for Fri & Sat which is 0 so the Expiry Date is 12/12/2018 return value <<





    Following code does this but method returns 09/12/2018 instead 12/12/2018. What is wrong in this??



    @api.one
    def get_expiry_date(self, start, end, day_selection):
    print("i am in 2nd", start, end, day_selection)
    dayformat = '%Y-%m-%d'
    current_date = datetime.now().date()
    if start:
    start = datetime.strptime(str(start), dayformat).date()
    if end:
    end = datetime.strptime(str(end), dayformat).date()
    if day_selection:
    selected_days = day_selection
    if start < current_date:
    start = datetime.strptime(str(start), dayformat).date()
    weekdays = self.weekday_count(start,end)
    print("days for start and end date",start,end, day_selection)
    adddays = 0
    if weekdays:
    for i in range(len(day_selection)):
    for item in weekdays[0]:
    weekdays_dict = item
    print("dict", type(weekdays), type(weekdays[0]), weekdays_dict)
    print("compare", selected_days[i], weekdays_dict, selected_days[i] == weekdays_dict)
    if selected_days[i] == item:
    adddays = adddays + weekdays[0].get(item)
    new_start = end
    end = datetime.strptime(str(end), dayformat).date() + timedelta(days=adddays)
    start = new_start
    print("New Expiry Date", start, end, adddays)
    if adddays > 0:
    self.get_expiry_date(start, end, day_selection)
    print("type of end is ", type(end))
    print("selected days are", selected_days[i],weekdays[0], weekdays[0].get(item), adddays)
    print("last returned values is",end)


    return end










    share|improve this question

























      4












      4








      4


      1






      I am working on Subscription Management system. I have issue calculating Subscription Expiry Date. The scenario is as follows,
      If a person subscribe for 1 month say 1/11/2018 to 30/11/2018 [DD/MM/YYYY] total 30 days but he want to exclude Friday & Saturday from each week of 30 days. So how should I calculate the Expiry Date?





      Logic is : Say End Date = Expiry Date then find Fri/Sat from 1/11/2018 to 30/11/2018 which comes out 5 Fri & 4 Sat = 9 days. Add to Expiry Date which will be 09/12/2018. Now search Fur & Sat between End Date & Expiry Date which comes out 1 Fri & 2 Sat = 3 days. Now End Date = Expiry Date and Expiry Date + 3 Days = 12/12/2018. Search between End Date & Expiry Date for Fri & Sat which is 0 so the Expiry Date is 12/12/2018 return value <<





      Following code does this but method returns 09/12/2018 instead 12/12/2018. What is wrong in this??



      @api.one
      def get_expiry_date(self, start, end, day_selection):
      print("i am in 2nd", start, end, day_selection)
      dayformat = '%Y-%m-%d'
      current_date = datetime.now().date()
      if start:
      start = datetime.strptime(str(start), dayformat).date()
      if end:
      end = datetime.strptime(str(end), dayformat).date()
      if day_selection:
      selected_days = day_selection
      if start < current_date:
      start = datetime.strptime(str(start), dayformat).date()
      weekdays = self.weekday_count(start,end)
      print("days for start and end date",start,end, day_selection)
      adddays = 0
      if weekdays:
      for i in range(len(day_selection)):
      for item in weekdays[0]:
      weekdays_dict = item
      print("dict", type(weekdays), type(weekdays[0]), weekdays_dict)
      print("compare", selected_days[i], weekdays_dict, selected_days[i] == weekdays_dict)
      if selected_days[i] == item:
      adddays = adddays + weekdays[0].get(item)
      new_start = end
      end = datetime.strptime(str(end), dayformat).date() + timedelta(days=adddays)
      start = new_start
      print("New Expiry Date", start, end, adddays)
      if adddays > 0:
      self.get_expiry_date(start, end, day_selection)
      print("type of end is ", type(end))
      print("selected days are", selected_days[i],weekdays[0], weekdays[0].get(item), adddays)
      print("last returned values is",end)


      return end










      share|improve this question














      I am working on Subscription Management system. I have issue calculating Subscription Expiry Date. The scenario is as follows,
      If a person subscribe for 1 month say 1/11/2018 to 30/11/2018 [DD/MM/YYYY] total 30 days but he want to exclude Friday & Saturday from each week of 30 days. So how should I calculate the Expiry Date?





      Logic is : Say End Date = Expiry Date then find Fri/Sat from 1/11/2018 to 30/11/2018 which comes out 5 Fri & 4 Sat = 9 days. Add to Expiry Date which will be 09/12/2018. Now search Fur & Sat between End Date & Expiry Date which comes out 1 Fri & 2 Sat = 3 days. Now End Date = Expiry Date and Expiry Date + 3 Days = 12/12/2018. Search between End Date & Expiry Date for Fri & Sat which is 0 so the Expiry Date is 12/12/2018 return value <<





      Following code does this but method returns 09/12/2018 instead 12/12/2018. What is wrong in this??



      @api.one
      def get_expiry_date(self, start, end, day_selection):
      print("i am in 2nd", start, end, day_selection)
      dayformat = '%Y-%m-%d'
      current_date = datetime.now().date()
      if start:
      start = datetime.strptime(str(start), dayformat).date()
      if end:
      end = datetime.strptime(str(end), dayformat).date()
      if day_selection:
      selected_days = day_selection
      if start < current_date:
      start = datetime.strptime(str(start), dayformat).date()
      weekdays = self.weekday_count(start,end)
      print("days for start and end date",start,end, day_selection)
      adddays = 0
      if weekdays:
      for i in range(len(day_selection)):
      for item in weekdays[0]:
      weekdays_dict = item
      print("dict", type(weekdays), type(weekdays[0]), weekdays_dict)
      print("compare", selected_days[i], weekdays_dict, selected_days[i] == weekdays_dict)
      if selected_days[i] == item:
      adddays = adddays + weekdays[0].get(item)
      new_start = end
      end = datetime.strptime(str(end), dayformat).date() + timedelta(days=adddays)
      start = new_start
      print("New Expiry Date", start, end, adddays)
      if adddays > 0:
      self.get_expiry_date(start, end, day_selection)
      print("type of end is ", type(end))
      print("selected days are", selected_days[i],weekdays[0], weekdays[0].get(item), adddays)
      print("last returned values is",end)


      return end







      python-3.x date recursion odoo






      share|improve this question













      share|improve this question











      share|improve this question




      share|improve this question










      asked Nov 22 '18 at 8:53









      JameelJameel

      234




      234
























          2 Answers
          2






          active

          oldest

          votes


















          1














          In your question, there is no definition of day_selection nor weekday_count thus hard to see what is going on. Probably the issue is with recursion, which is not necessary.



          If day_selection is defined as the days selected to exclude (list of strftime('%a'), like ['Mon', 'Tue']), then:



          from datetime import datetime, timedelta

          def get_expiry_date(start, end, day_selection):
          dayformat = '%Y-%m-%d'
          weekdays= {}
          start = datetime.strptime(str(start), dayformat).date()
          end = datetime.strptime(str(end), dayformat).date()
          # Count weekdays
          for i in range((end - start).days+1):
          weekday = (start + timedelta(i)).strftime('%a')
          weekdays[weekday] = 1 + weekdays.setdefault(weekday, 0)
          # Count subscription days to add
          sub_days_to_add = 0
          for selected in day_selection:
          sub_days_to_add += weekdays.setdefault(selected, 0)
          # Count calender days to add
          cal_days_extension = 0
          while sub_days_to_add > 0:
          if (end + timedelta(days=cal_days_extension + 1)).strftime('%a') not in day_selection:
          sub_days_to_add -= 1
          cal_days_extension += 1
          # Add to end day
          return end + timedelta(days=cal_days_extension)


          Tests:



          print (get_expiry_date('2018-11-01', '2018-11-30', ['Fri', 'Sat']))
          # ---> 2018-12-12
          print (get_expiry_date('2018-11-01', '2018-11-30', ))
          # ---> 2018-11-30


          Also it would be safer to use from odoo.tools import DEFAULT_SERVER_DATE_FORMAT than dayformat = '%Y-%m-%d'. And for parameters like start & end, if they are mandatory, can make these fields required in Odoo.






          share|improve this answer
























          • Awesome solution! Worked like charm. Thank you very much. Yes you are right day_selection is actually the same what you mentioned >> if self.ex_sunday: day_selection.append('Sun') << and weekday_count for counting day & number of times they appear in given date range.

            – Jameel
            Nov 23 '18 at 12:48





















          1














          The logic that you are trying to do is hard



          From what I understand you are running a subcription system
          based on number of days not dates so in order to compute the
          end date you just need this:




          1. start date (ex: 01/11/2018)

          2. number of days (ex: 30 days)

          3. excluded days (ex: Friday, Saturday)


          # day are like this
          # Fri
          # Sat
          # Sun
          # Mon
          # Tue
          # Wed
          # Thu

          # start day
          def get_expiry_date(start_date, number_of_days, excluded_days = None):
          """ compute end date of subcription period """
          if excluded_days is None:
          excluded_days =
          # check params
          start_date = str(start_date)
          if number_of_days < 1:
          raise exception.UserError(_('Number of days should be > 0!!')) # import the translate "_" method
          if len(excluded_days) > 5:
          raise exception.UserError(_('To much excluded days!!')) # import the translate "_" method

          date_format = '%Y-%m-%d'
          end_date = datetime.strptime(start_date, date_format)

          # compute end date
          # keeping adding one day until you finish your days
          add_one_day = timedelta(days=1)
          while number_of_days > 1:
          end_date += add_one_day
          if end_date.strftime('%a') not in excluded_days:
          # day is not excluded compute it
          number_of_days += -1

          return end_date.strftime(date_format)


          And this a test value that you can checkout:



                  print get_expiry_date('2018-11-01', 30, ['Fri', 'Sat'])  # 2018-12-12
          print get_expiry_date('2018-11-01', 30, ['Fri']) # 2018-12-05
          print get_expiry_date('2018-11-01', 30, ) # 2018-11-30
          print get_expiry_date('2018-11-01', 90, ) # 2019-01-29
          print get_expiry_date('2018-11-01', 30, ['Mon', 'Thu']) # 2018-12-11


          If you have all ready a running system you can use this:



          def get_expiry_date(start_date, end_date, excluded_days = None):
          if excluded_days is None:
          excluded_days =
          start_date = str(start_date)
          end_date = str(end_date)
          date_format = '%Y-%m-%d'
          # compute number of days
          number_of_days = (datetime.strptime(end_date, date_format) - datetime.strptime(start_date, date_format)).days
          expiry_date = datetime.strptime(start_date, date_format)

          if len(excluded_days) > 5:
          raise Exception('To much excluded days!!')

          # keeping adding one day until you finish your days
          one_day = timedelta(days=1)
          while number_of_days > 0:
          expiry_date += one_day
          # if day is not excluded reduce the number of left days
          if expiry_date.strftime('%a') not in excluded_days:
          number_of_days += -1

          return expiry_date.strftime(date_format)

          print get_expiry_date('2018-11-01', '2018-11-30', ['Fri', 'Sat']) # 2018-12-12





          share|improve this answer


























          • It also works as you mentioned scenario of number of days. I will keep in mind for this change. Thanks a lot for your precious time and efforts. Support means a lot!

            – Jameel
            Nov 23 '18 at 12:53











          • I'm curious why did you remove acceptance is the calcutation wrong?

            – EasyOdoo
            Nov 24 '18 at 5:30











          • The calculations are correct but actually solution of @mingtwo_h9 is best suited for me so when I accepted that your acceptance is removed. I think only 1 solution is accepted. Basically I would prefer both solutions as accepted.

            – Jameel
            Nov 25 '18 at 10:23











          • The funny thing he is doing the same thing that i did but with very complicated code. It's okay

            – EasyOdoo
            Nov 25 '18 at 19:39











          • The funny thing he is doing the same thing that i did but with very complicated code. It's okay

            – EasyOdoo
            Nov 25 '18 at 19:39











          Your Answer






          StackExchange.ifUsing("editor", function () {
          StackExchange.using("externalEditor", function () {
          StackExchange.using("snippets", function () {
          StackExchange.snippets.init();
          });
          });
          }, "code-snippets");

          StackExchange.ready(function() {
          var channelOptions = {
          tags: "".split(" "),
          id: "1"
          };
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function() {
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled) {
          StackExchange.using("snippets", function() {
          createEditor();
          });
          }
          else {
          createEditor();
          }
          });

          function createEditor() {
          StackExchange.prepareEditor({
          heartbeatType: 'answer',
          autoActivateHeartbeat: false,
          convertImagesToLinks: true,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: 10,
          bindNavPrevention: true,
          postfix: "",
          imageUploader: {
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          },
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          });


          }
          });














          draft saved

          draft discarded


















          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53427062%2fodoo-11-python-3-how-to-find-expiry-date-of-subscription-if-some-weekdays-are%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown

























          2 Answers
          2






          active

          oldest

          votes








          2 Answers
          2






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes









          1














          In your question, there is no definition of day_selection nor weekday_count thus hard to see what is going on. Probably the issue is with recursion, which is not necessary.



          If day_selection is defined as the days selected to exclude (list of strftime('%a'), like ['Mon', 'Tue']), then:



          from datetime import datetime, timedelta

          def get_expiry_date(start, end, day_selection):
          dayformat = '%Y-%m-%d'
          weekdays= {}
          start = datetime.strptime(str(start), dayformat).date()
          end = datetime.strptime(str(end), dayformat).date()
          # Count weekdays
          for i in range((end - start).days+1):
          weekday = (start + timedelta(i)).strftime('%a')
          weekdays[weekday] = 1 + weekdays.setdefault(weekday, 0)
          # Count subscription days to add
          sub_days_to_add = 0
          for selected in day_selection:
          sub_days_to_add += weekdays.setdefault(selected, 0)
          # Count calender days to add
          cal_days_extension = 0
          while sub_days_to_add > 0:
          if (end + timedelta(days=cal_days_extension + 1)).strftime('%a') not in day_selection:
          sub_days_to_add -= 1
          cal_days_extension += 1
          # Add to end day
          return end + timedelta(days=cal_days_extension)


          Tests:



          print (get_expiry_date('2018-11-01', '2018-11-30', ['Fri', 'Sat']))
          # ---> 2018-12-12
          print (get_expiry_date('2018-11-01', '2018-11-30', ))
          # ---> 2018-11-30


          Also it would be safer to use from odoo.tools import DEFAULT_SERVER_DATE_FORMAT than dayformat = '%Y-%m-%d'. And for parameters like start & end, if they are mandatory, can make these fields required in Odoo.






          share|improve this answer
























          • Awesome solution! Worked like charm. Thank you very much. Yes you are right day_selection is actually the same what you mentioned >> if self.ex_sunday: day_selection.append('Sun') << and weekday_count for counting day & number of times they appear in given date range.

            – Jameel
            Nov 23 '18 at 12:48


















          1














          In your question, there is no definition of day_selection nor weekday_count thus hard to see what is going on. Probably the issue is with recursion, which is not necessary.



          If day_selection is defined as the days selected to exclude (list of strftime('%a'), like ['Mon', 'Tue']), then:



          from datetime import datetime, timedelta

          def get_expiry_date(start, end, day_selection):
          dayformat = '%Y-%m-%d'
          weekdays= {}
          start = datetime.strptime(str(start), dayformat).date()
          end = datetime.strptime(str(end), dayformat).date()
          # Count weekdays
          for i in range((end - start).days+1):
          weekday = (start + timedelta(i)).strftime('%a')
          weekdays[weekday] = 1 + weekdays.setdefault(weekday, 0)
          # Count subscription days to add
          sub_days_to_add = 0
          for selected in day_selection:
          sub_days_to_add += weekdays.setdefault(selected, 0)
          # Count calender days to add
          cal_days_extension = 0
          while sub_days_to_add > 0:
          if (end + timedelta(days=cal_days_extension + 1)).strftime('%a') not in day_selection:
          sub_days_to_add -= 1
          cal_days_extension += 1
          # Add to end day
          return end + timedelta(days=cal_days_extension)


          Tests:



          print (get_expiry_date('2018-11-01', '2018-11-30', ['Fri', 'Sat']))
          # ---> 2018-12-12
          print (get_expiry_date('2018-11-01', '2018-11-30', ))
          # ---> 2018-11-30


          Also it would be safer to use from odoo.tools import DEFAULT_SERVER_DATE_FORMAT than dayformat = '%Y-%m-%d'. And for parameters like start & end, if they are mandatory, can make these fields required in Odoo.






          share|improve this answer
























          • Awesome solution! Worked like charm. Thank you very much. Yes you are right day_selection is actually the same what you mentioned >> if self.ex_sunday: day_selection.append('Sun') << and weekday_count for counting day & number of times they appear in given date range.

            – Jameel
            Nov 23 '18 at 12:48
















          1












          1








          1







          In your question, there is no definition of day_selection nor weekday_count thus hard to see what is going on. Probably the issue is with recursion, which is not necessary.



          If day_selection is defined as the days selected to exclude (list of strftime('%a'), like ['Mon', 'Tue']), then:



          from datetime import datetime, timedelta

          def get_expiry_date(start, end, day_selection):
          dayformat = '%Y-%m-%d'
          weekdays= {}
          start = datetime.strptime(str(start), dayformat).date()
          end = datetime.strptime(str(end), dayformat).date()
          # Count weekdays
          for i in range((end - start).days+1):
          weekday = (start + timedelta(i)).strftime('%a')
          weekdays[weekday] = 1 + weekdays.setdefault(weekday, 0)
          # Count subscription days to add
          sub_days_to_add = 0
          for selected in day_selection:
          sub_days_to_add += weekdays.setdefault(selected, 0)
          # Count calender days to add
          cal_days_extension = 0
          while sub_days_to_add > 0:
          if (end + timedelta(days=cal_days_extension + 1)).strftime('%a') not in day_selection:
          sub_days_to_add -= 1
          cal_days_extension += 1
          # Add to end day
          return end + timedelta(days=cal_days_extension)


          Tests:



          print (get_expiry_date('2018-11-01', '2018-11-30', ['Fri', 'Sat']))
          # ---> 2018-12-12
          print (get_expiry_date('2018-11-01', '2018-11-30', ))
          # ---> 2018-11-30


          Also it would be safer to use from odoo.tools import DEFAULT_SERVER_DATE_FORMAT than dayformat = '%Y-%m-%d'. And for parameters like start & end, if they are mandatory, can make these fields required in Odoo.






          share|improve this answer













          In your question, there is no definition of day_selection nor weekday_count thus hard to see what is going on. Probably the issue is with recursion, which is not necessary.



          If day_selection is defined as the days selected to exclude (list of strftime('%a'), like ['Mon', 'Tue']), then:



          from datetime import datetime, timedelta

          def get_expiry_date(start, end, day_selection):
          dayformat = '%Y-%m-%d'
          weekdays= {}
          start = datetime.strptime(str(start), dayformat).date()
          end = datetime.strptime(str(end), dayformat).date()
          # Count weekdays
          for i in range((end - start).days+1):
          weekday = (start + timedelta(i)).strftime('%a')
          weekdays[weekday] = 1 + weekdays.setdefault(weekday, 0)
          # Count subscription days to add
          sub_days_to_add = 0
          for selected in day_selection:
          sub_days_to_add += weekdays.setdefault(selected, 0)
          # Count calender days to add
          cal_days_extension = 0
          while sub_days_to_add > 0:
          if (end + timedelta(days=cal_days_extension + 1)).strftime('%a') not in day_selection:
          sub_days_to_add -= 1
          cal_days_extension += 1
          # Add to end day
          return end + timedelta(days=cal_days_extension)


          Tests:



          print (get_expiry_date('2018-11-01', '2018-11-30', ['Fri', 'Sat']))
          # ---> 2018-12-12
          print (get_expiry_date('2018-11-01', '2018-11-30', ))
          # ---> 2018-11-30


          Also it would be safer to use from odoo.tools import DEFAULT_SERVER_DATE_FORMAT than dayformat = '%Y-%m-%d'. And for parameters like start & end, if they are mandatory, can make these fields required in Odoo.







          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered Nov 22 '18 at 18:31









          mingtwo_h9mingtwo_h9

          963




          963













          • Awesome solution! Worked like charm. Thank you very much. Yes you are right day_selection is actually the same what you mentioned >> if self.ex_sunday: day_selection.append('Sun') << and weekday_count for counting day & number of times they appear in given date range.

            – Jameel
            Nov 23 '18 at 12:48





















          • Awesome solution! Worked like charm. Thank you very much. Yes you are right day_selection is actually the same what you mentioned >> if self.ex_sunday: day_selection.append('Sun') << and weekday_count for counting day & number of times they appear in given date range.

            – Jameel
            Nov 23 '18 at 12:48



















          Awesome solution! Worked like charm. Thank you very much. Yes you are right day_selection is actually the same what you mentioned >> if self.ex_sunday: day_selection.append('Sun') << and weekday_count for counting day & number of times they appear in given date range.

          – Jameel
          Nov 23 '18 at 12:48







          Awesome solution! Worked like charm. Thank you very much. Yes you are right day_selection is actually the same what you mentioned >> if self.ex_sunday: day_selection.append('Sun') << and weekday_count for counting day & number of times they appear in given date range.

          – Jameel
          Nov 23 '18 at 12:48















          1














          The logic that you are trying to do is hard



          From what I understand you are running a subcription system
          based on number of days not dates so in order to compute the
          end date you just need this:




          1. start date (ex: 01/11/2018)

          2. number of days (ex: 30 days)

          3. excluded days (ex: Friday, Saturday)


          # day are like this
          # Fri
          # Sat
          # Sun
          # Mon
          # Tue
          # Wed
          # Thu

          # start day
          def get_expiry_date(start_date, number_of_days, excluded_days = None):
          """ compute end date of subcription period """
          if excluded_days is None:
          excluded_days =
          # check params
          start_date = str(start_date)
          if number_of_days < 1:
          raise exception.UserError(_('Number of days should be > 0!!')) # import the translate "_" method
          if len(excluded_days) > 5:
          raise exception.UserError(_('To much excluded days!!')) # import the translate "_" method

          date_format = '%Y-%m-%d'
          end_date = datetime.strptime(start_date, date_format)

          # compute end date
          # keeping adding one day until you finish your days
          add_one_day = timedelta(days=1)
          while number_of_days > 1:
          end_date += add_one_day
          if end_date.strftime('%a') not in excluded_days:
          # day is not excluded compute it
          number_of_days += -1

          return end_date.strftime(date_format)


          And this a test value that you can checkout:



                  print get_expiry_date('2018-11-01', 30, ['Fri', 'Sat'])  # 2018-12-12
          print get_expiry_date('2018-11-01', 30, ['Fri']) # 2018-12-05
          print get_expiry_date('2018-11-01', 30, ) # 2018-11-30
          print get_expiry_date('2018-11-01', 90, ) # 2019-01-29
          print get_expiry_date('2018-11-01', 30, ['Mon', 'Thu']) # 2018-12-11


          If you have all ready a running system you can use this:



          def get_expiry_date(start_date, end_date, excluded_days = None):
          if excluded_days is None:
          excluded_days =
          start_date = str(start_date)
          end_date = str(end_date)
          date_format = '%Y-%m-%d'
          # compute number of days
          number_of_days = (datetime.strptime(end_date, date_format) - datetime.strptime(start_date, date_format)).days
          expiry_date = datetime.strptime(start_date, date_format)

          if len(excluded_days) > 5:
          raise Exception('To much excluded days!!')

          # keeping adding one day until you finish your days
          one_day = timedelta(days=1)
          while number_of_days > 0:
          expiry_date += one_day
          # if day is not excluded reduce the number of left days
          if expiry_date.strftime('%a') not in excluded_days:
          number_of_days += -1

          return expiry_date.strftime(date_format)

          print get_expiry_date('2018-11-01', '2018-11-30', ['Fri', 'Sat']) # 2018-12-12





          share|improve this answer


























          • It also works as you mentioned scenario of number of days. I will keep in mind for this change. Thanks a lot for your precious time and efforts. Support means a lot!

            – Jameel
            Nov 23 '18 at 12:53











          • I'm curious why did you remove acceptance is the calcutation wrong?

            – EasyOdoo
            Nov 24 '18 at 5:30











          • The calculations are correct but actually solution of @mingtwo_h9 is best suited for me so when I accepted that your acceptance is removed. I think only 1 solution is accepted. Basically I would prefer both solutions as accepted.

            – Jameel
            Nov 25 '18 at 10:23











          • The funny thing he is doing the same thing that i did but with very complicated code. It's okay

            – EasyOdoo
            Nov 25 '18 at 19:39











          • The funny thing he is doing the same thing that i did but with very complicated code. It's okay

            – EasyOdoo
            Nov 25 '18 at 19:39
















          1














          The logic that you are trying to do is hard



          From what I understand you are running a subcription system
          based on number of days not dates so in order to compute the
          end date you just need this:




          1. start date (ex: 01/11/2018)

          2. number of days (ex: 30 days)

          3. excluded days (ex: Friday, Saturday)


          # day are like this
          # Fri
          # Sat
          # Sun
          # Mon
          # Tue
          # Wed
          # Thu

          # start day
          def get_expiry_date(start_date, number_of_days, excluded_days = None):
          """ compute end date of subcription period """
          if excluded_days is None:
          excluded_days =
          # check params
          start_date = str(start_date)
          if number_of_days < 1:
          raise exception.UserError(_('Number of days should be > 0!!')) # import the translate "_" method
          if len(excluded_days) > 5:
          raise exception.UserError(_('To much excluded days!!')) # import the translate "_" method

          date_format = '%Y-%m-%d'
          end_date = datetime.strptime(start_date, date_format)

          # compute end date
          # keeping adding one day until you finish your days
          add_one_day = timedelta(days=1)
          while number_of_days > 1:
          end_date += add_one_day
          if end_date.strftime('%a') not in excluded_days:
          # day is not excluded compute it
          number_of_days += -1

          return end_date.strftime(date_format)


          And this a test value that you can checkout:



                  print get_expiry_date('2018-11-01', 30, ['Fri', 'Sat'])  # 2018-12-12
          print get_expiry_date('2018-11-01', 30, ['Fri']) # 2018-12-05
          print get_expiry_date('2018-11-01', 30, ) # 2018-11-30
          print get_expiry_date('2018-11-01', 90, ) # 2019-01-29
          print get_expiry_date('2018-11-01', 30, ['Mon', 'Thu']) # 2018-12-11


          If you have all ready a running system you can use this:



          def get_expiry_date(start_date, end_date, excluded_days = None):
          if excluded_days is None:
          excluded_days =
          start_date = str(start_date)
          end_date = str(end_date)
          date_format = '%Y-%m-%d'
          # compute number of days
          number_of_days = (datetime.strptime(end_date, date_format) - datetime.strptime(start_date, date_format)).days
          expiry_date = datetime.strptime(start_date, date_format)

          if len(excluded_days) > 5:
          raise Exception('To much excluded days!!')

          # keeping adding one day until you finish your days
          one_day = timedelta(days=1)
          while number_of_days > 0:
          expiry_date += one_day
          # if day is not excluded reduce the number of left days
          if expiry_date.strftime('%a') not in excluded_days:
          number_of_days += -1

          return expiry_date.strftime(date_format)

          print get_expiry_date('2018-11-01', '2018-11-30', ['Fri', 'Sat']) # 2018-12-12





          share|improve this answer


























          • It also works as you mentioned scenario of number of days. I will keep in mind for this change. Thanks a lot for your precious time and efforts. Support means a lot!

            – Jameel
            Nov 23 '18 at 12:53











          • I'm curious why did you remove acceptance is the calcutation wrong?

            – EasyOdoo
            Nov 24 '18 at 5:30











          • The calculations are correct but actually solution of @mingtwo_h9 is best suited for me so when I accepted that your acceptance is removed. I think only 1 solution is accepted. Basically I would prefer both solutions as accepted.

            – Jameel
            Nov 25 '18 at 10:23











          • The funny thing he is doing the same thing that i did but with very complicated code. It's okay

            – EasyOdoo
            Nov 25 '18 at 19:39











          • The funny thing he is doing the same thing that i did but with very complicated code. It's okay

            – EasyOdoo
            Nov 25 '18 at 19:39














          1












          1








          1







          The logic that you are trying to do is hard



          From what I understand you are running a subcription system
          based on number of days not dates so in order to compute the
          end date you just need this:




          1. start date (ex: 01/11/2018)

          2. number of days (ex: 30 days)

          3. excluded days (ex: Friday, Saturday)


          # day are like this
          # Fri
          # Sat
          # Sun
          # Mon
          # Tue
          # Wed
          # Thu

          # start day
          def get_expiry_date(start_date, number_of_days, excluded_days = None):
          """ compute end date of subcription period """
          if excluded_days is None:
          excluded_days =
          # check params
          start_date = str(start_date)
          if number_of_days < 1:
          raise exception.UserError(_('Number of days should be > 0!!')) # import the translate "_" method
          if len(excluded_days) > 5:
          raise exception.UserError(_('To much excluded days!!')) # import the translate "_" method

          date_format = '%Y-%m-%d'
          end_date = datetime.strptime(start_date, date_format)

          # compute end date
          # keeping adding one day until you finish your days
          add_one_day = timedelta(days=1)
          while number_of_days > 1:
          end_date += add_one_day
          if end_date.strftime('%a') not in excluded_days:
          # day is not excluded compute it
          number_of_days += -1

          return end_date.strftime(date_format)


          And this a test value that you can checkout:



                  print get_expiry_date('2018-11-01', 30, ['Fri', 'Sat'])  # 2018-12-12
          print get_expiry_date('2018-11-01', 30, ['Fri']) # 2018-12-05
          print get_expiry_date('2018-11-01', 30, ) # 2018-11-30
          print get_expiry_date('2018-11-01', 90, ) # 2019-01-29
          print get_expiry_date('2018-11-01', 30, ['Mon', 'Thu']) # 2018-12-11


          If you have all ready a running system you can use this:



          def get_expiry_date(start_date, end_date, excluded_days = None):
          if excluded_days is None:
          excluded_days =
          start_date = str(start_date)
          end_date = str(end_date)
          date_format = '%Y-%m-%d'
          # compute number of days
          number_of_days = (datetime.strptime(end_date, date_format) - datetime.strptime(start_date, date_format)).days
          expiry_date = datetime.strptime(start_date, date_format)

          if len(excluded_days) > 5:
          raise Exception('To much excluded days!!')

          # keeping adding one day until you finish your days
          one_day = timedelta(days=1)
          while number_of_days > 0:
          expiry_date += one_day
          # if day is not excluded reduce the number of left days
          if expiry_date.strftime('%a') not in excluded_days:
          number_of_days += -1

          return expiry_date.strftime(date_format)

          print get_expiry_date('2018-11-01', '2018-11-30', ['Fri', 'Sat']) # 2018-12-12





          share|improve this answer















          The logic that you are trying to do is hard



          From what I understand you are running a subcription system
          based on number of days not dates so in order to compute the
          end date you just need this:




          1. start date (ex: 01/11/2018)

          2. number of days (ex: 30 days)

          3. excluded days (ex: Friday, Saturday)


          # day are like this
          # Fri
          # Sat
          # Sun
          # Mon
          # Tue
          # Wed
          # Thu

          # start day
          def get_expiry_date(start_date, number_of_days, excluded_days = None):
          """ compute end date of subcription period """
          if excluded_days is None:
          excluded_days =
          # check params
          start_date = str(start_date)
          if number_of_days < 1:
          raise exception.UserError(_('Number of days should be > 0!!')) # import the translate "_" method
          if len(excluded_days) > 5:
          raise exception.UserError(_('To much excluded days!!')) # import the translate "_" method

          date_format = '%Y-%m-%d'
          end_date = datetime.strptime(start_date, date_format)

          # compute end date
          # keeping adding one day until you finish your days
          add_one_day = timedelta(days=1)
          while number_of_days > 1:
          end_date += add_one_day
          if end_date.strftime('%a') not in excluded_days:
          # day is not excluded compute it
          number_of_days += -1

          return end_date.strftime(date_format)


          And this a test value that you can checkout:



                  print get_expiry_date('2018-11-01', 30, ['Fri', 'Sat'])  # 2018-12-12
          print get_expiry_date('2018-11-01', 30, ['Fri']) # 2018-12-05
          print get_expiry_date('2018-11-01', 30, ) # 2018-11-30
          print get_expiry_date('2018-11-01', 90, ) # 2019-01-29
          print get_expiry_date('2018-11-01', 30, ['Mon', 'Thu']) # 2018-12-11


          If you have all ready a running system you can use this:



          def get_expiry_date(start_date, end_date, excluded_days = None):
          if excluded_days is None:
          excluded_days =
          start_date = str(start_date)
          end_date = str(end_date)
          date_format = '%Y-%m-%d'
          # compute number of days
          number_of_days = (datetime.strptime(end_date, date_format) - datetime.strptime(start_date, date_format)).days
          expiry_date = datetime.strptime(start_date, date_format)

          if len(excluded_days) > 5:
          raise Exception('To much excluded days!!')

          # keeping adding one day until you finish your days
          one_day = timedelta(days=1)
          while number_of_days > 0:
          expiry_date += one_day
          # if day is not excluded reduce the number of left days
          if expiry_date.strftime('%a') not in excluded_days:
          number_of_days += -1

          return expiry_date.strftime(date_format)

          print get_expiry_date('2018-11-01', '2018-11-30', ['Fri', 'Sat']) # 2018-12-12






          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited Nov 24 '18 at 7:05

























          answered Nov 22 '18 at 20:11









          EasyOdooEasyOdoo

          7,2092823




          7,2092823













          • It also works as you mentioned scenario of number of days. I will keep in mind for this change. Thanks a lot for your precious time and efforts. Support means a lot!

            – Jameel
            Nov 23 '18 at 12:53











          • I'm curious why did you remove acceptance is the calcutation wrong?

            – EasyOdoo
            Nov 24 '18 at 5:30











          • The calculations are correct but actually solution of @mingtwo_h9 is best suited for me so when I accepted that your acceptance is removed. I think only 1 solution is accepted. Basically I would prefer both solutions as accepted.

            – Jameel
            Nov 25 '18 at 10:23











          • The funny thing he is doing the same thing that i did but with very complicated code. It's okay

            – EasyOdoo
            Nov 25 '18 at 19:39











          • The funny thing he is doing the same thing that i did but with very complicated code. It's okay

            – EasyOdoo
            Nov 25 '18 at 19:39



















          • It also works as you mentioned scenario of number of days. I will keep in mind for this change. Thanks a lot for your precious time and efforts. Support means a lot!

            – Jameel
            Nov 23 '18 at 12:53











          • I'm curious why did you remove acceptance is the calcutation wrong?

            – EasyOdoo
            Nov 24 '18 at 5:30











          • The calculations are correct but actually solution of @mingtwo_h9 is best suited for me so when I accepted that your acceptance is removed. I think only 1 solution is accepted. Basically I would prefer both solutions as accepted.

            – Jameel
            Nov 25 '18 at 10:23











          • The funny thing he is doing the same thing that i did but with very complicated code. It's okay

            – EasyOdoo
            Nov 25 '18 at 19:39











          • The funny thing he is doing the same thing that i did but with very complicated code. It's okay

            – EasyOdoo
            Nov 25 '18 at 19:39

















          It also works as you mentioned scenario of number of days. I will keep in mind for this change. Thanks a lot for your precious time and efforts. Support means a lot!

          – Jameel
          Nov 23 '18 at 12:53





          It also works as you mentioned scenario of number of days. I will keep in mind for this change. Thanks a lot for your precious time and efforts. Support means a lot!

          – Jameel
          Nov 23 '18 at 12:53













          I'm curious why did you remove acceptance is the calcutation wrong?

          – EasyOdoo
          Nov 24 '18 at 5:30





          I'm curious why did you remove acceptance is the calcutation wrong?

          – EasyOdoo
          Nov 24 '18 at 5:30













          The calculations are correct but actually solution of @mingtwo_h9 is best suited for me so when I accepted that your acceptance is removed. I think only 1 solution is accepted. Basically I would prefer both solutions as accepted.

          – Jameel
          Nov 25 '18 at 10:23





          The calculations are correct but actually solution of @mingtwo_h9 is best suited for me so when I accepted that your acceptance is removed. I think only 1 solution is accepted. Basically I would prefer both solutions as accepted.

          – Jameel
          Nov 25 '18 at 10:23













          The funny thing he is doing the same thing that i did but with very complicated code. It's okay

          – EasyOdoo
          Nov 25 '18 at 19:39





          The funny thing he is doing the same thing that i did but with very complicated code. It's okay

          – EasyOdoo
          Nov 25 '18 at 19:39













          The funny thing he is doing the same thing that i did but with very complicated code. It's okay

          – EasyOdoo
          Nov 25 '18 at 19:39





          The funny thing he is doing the same thing that i did but with very complicated code. It's okay

          – EasyOdoo
          Nov 25 '18 at 19:39


















          draft saved

          draft discarded




















































          Thanks for contributing an answer to Stack Overflow!


          • Please be sure to answer the question. Provide details and share your research!

          But avoid



          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.


          To learn more, see our tips on writing great answers.




          draft saved


          draft discarded














          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53427062%2fodoo-11-python-3-how-to-find-expiry-date-of-subscription-if-some-weekdays-are%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown





















































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown

































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown







          Popular posts from this blog

          "Incorrect syntax near the keyword 'ON'. (on update cascade, on delete cascade,)

          Alcedinidae

          Origin of the phrase “under your belt”?