Amelio Vazquez-Reina
Amelio Vazquez-Reina

Reputation: 96360

Mirroring dates in Python

Say we have a system that runs continuously, and that we make some changes to it on a particular date start_date.

We would like to compare the effects of the changes between:

For example, say I started my experiments on March 25 (in red), and that today is March 29 (green), I would like to obtain the four dates that define time_window_before (the two dates in yellow) and time_window_after( the two dates in blue).

                        enter image description here

The idea is to compare the results of the experiment started on start_date before and after the experiment started, on the longest possible number of days on a time window that is symmetric (in terms of days of the week) to the date the experiment started.

In other words, given start_date and today's date, how can I find the pairs of dates that define time_window_before time_window_after ( as datetime objects)?

Update

Since I was asked what happens if start_date and today's date don't fall on the same week, below is one such example:

                        enter image description here

Upvotes: 2

Views: 87

Answers (3)

Amelio Vazquez-Reina
Amelio Vazquez-Reina

Reputation: 96360

The following should do it:

def get_symmetric_time_window_fwd(ref_date, end_date):
  da1 = ref_date+timedelta(1)
  da2 = end_date-timedelta(1)

  if da2.weekday() >= ref_date.weekday():
    db2 = da2 - timedelta( 7 * (1+int((end_date - ref_date).days/7)))
  else:
    db2 = da2 - timedelta( 7 * (int((end_date - ref_date).days/7)))

  db1 = db2-(da2-da1)

  return da1, da2, db1, db2

Test 1:

In: get_symmetric_time_window(date(2014, 3, 18), date(2014, 3, 29))
Out: 
(datetime.date(2014, 3, 19),
 datetime.date(2014, 3, 28),
 datetime.date(2014, 3, 5),
 datetime.date(2014, 3, 14))

Test 2:

In: get_symmetric_time_window(date(2014, 3, 25), date(2014, 3, 29))
Out: 
(datetime.date(2014, 3, 26),
 datetime.date(2014, 3, 28),
 datetime.date(2014, 3, 19),
 datetime.date(2014, 3, 21))

Test 3:

In: get_symmetric_time_window(date(2014, 7, 17), date(2014, 7, 23))
Out: 
(datetime.date(2014, 7, 18),
 datetime.date(2014, 7, 22),
 datetime.date(2014, 7, 11),
 datetime.date(2014, 7, 15))

Upvotes: 1

Heikki Toivonen
Heikki Toivonen

Reputation: 31150

This works at least in your two samples, would this be good enough?:

experiment_start_date = datetime.date(2014,3,18)
now=datetime.date(2014,3,29)

day_after1 = experiment_start_date+datetime.timedelta(1)
day_after2 = now-datetime.timedelta(1)
day_before2 = experiment_start_date-datetime.timedelta(day_after2.weekday()-experiment_start_date.weekday()+1)
day_before1 = day_before2-(day_after2-day_after1)

Upvotes: 2

Michal
Michal

Reputation: 2532

Python's datetime library has all the methods you need to add and subtract the dates:

from datetime import date, timedelta

def get_time_window_after(experiment_start_date, experiment_end_date):
  # Add 1 day to start and subtract 1 day from end
  print "After Start: %s" %(experiment_start_date + timedelta(days = 1))
  print "After End: %s" %(experiment_end_date - timedelta(days = 1))

def get_time_window_before(experiment_start_date, experiment_end_date):
  # Find the total length of the experiment
  delta = experiment_end_date - experiment_start_date
  # Determine how many weeks it covers (add 1 because same week would be 0)
  delta_magnitude = 1 + (delta.days / 7)

  # Subtract 7 days per week that the experiment covered, also add/subtract 1 day
  print "Before Start: %s" %(experiment_start_date - timedelta(days = 7 * delta_magnitude) + timedelta(days = 1))
  print "Before End: %s" %(experiment_end_date - timedelta(days = 7 * delta_magnitude) - timedelta(days = 1))

Here's the examples I ran the code with to make sure it works:

print "\nResults for March 25 2014 to March 29 2014"
get_time_window_after(date(2014, 3, 25), date(2014, 3, 29))
get_time_window_before(date(2014, 3, 25), date(2014, 3, 29))

print "\nResults for March 18 2014 to March 29 2014"
get_time_window_after(date(2014, 3, 18), date(2014, 3, 29))
get_time_window_before(date(2014, 3, 18), date(2014, 3, 29))

print "\nResults for March 18 2014 to April 04 2014"
get_time_window_after(date(2014, 3, 18), date(2014, 4, 4))
get_time_window_before(date(2014, 3, 18), date(2014, 4, 4))

Note: If you make these functions return values and set variables, you could use the time_window_after as input into get_time_window_before() function and forego the duplicated timedelta(days = 1) logic.

Upvotes: 2

Related Questions