Home > Blockchain >  How to exclude certain hours between two date differenece?
How to exclude certain hours between two date differenece?

Time:07-27

I want to get the total hours difference between two timestamps but I want to exclude certain hour in there . I want to exclude these hours from 5PM-10AM everyday.

  from datetime import datetime
  def get_total_hours(model_instance):
      datetime = model_instance.datetime
      now = datetime.now()
      diff = now - datetime
      total_secs = diff.total_seconds()
      hours =  total_secs // 3600
      return hours

CodePudding user response:

I'd envision the problem geometrically:

          day n     day n 1   etc...
        _______________________________________________________________________
00:00   |         |         |         |         |         |         |         |
        |         |         |         |         |         |         |         |
        |         |         |         |         |         |         |         |
        |         |         |         |         |         |         |         |
        |         |         |         |         |         |         |         |
EXCLUDED|         |         |         |         |         |-- t2 ---|         |
        |         |         |         |         |         |         |         |
        |         |         |         |         |         |         |         |
        |         |         |         |         |         |         |         |
10:00   |.........|.........|.........|.........|.........|.........|.........|
        |         |xxxxxxxxx|xxxxxxxxx|xxxxxxxxx|xxxxxxxxx|         |         |
        |         |xxxxxxxxx|xxxxxxxxx|xxxxxxxxx|xxxxxxxxx|         |         |
        |         |xxxxxxxxx|xxxxxxxxx|xxxxxxxxx|xxxxxxxxx|         |         |
COUNTED |-- t1 ---|xxxxxxxxx|xxxxxxxxx|xxxxxxxxx|xxxxxxxxx|         |         |
        |xxxxxxxxx|xxxxxxxxx|xxxxxxxxx|xxxxxxxxx|xxxxxxxxx|         |         |
        |xxxxxxxxx|xxxxxxxxx|xxxxxxxxx|xxxxxxxxx|xxxxxxxxx|         |         |
        |xxxxxxxxx|xxxxxxxxx|xxxxxxxxx|xxxxxxxxx|xxxxxxxxx|         |         |
17:00   |.........|.........|.........|.........|.........|.........|.........|
        |         |         |         |         |         |         |         |
        |         |         |         |         |         |         |         |
        |         |         |         |         |         |         |         |
        |         |         |         |         |         |         |         |
EXCLUDED|         |         |         |         |         |         |         |
        |         |         |         |         |         |         |         |
        |         |         |         |         |         |         |         |
        |         |         |         |         |         |         |         |
        |         |         |         |         |         |         |         |
        |         |         |         |         |         |         |         |
23:59   |_________|_________|_________|_________|_________|_________|_________|

Whatever t1 and t2 might be, your answer is the area of a rectangle (height x width) plus some edge case handling at the ends.

CodePudding user response:

First, check the remaining hours for each date.

Then, check the day gap between the start and end dates.

import datetime

dt_start = datetime.datetime(year=2022, month=7, day=31, hour=20)
dt_end = datetime.datetime(year=2022, month=8, day=2, hour=10, minute=30)

dt_start_gap_lb = dt_start.replace(hour=10, minute=0, second=0, microsecond=0)
dt_start_gap_ub = dt_start.replace(hour=17, minute=0, second=0, microsecond=0)
dt_end_gap_lb = dt_end.replace(hour=10, minute=0, second=0, microsecond=0)
dt_end_gap_ub = dt_end.replace(hour=17, minute=0, second=0, microsecond=0)

dt_start_remain = dt_start_gap_ub - max(dt_start_gap_lb, dt_start)
dt_end_remain = min(dt_end_gap_ub, dt_end) - dt_end_gap_lb

dt_start_remain_hours = 0 if dt_start_remain.days < 0 else dt_start_remain.seconds / 3600.0
dt_end_remain_hours = 0 if dt_end_remain.days < 0 else dt_end_remain.seconds / 3600.0

gap_hours = max((dt_end_gap_lb - dt_start_gap_ub).days * (17-10)   dt_start_remain_hours   dt_end_remain_hours, 0)

Results:

dt_start = datetime.datetime(year=2022, month=7, day=31, hour=20)
dt_end = datetime.datetime(year=2022, month=8, day=2, hour=10, minute=30)
> 7.5
dt_start = datetime.datetime(year=2022, month=7, day=31, hour=16, minute=30)
dt_end = datetime.datetime(year=2022, month=8, day=2, hour=10, minute=30)
> 8.0
dt_start = datetime.datetime(year=2022, month=7, day=31, hour=5, minute= 30)
dt_end = datetime.datetime(year=2022, month=7, day=31, hour=10, minute=30)
> 0.5

CodePudding user response:

Given a model Foo with a field timestamp, and t1 and t2 defined as per the question:

Foo.objects.filter(timestamp__gte=t1, timestamp__lte=t2
   ).exclude( timestamp__hour__gte=17 # up to 23 by definition
   ).exclude( timestamp__hour__lte=9  # down to 0 by definition
   )

Alternatively,

    .exclude( timestamp__hour__in=[
        0,1,2,3,4,5,6,7,8,9,17,18,19,20,21,22,23 ])
  • Related