Python日期时间问题:是否有更好的解决方案

时间:2018-11-15 20:34:56

标签: python function datetime

我找到了使用python 3 datetime对象的以下问题的正确解决方案。但是,我的解决方案似乎真的很乱,我想知道是否可以得到一些帮助来清理它:

问题: 完成which_date()函数,该函数将在其后返回初始日期之后指定时间段之后的日期。可以用两种不同的方式指定时间段:以天数表示,例如“ 1天”或“ 30天”,或以周数表示,例如“ 2周”或“ 12周”。

def which_date(start_date,time):
    """
    This function takes as input a string depicting a date in YYYY/mm/dd
    format and a string stating a time period in the form of "X day(s)" or
    "Y week(s)". Output should be a string in form YYYY/mm/dd with the date
    that is X days or Y weeks after the initial date.
    """

    # Every thing after this comment and before 'return end_date' is my 
    #code to solve this probmem
    start_date_split = start_date.split('/')
    start_date_split = list(map(int, start_date_split))
    year, month, day = start_date_split[0], start_date_split[1], 
    start_date_split[2]
    start_date_date_obj = datetime.date(year, month, day)

    time_split = time.split(' ')
    time_amount = int(time_split[0])
    days_or_weeks = time_split[1]

    time_to_add = datetime.timedelta(0)
    if 'day' in days_or_weeks:
        time_to_add = datetime.timedelta(days = time_amount)
    else:
        time_to_add = datetime.timedelta(weeks = time_amount)

    end_date_date_obj = start_date_date_obj + time_to_add    
    end_date = end_date_date_obj.strftime('%Y/%m/%d')
    return end_date

以下是验证测试:

def test():
   assert which_date('2016/02/10','35 days') == '2016/03/16'
   assert which_date('2016/12/21','3 weeks') == '2017/01/11'
   assert which_date('2015/01/17','1 week') == '2015/01/24'
   print("All tests completed.")

3 个答案:

答案 0 :(得分:0)

对列表进行了一些分解以减少某些代码行。还删除了一些新变量的创建,而直接使用了这些值:

import datetime

def which_date(start_date,time):
  """
  This function takes as input a string depicting a date in YYYY/mm/dd
  format and a string stating a time period in the form of "X day(s)" or
  "Y week(s)". Output should be a string in form YYYY/mm/dd with the date
  that is X days or Y weeks after the initial date.
  """

  # Every thing after this comment and before 'return end_date' is my 
  # code to solve this problem

  year, month, day = [int(each) for each in start_date.split('/')]

  start_date_date_obj = datetime.date(year, month, day)

  time_amount, days_or_weeks = [int(value) if index==0 else value for index, value in enumerate(time.split(' '))]

  time_to_add = datetime.timedelta(days = time_amount) if days_or_weeks=='days' else datetime.timedelta(weeks = time_amount)

  return (start_date_date_obj + time_to_add).strftime('%Y/%m/%d')

def test():
  assert which_date('2016/02/10','35 days') == '2016/03/16'
  assert which_date('2016/12/21','3 weeks') == '2017/01/11'
  assert which_date('2015/01/17','1 week') == '2015/01/24'
  print("All tests completed.")

test()

答案 1 :(得分:0)

您可以使用正则表达式以具有“清洁器”功能:

import re
import datetime


def which_date(start_date, time):
    # Split your date into a list by using non-decimal characters as separators
    year, month, day = re.split(r'\D', start_date)
    start_date_date_obj = datetime.date(int(year), int(month), int(day))

    # Create group captures in order to get the quantity of day(s)/week(s)
    # and pass those as generic arguments to timedelta
    time_match = re.search(r'(\d+) (day|week)[s]?', time)
    args = {time_match.group(2) + 's': int(time_match.group(1))}
    time_to_add = datetime.timedelta(**args)

    end_date_date_obj = start_date_date_obj + time_to_add
    end_date = end_date_date_obj.strftime('%Y/%m/%d')
    return end_date

答案 2 :(得分:0)

这是一个更简单的版本of a previous answer。我是一个初学者,所以我在这里看不懂所有高级代码。

import datetime
def which_date(start_date,time):
    """
    This function takes as input a string depicting a date in YYYY/mm/dd
    format and a string stating a time period in the form of "X day(s)" or
    "Y week(s)". Output should be a string in form YYYY/mm/dd with the date
    that is X days or Y weeks after the initial date.
    """

    year, month, day = [int(each) for each in start_date.split('/')]


    start_date_date_obj = datetime.date(year, month, day)

    add = 1
    string = time.split()
    if string[1] == "days" or string[1] == "day":
        add = int(string[0])
    else:
        add = (int(string[0]))*7



    time_to_add = datetime.timedelta(days = add)

    end_date = (start_date_date_obj + time_to_add).strftime('%Y/%m/%d')

    return end_date