Вопрос по datetime, time, python – Python: код манипуляции с датой

0

В python я хочу вычислить дельта-дни для дня day_of_a_year и соответствующего ему месяца, а также дельта-дни для месяца + 1.

* Извините, я забыл упомянуть, что год является известной переменной например.

def a(day_of_year):
    <...>
    return [(days_from_start_of_month),(days_untill_end_of_month)]

так Если

day_of_year = 32 
a(32) = (2,28) #assuming the month which the day_of_year corresponds to starts from day 30 and ends to day 60.

Пока я изучаю модули datetime, timeutils и calendar, и я действительно не могу понять логику кода! Я хотел бы показать что-то солидное, но я теряюсь где-то в функциях timedelta

Да, я знаю, что вы правы. Числа, которые я сказал, были с отступом в качестве примера user528025
Когда вы говорите: «Я не могу понять логику для кода» о чем конкретно вы говорите? Paul Seeb
Вам также нужно будет передать год для выполнения своей функции, поскольку в некоторых годах число дней отличается. GP89
не могли бы вы уточнить свой пример. Его трудно следовать. Также что вы пробовали? Что именно вы хотите в качестве выходного? Paul Seeb
32-й день года - 1 февраля; В январе 31 день. Martijn Pieters♦

Ваш Ответ

2   ответа
2

как и первый день следующего месяца. Как только вы это сделаете, остальное станет еще проще. Как указано в ФП,calendar.monthrange function дает нам самый читаемый способ получить последний день месяца.

>>> from datetime import date, year
>>> import calendar
>>> def first_day(dt):
...      # Simply copy year and month into new date instance
...      return date(dt.year, dt.month, 1)
...
>>> def last_day(dt):
...      days_in_month = calendar.monthrange(dt.year, dt.month)[1]
...      return date(dt.year, dt.month, days_in_month)
...
>>> nth_day = 32
>>> day_of_year = date(2012, 1, 1) + timedelta(days=nth_day - 1)
>>> day_of_year
datetime.date(2012, 2, 1)
>>> first_day(day_of_year), last_day(day_of_year)
(datetime.date(2012, 2, 1), datetime.date(2012, 2, 29))
>>> day_of_year - first_day(day_of_year), last_day(day_of_year) - day_of_year
(datetime.timedelta(0), datetime.timedelta(28))

Чтобы объединить эти методы в одну функцию:

def delta_to_start_and_end(year, day_of_year):
    dt = date(year, 1, 1) + timedelta(days=(day_of_year - 1))

    def first_day(dt):
         return date(dt.year, dt.month, 1)
    def last_day(dt):
         days_in_month = calendar.monthrange(dt.year, dt.month)[1]
         return date(dt.year, dt.month, days_in_month)

    return (dt - first_day(dt)).days, (last_day(dt) - dt).days

Выход:

>>> delta_to_start_and_end(2012, 32)
(0, 28)
>>> delta_to_start_and_end(2011, 32)
(0, 27)
>>> delta_to_start_and_end(2012, 34)
(2, 26)
>>> delta_to_start_and_end(2012, 364)
(28, 2)

Я не уверен, хотите ли вы добавить1 каждому из этих двух значений; в настоящее время первый день месяца (первый пример) дает вам0 в качестве первого значения и (дней в месяце - 1) в качестве второго значения, поскольку это разница в днях от этих точек. Добавить тривиально+ 1 дважды на последней строкеdelta_to_start_and_end функционировать, если вам это нужно.

Как историческая справка, предыдущая версия этого ответа использовала другой метод для вычисления последнего дня месяца без календарного модуля:

def last_day(dt):
     rest, month = divmod(dt.month, 12)
     return date(dt.year + rest, month + 1, 1) - timedelta(days=1) 

Эта функция используетdivmod builtin function для обработки «текущий месяц - декабрь»; Край случай; в этом случае следующий месяц не13, но1 и нам также нужно увеличить год на единицу. Перемещение по номеру обратно на «начало» является модулем числа, ноdivmod Функция также дает нам делитель, который оказывается1 если текущий месяц12, Это дает нам удобный индикатор, когда увеличивать год.

Также можете ли вы объяснить, если это возможно, функцию last_day? Я заблудился, пытаясь выяснить, что происходит user528025
последний день месяца также можно рассчитать с помощью calendar.monthrange (year, month) - & gt; (0 ~ 6 (0 = пн, 6 = вс), days_of_month) calendar.monthrange (2000,30) - & gt; (3,31) user528025
ах вы заметили проблему с днями = 31, я просто собирался указать на это: P
@ GP89: далеко впереди! :-П
@ user528025: черт возьми, забыл про модуль календаря. :-) Я включил некоторые комментарии вlast_day функция уже, вы видели это (позже редактировать).
0

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

monthdays = (31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31)

day = 32

total = 0
for i in monthdays:
    if day - total - i < 0:
        before = day - total
        after = total + i - day
        break
    total += i

print before, after

(просто быстрый старт, возможно, есть более элегантный способ)

Это сломается в високосный год, как 2012.
Вот почему я сказал «просто быстрый старт». : D
@ BrtH Да, если год кратен 100, то это всего лишь високосный год, если он также кратен 400. Например, 1900 год не был високосным, а 2000 год. user528025
Вы можете проверить високосный год, просто выполнивif year % 4: #not leap насколько я знаю. или есть другие правила для високосных лет?
Я думал об этом, но, к сожалению, я должен учитывать високосные годы user528025

Похожие вопросы