Come calcolare Venerdì prossimo alle 3 del mattino?
-
19-09-2019 - |
Domanda
Come si può calcolare il seguente Venerdì alle 03:00 come oggetto datetime
?
Chiarificazione:. cioè, la data calcolata deve sempre essere maggiore di 7 giorni di distanza, e inferiore o uguale a 14
Soluzione
Ecco una funzione e una prova che essa soddisfa i requisiti del OP:
import datetime
_3AM = datetime.time(hour=3)
_FRI = 4 # Monday=0 for weekday()
def next_friday_3am(now):
now += datetime.timedelta(days=7)
if now.time() < _3AM:
now = now.combine(now.date(),_3AM)
else:
now = now.combine(now.date(),_3AM) + datetime.timedelta(days=1)
return now + datetime.timedelta((_FRI - now.weekday()) % 7)
if __name__ == '__main__':
start = datetime.datetime.now()
for i in xrange(7*24*60*60):
now = start + datetime.timedelta(seconds=i)
then = next_friday_3am(now)
assert datetime.timedelta(days=7) < then - now <= datetime.timedelta(days=14)
assert then.weekday() == _FRI
assert then.time() == _3AM
Altri suggerimenti
Se si installa dateutil , allora si potrebbe fare qualcosa di simile:
import datetime
import dateutil.relativedelta as reldate
def following_friday(dt):
rd=reldate.relativedelta(
weekday=reldate.FR(+2),
hours=+21)
rd2=reldate.relativedelta(
hour=3,minute=0,second=0,microsecond=0)
return dt+rd+rd2
In alto, hours=+21
dice relativedelta
per incrementare il dt
da 21 ore prima di trovare il prossimo Venerdì. Quindi, se dt
è 12 marzo 2010 alle 02:00, l'aggiunta di 21 ore lo rende 11:00 dello stesso giorno , ma se dt
è dopo 3:00, quindi l'aggiunta di 21 ore pushs dt
in Sabato.
Ecco il codice di prova.
if __name__=='__main__':
today=datetime.datetime.now()
for dt in [today+datetime.timedelta(days=i) for i in range(-7,8)]:
print('%s --> %s'%(dt,following_friday(dt)))
che produce:
2010-03-05 20:42:09.246124 --> 2010-03-19 03:00:00
2010-03-06 20:42:09.246124 --> 2010-03-19 03:00:00
2010-03-07 20:42:09.246124 --> 2010-03-19 03:00:00
2010-03-08 20:42:09.246124 --> 2010-03-19 03:00:00
2010-03-09 20:42:09.246124 --> 2010-03-19 03:00:00
2010-03-10 20:42:09.246124 --> 2010-03-19 03:00:00
2010-03-11 20:42:09.246124 --> 2010-03-19 03:00:00
2010-03-12 20:42:09.246124 --> 2010-03-26 03:00:00
2010-03-13 20:42:09.246124 --> 2010-03-26 03:00:00
2010-03-14 20:42:09.246124 --> 2010-03-26 03:00:00
2010-03-15 20:42:09.246124 --> 2010-03-26 03:00:00
2010-03-16 20:42:09.246124 --> 2010-03-26 03:00:00
2010-03-17 20:42:09.246124 --> 2010-03-26 03:00:00
2010-03-18 20:42:09.246124 --> 2010-03-26 03:00:00
2010-03-19 20:42:09.246124 --> 2010-04-02 03:00:00
po 'prima di 3:00:
two = datetime.datetime(2010, 3, 12, 2, 0)
for date in [two+datetime.timedelta(days=i) for i in range(-7,8)]:
result = following_friday(date)
print('{0}-->{1}'.format(date,result))
rendimenti:
2010-03-05 02:00:00-->2010-03-12 03:00:00
2010-03-06 02:00:00-->2010-03-19 03:00:00
2010-03-07 02:00:00-->2010-03-19 03:00:00
2010-03-08 02:00:00-->2010-03-19 03:00:00
2010-03-09 02:00:00-->2010-03-19 03:00:00
2010-03-10 02:00:00-->2010-03-19 03:00:00
2010-03-11 02:00:00-->2010-03-19 03:00:00
2010-03-12 02:00:00-->2010-03-19 03:00:00
2010-03-13 02:00:00-->2010-03-26 03:00:00
2010-03-14 02:00:00-->2010-03-26 03:00:00
2010-03-15 02:00:00-->2010-03-26 03:00:00
2010-03-16 02:00:00-->2010-03-26 03:00:00
2010-03-17 02:00:00-->2010-03-26 03:00:00
2010-03-18 02:00:00-->2010-03-26 03:00:00
2010-03-19 02:00:00-->2010-03-26 03:00:00
Mi piace dateutil per questi compiti in generale, ma non capisco le euristiche che si desidera - come io uso le parole, se dico "Venerdì prossimo" ed è Giovedi i farebbe significa domani (probabilmente ho lavorato troppo duro e perso le tracce di ciò che giorno della settimana è) . Se è possibile specificare le euristiche rigorosamente possono sicuramente essere programmati, naturalmente, ma se sono strano e stravagante abbastanza è improbabile che trovarli già pre-programmati per voi in pacchetti esistenti; -).
In base alla tua precisazione ... Penso che si possa fare qualcosa di simile:
from datetime import *
>>> today = datetime.today()
>>> todayAtThreeAm = datetime(today.year, today.month, today.day, 3)
>>> todayAtThreeAm
datetime.datetime(2010, 3, 12, 3, 0)
>>> nextFridayAtThreeAm = todayAtThreeAm + timedelta(12 - today.isoweekday())
>>> nextFridayAtThreeAm
datetime.datetime(2010, 3, 19, 3, 0)
Avviso isoweekday()
restituisce 1 a 7 per lunedi alla domenica. 12 rappresenta venerdì della settimana successiva. Quindi 12 -. Today.isoweekday () ti dà il delta tempo corretto è necessario aggiungere ad oggi
Spero che questo aiuti.
pendolo , si può fare:
In [15]: pendulum.now().next(pendulum.FRIDAY).next(pendulum.FRIDAY).add(hours=3)
Out[15]: DateTime(2019, 5, 3, 3, 0, 0, tzinfo=Timezone('America/Los_Angeles'))
Si noti che ci sono due next Friday
in questa linea.
Per convertire in stringa,
In [16]: pendulum.now().next(pendulum.FRIDAY).next(pendulum.FRIDAY).add(hours=3).to_iso8601_string()
Out[16]: '2019-05-03T03:00:00-07:00'