There was a need to write a script on a python with which he was familiar very superficially. It is necessary to write a script which, by the date entered, determines its belonging to the date range and displays which range it belongs to.

For example: There is a list of church posts with dates and names, I enter the date and get to which post the date belongs to or null if the day is not fast.

  • Indicate where you store the values ​​of the dates with which to compare. - Legionary
  • Most likely in the text of the program itself in the form of a structure, everything can be varied here. It makes no sense to connect a DB of any kind, because the ranges are only 8-10 boundaries and the number if it changes very rarely. - widler
  • one
    @AntonMelnikov this question is not very specific and therefore may not be very useful for future visitors to the site (although if a person interested in working with date ranges in Python learns at least that you can use the datetime module and compare its objects directly from published answers, then already a plus). If the question is useful to others, then the author’s ability to find a solution on his own does not matter. You have a mistaken idea of ​​the purpose of the site’s existence (a sheet of broken code is not a good question). See Work for the Author - jfs
  • one
    @jfs In my opinion, before asking for help, a person should try to do it himself. Open the smart library reference, see the datetime module, read about the methods. Elementary google "python compare dates". Looked through the thread you are referring to. IMHO, such a statement of the problem, as the author - is not a reason for closing, I did not put flags on him. But thinking about life is necessary, so I just left a comment. - Anton Melnikov
  • one
    @AntonMelnikov I agree with what you say, but it doesn’t have anything to do with what questions should be on the site (“for another” or not). Read the link that I gave, think (this is a difficult question — I do not believe that you could learn it so quickly). Comments are no place for meta-discussions. If you think you have something to say, then post your answer on Mete in an existing topic or open a new one (as you wish). - jfs

4 answers 4

import datetime class DATE(dict): def __init__(self, **kwargs): '''список церковных постов с датами и названиями''' for k, v in kwargs.items(): start, stop = v self[k] = datetime.date(*start), datetime.date(*stop) def compare(self, date_): '''по введённой дате определяет её принадлежность к диапазону дат''' d_ = datetime.date(*date_) for post_name in self: start, stop = self[post_name] if start <= d_ <= stop: # определяет return post_name # выводит к какому диапазону она принадлежит # Есть список церковных постов с датами и названиями d = DATE( post_1=[(2016, 1, 1), (2016, 1, 10)], post_2=[(2016, 3, 5), (2016, 4, 11)] ) # я ввожу дату и получаю к какому посту принадлежит дата или null если день не постный print(d.compare((2016, 1, 5))) print(d.compare((2016, 3, 5))) print(d.compare((2016, 12, 5))) 

out:

 post_1 post_2 None 
  • The use of inheritance is not justified here. There is no need to create a new collection to store a set of posts. Finding which post the date belongs to can be implemented as a function, and even if you use a class, DATE not the best name. - jfs

About working with dates in Python in Russian .

But in this particular case, it is easier to use ordinary logical operators, for example:

 return (t1start <= t2 <= t1end) 

returns true if t2 is between t1start and t1end.

As a result, if our list of dates is a dictionary, where the key is the interval index (or the name of the holiday), and the value is a tuple with the beginning and end of the interval {1:(t1start,t1end), 2:(t2start,t2end), ..., N:(tNstart,tNend)} , then you can check by the following function:

 def (check_date, intervals): for index, interval in intervals: t1start, t1end = interval if (t1start <= check_date <= t1end): return index return None 

This function will return the value of the dictionary key in case check_date is in the corresponding interval. Otherwise, the function will return None.

Checked date and interval limits should be of type date

 from datetime import date 
  • To understand if given intervals of dates a and b intersect, it is possible to use a simpler condition: a.start <= b.end and b.start <= a.end - jfs
  • A little wrong in the example indicated. To ensure that the d1 date is between t_start and t_end, the condition t_start <= d1 <= t_end - vscoder must be true

In the standard python library there is a datetime module, in which there are tools for working with date and time.

A simple example:

 import datetime delta = datetime.date.today() - datetime.date(1987, 12, 28) # разница текущим днем и моим днем рождения:) - объект timedelta print(delta.days) # Разница между датами в днях, на сегодня это 10521 # Пример разбора даты из текста: sdate = "17.10.2016" d = datetime.datetime.strptime(sdate, '%d.%m.%Y') print(d) # Объект даты-времени: datetime.datetime(2016, 10, 17, 0, 0) 

For date and datetime objects, getting into the date range can be checked simply with the help of < , > , <= , >= operators, including so: d1 <= d <= d2

Datetime module documentation

    There is a list of church posts with dates and names, I enter the date and get what date the post belongs to or null if the day is not a fast one.

     #!/usr/bin/env python3 from datetime import datetime from collections import namedtuple DateRange = namedtuple('DateRange', 'start end') dates = { 'Великий Пост': make_date_range("14 марта – 30 апреля 2016"), 'Петров пост': make_date_range("27 июня – 11 июля 2016"), # ... } now = datetime.now() fast = next((name for name, r in dates.items() if r.start <= now < r.end), None) 

    fast is the name of the post or None if there is no post today (not including. .end date — use <= r.end to include the end date if necessary), where:

     import re def make_date_range(date_range_string): d1, m1, d2, m2, year = re.match(r"(\d+)\s*(\w+)\s*–\s*(\d+)\s*(\w+)\s*(\d+)", date_range_string).groups() months = {'марта': 3, 'апреля': 4, 'июня': 6, 'июля': 7} # ... return DateRange(datetime(int(year), months[m1], int(d1)), datetime(int(year), months[m2], int(d2))) 

    Related question: Find first element in a predicate sequence


    If there is a list of dates, then you can quickly find to which date range / interval the entered date belongs, using the bisect module, which performs a binary search on a sorted list :

     from bisect import bisect Y = datetime.now().year seasons = [datetime(*args) for args in [ (Y, 1, 1), # winter (Y, 3, 1), # spring (Y, 6, 1), # summer (Y, 9, 1), # autumn (Y, 12, 1) # winter ]] season_names = [None, 'winter', 'spring', 'summer', 'autumn', 'winter'] index = bisect(seasons, datetime.now()) print(season_names[index]) # -> autumn