Проблема Python Datetime: есть ли лучшее решение - PullRequest
0 голосов
/ 15 ноября 2018

Я нашел правильное решение следующей проблемы, которая использует объекты 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 голосов
/ 16 ноября 2018

Вы можете использовать регулярные выражения, чтобы иметь функцию «уборщика»:

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
0 голосов
/ 21 декабря 2018

Вот более простая версия предыдущего ответа .Я новичок, поэтому я не могу понять весь сложный код здесь.

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
0 голосов
/ 15 ноября 2018

Произошла некоторая деструктуризация списка, чтобы сократить количество строк кода. Также убрал создание некоторых новых переменных и просто использовал значения напрямую:

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()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...