Ищем * существующий * модуль Python для определения финансовых месяцев - PullRequest
3 голосов
/ 03 ноября 2011

Я в аду календаря, и я надеюсь, что существует модуль Python, который делает то, что я хочу.

Я делаю веб-приложение на Python, которое работает с подписками. Концептуально он похож на план мобильного телефона: вы начинаете свою подписку в определенную дату (скажем, 1.13.2011), и за каждый расчетный месяц у вас есть куча "сеансов" (телефонных звонков), за которые вы должны будете платить.

Нам нужно:

  1. Знать, к какому месяцу выставления счетов подпадает каждая сессия.
  2. Знать время начала и время окончания каждого расчетного месяца.

Например, если вы зарегистрировались на 1.13.2011 и сделали телефонный звонок на 1.20.2011, это будет рассчитывать на ваш первый платежный месяц. То же самое для телефонного звонка на 2.10.2011. Но если вы позвоните по номеру 2.15.2011, он будет рассчитан на ваш второй расчетный месяц.

Относительно даты начала и окончания: если сегодня 2.15.2011, тогда дата начала текущего месяца 2.13.2011, а дата его окончания 3.13.2011.

Возможно, вы думаете, что это не так сложно, но тогда вы должны учитывать, что месяцы имеют разную продолжительность. Правило обработки этого правила заключается в том, что если ваша подписка начинается 30-го числа любого месяца, ее предельные даты в каждом месяце будут min(30, n_days_in_that_month). Это относится и к 29, 30 и 31.


Я пытался кодировать это, но это стало слишком сложным. Я ищу готовый существующий модуль, который выполняет эти функции.

Ради любви к Богу, не оставляйте ответ с эскизом реализации! Это бесполезно для меня. Я ценю ваши намерения, но в аду календаря наброски реализаций не помогают. У меня уже есть эскиз реализации, и отладка вашей займет столько же времени, сколько отладка моей.

Меня интересует только использование существующего модуля, который обрабатывает такие задачи календаря. Знаете ли вы один?

Ответы [ 3 ]

5 голосов
/ 03 ноября 2011

http://labix.org/python-dateutil

Редактирование Барана: класс dateutil.rrule.rrule - это класс, который сделал точно , что я и хотел.

2 голосов
/ 03 ноября 2011

Относительно дат начала и окончания: если сегодня 2.15.2011, то датой начала текущего месяца является 2.13.2011, а датой его окончания является 3.13.2011.

Возможно, вы думаетеэто не так сложно, но тогда вы должны учитывать, что месяцы имеют разную продолжительность.Правило обработки этого правила заключается в том, что если ваша подписка начинается 30-го числа любого месяца, ее предельные даты в каждом месяце будут минимальными (30, n_days_in_that_month).Это относится и к 29, 30 и 31.

Это все еще довольно простой.Используйте модуль datetime для хранения datetime, чтобы вы могли легко разобрать день (например, если dt - это дата, то dt.day).Платежный цикл начинается, скажем, 29 (самый сложный случай).Пусть billing_cycle_day=29.Оплачиваемое событие происходит, скажем, event_day=10, event_month=5.Затем с event_day < billing_cycle_day вы выставляете счет на счет event_month.В противном случае вы выставляете счет на счет следующего месяца (помня, что если месяц = ​​12; вы должны увеличивать год).

Таким образом, теперь цикл выставления счетов всегда будет с 29-го по 28-е в следующем месяце.Осложнение возникает, если, скажем, дата, такая как 29.02.2011, не существует.Например, начальная дата цикла выставления счета должна быть 29.02.2011 (но она не существует);в этом случае вы просто делаете это первым в следующем месяце.

billing_cycle_day = 29
year, month = 2011, 2
import datetime
def create_date_or_first_of_next_month(year, month, day):
    try:
        return datetime.date(year, month, day)
    except ValueError:
        year_n, month_n = (year, month+1) if month != 12 else (year+1, 1)
        return datetime.date(year_n, month_n, 1)
1 голос
/ 04 ноября 2011

Эта проблема не так сложна, как вы думаете.Все, что вам нужно сделать, это написать функцию, которая с учетом начального дня (например, 13 или 30) возвращает два объекта даты, которые являются началом и концом текущего финансового месяца.Вы уже набросали все детали вашего вопроса.Лучше всего включить в функцию необязательный параметр todayis, чтобы указать, какой день использовать в качестве ссылки на сегодняшний день.Например, если сегодня 15 октября 2011 года, а вы указали 13, функция предполагает, что вы имеете в виду 13 октября 2011 года. Но если вы хотите перезапустить июньские данные, вы должны указать todayis = date (2011,0613)

Возвращаемые значения (начало и конец) позволяют вам точно определить даты, которые принадлежат этому финансовому месяцу.Но если дата предшествует дате начала и менее чем за 29 дней до даты начала, то вы также можете указать предыдущий финансовый месяц.То же самое касается следующего финансового месяца.Это полезно, потому что будет много ситуаций, когда вы обрабатываете данные через несколько дней, поэтому у вас будет смесь двух финансовых месяцев для обработки.

...