在Python中镜像日期

时间:2014-03-27 18:50:59

标签: python datetime

假设我们有一个持续运行的系统,并且我们在特定日期start_date对其进行了一些更改。

我们想比较两者之间变化的影响:

  • start_date与今天日期之间全天的时间窗口(以黄色显示)
  • 之前 start_date的完整日期的等效时间窗口(一周中的同一天)(以蓝色显示)

例如,假设我在 3月25日开始实验(红色),今天 3月29日(绿色),我想获得< strong>四个日期定义 time_window_before(黄色的两个日期)和time_window_after(两个日期为蓝色)。

enter image description here

我们的想法是比较实验开始之前和之后start_date 开始的实验结果,以及可能的最长天数时间窗口是对称的(以星期几为单位)到实验开始的日期。

换句话说,在给定start_date和今天的日期的情况下,如何找到定义time_window_before time_window_after(作为datetime个对象)的日期对?

更新

因为我被问到如果start_date和今天的日期不在同一周会发生什么,下面是一个这样的例子:

enter image description here

3 个答案:

答案 0 :(得分:2)

这至少在你的两个样本中起作用,这还不错吗?:

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)

答案 1 :(得分:2)

Python的datetime库具有添加和减去日期所需的所有方法:

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))

以下是我运行代码以确保其有效的示例:

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))

注意:如果您使这些函数返回值并设置变量,则可以使用time_window_after作为get_time_window_before()函数的输入,并放弃重复的timedelta(days = 1)逻辑。

答案 2 :(得分:1)

以下应该这样做:

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

测试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))

测试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))

测试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))