Metoda Python datetime.isocalendar()
zwraca krotkę (ISO_year, ISO_week_number, ISO_weekday)
dla danego obiektu datetime
. Czy istnieje odpowiednia funkcja odwrotna? Jeśli nie, czy istnieje prosty sposób obliczenia daty podanej na rok, numer tygodnia i dzień tygodnia?Jaki jest najlepszy sposób na znalezienie odwrotności datetime.isocalendar()?
Odpowiedz
Niedawno miałem rozwiązać ten problem się i wpadł na to rozwiązanie:
import datetime
def iso_year_start(iso_year):
"The gregorian calendar date of the first day of the given ISO year"
fourth_jan = datetime.date(iso_year, 1, 4)
delta = datetime.timedelta(fourth_jan.isoweekday()-1)
return fourth_jan - delta
def iso_to_gregorian(iso_year, iso_week, iso_day):
"Gregorian calendar date for the given ISO year, week and day"
year_start = iso_year_start(iso_year)
return year_start + datetime.timedelta(days=iso_day-1, weeks=iso_week-1)
kilku przypadkach Test:
>>> iso = datetime.date(2005, 1, 1).isocalendar()
>>> iso
(2004, 53, 6)
>>> iso_to_gregorian(*iso)
datetime.date(2005, 1, 1)
>>> iso = datetime.date(2010, 1, 4).isocalendar()
>>> iso
(2010, 1, 1)
>>> iso_to_gregorian(*iso)
datetime.date(2010, 1, 4)
>>> iso = datetime.date(2010, 1, 3).isocalendar()
>>> iso
(2009, 53, 7)
>>> iso_to_gregorian(*iso)
datetime.date(2010, 1, 3)
EDYCJA: zignoruj to, skrzynie brzegowe są uciążliwe. Idź z rozwiązaniem Bena.
Ok, po bliższym przyjrzeniu zauważyłem, że strptime
ma %W
i %w
parametry, więc następujące prace:
def fromisocalendar(y,w,d):
return datetime.strptime("%04dW%02d-%d"%(y,w-1,d), "%YW%W-%w")
Kilka pułapek: Numer ISO tydzień rozpoczyna się 1
, natomiast %W
rozpoczyna się 0
. Dzień tygodnia ISO rozpoczyna się 1
(poniedziałek), która jest taka sama jak %w
, więc niedziela będzie prawdopodobnie musiał być 0
nie 7
...
Którą wersję używasz ?, testowałem w wersji 2.4.2 i nie działało dla mnie, znalazłem http://bugs.python.org/issue1045381, ale powiedziałem, że zrobiono to na 2.3 –
Używam 2.5. 2,% W działa, nie jesteś pewien% U. – Tom
Wygląda na to, że na niego odpowiedziałeś. Dlaczego nie przyjąć odpowiedzi? –
Należy pamiętać, że% W jest tydzień # (0,53), który NIE JEST TO SAMO jako tydzień ISO (1-53). Będą przypadki skrajne, w których% W nie będzie działać.
import datetime
def iso_to_gregorian(iso_year, iso_week, iso_day):
"Gregorian calendar date for the given ISO year, week and day"
fourth_jan = datetime.date(iso_year, 1, 4)
_, fourth_jan_week, fourth_jan_day = fourth_jan.isocalendar()
return fourth_jan + datetime.timedelta(days=iso_day-fourth_jan_day, weeks=iso_week-fourth_jan_week)
ten został zaadaptowany z @ BenJames bardzo dobra odpowiedź. Nie musisz znać pierwszego dnia w roku. Musisz tylko poznać przykład daty, która z pewnością jest w tym samym roku ISO, oraz kalendarz ISO tygodnia i dzień tej daty.
Czwarty stycznia jest po prostu jeden przykład, ponieważ, jak Ben wskazał, czwarty z Jan zawsze należy do tego samego roku ISO i roku gregoriańskiego, i jest pierwszym dniem w roku, aby to zrobić.
Ponieważ tygodnie są tej samej długości, można po prostu odjąć dni i tygodnie między ISO daty, która ma, a ISO daty, którą znasz w obu formach i dodać tę liczbę dni i tygodnie. (Nie ma znaczenia, czy te liczby są dodatnie lub ujemne, więc można wybrać inny dzień „stałe”, takich jak lis 28th.)
Edycja
poprawiłem tego powodu, jak to wskazał usłużnie przez @ JoSo, pierwszy dzień roku gregoriańskiego, który również należy do roku ISO, to 4 stycznia, a nie 5 stycznia. Jak wyjaśnia wyjaśnienie, nie ma znaczenia, która data zostanie wybrana jako punkt odniesienia, ale wybór czwartego stycznia sprawia, że wybór ten jest mniej "magiczny".
Czy możesz mi powiedzieć, czy naprawdę działa bez zarzutu w każdej sytuacji? – Geeocode
@GeorgeSolymosi Użyłem biblioteki testów Pythona dla hipotez w celu wyszukania jakichkolwiek poprawnych obiektów 'datetime', dla których ta funkcja nie jest odwrotnością' isocalendar'. Nie znaleziono żadnych/Zobacz https://github.com/jwg4/qual/blob/master/qual/tests/test_iso.py Nie jest to oczywiście gwarancja - byłbym zainteresowany usłyszeniem o jakichkolwiek błędach. Jeśli pracujesz zgodnie z logiką kodu, możesz lub nie być przekonanym, że robi to dobrze. – jwg
jest to bardziej skomplikowane niż to konieczne. Spójrz na odpowiedź Bena lub na Wikipedię. Czwarty dzień będzie równie dobry, a ponadto zawsze znajduje się w pierwszym tygodniu ISO roku ISO. –
Zaczynając w Pythonie 3.6, datetime.strptime()
wesprze dyrektyw %G
, %V
i %u
, więc można po prostu zrobić datetime.strptime('2015 1 2', '%G %V %u').date()
. Zobacz: https://hg.python.org/cpython/rev/acdebfbfbdcf
Jak Pythona 3.6 (obecnie in development), można korzystać z nowych %G
, %u
i %V
dyrektyw.Zobacz issue 12006 i updated documentation:
%G
ISO 8601 rok z wieku reprezentującą rok, który zawiera większą część tygodnia ISO (%V
).
%u
Dzień tygodnia ISO 8601 jako liczba dziesiętna, gdzie 1 oznacza poniedziałek.
%V
Tydzień ISO 8601 jako liczba dziesiętna z poniedziałkiem jako pierwszym dniem tygodnia. Tydzień 01 jest tydzień zawierający sty 4.
Podając łańcuch z roku, weeknumber i liczby dni tygodnia, to jest łatwe do analizowania tych się na bieżąco z:
from datetime import date
date.strptime('2002 01 1', '%G %V %u')
lub jako funkcja z całkowite nakłady:
from datetime import date
def date_from_isoweek(iso_year, iso_weeknumber, iso_weekday):
return date.strptime(
'{:04d} {:02d} {:d}'.format(iso_year, iso_weeknumber, iso_weekday)
'%G %V %u')
przez następne osób przybywających tutaj, krótszy, single-def, wersja dobrego rozwiązania Bena:
def iso_to_gregorian(iso_year, iso_week, iso_day):
jan4 = datetime.date(iso_year, 1, 4)
start = jan4 - datetime.timedelta(days=jan4.isoweekday()-1)
return start + datetime.timedelta(weeks=iso_week-1, days=iso_day-1)
- 1. Jaki jest najlepszy sposób na znalezienie kodu blokującego główny wątek?
- 2. Jaki jest właściwy sposób na znalezienie krawędzi między dwoma wierzchołkami?
- 3. Jaki jest najlepszy sposób na skopiowanie listy?
- 4. Jaki jest najlepszy sposób na naukę Erlanga?
- 5. Jaki jest najlepszy sposób na seed srand()?
- 6. Jaki jest najlepszy sposób na naukę CUDA?
- 7. Jaki jest najlepszy sposób na wdrożenie "timera"?
- 8. Najlepszy sposób na znalezienie/zastąpienie w kilku plikach?
- 9. Jaki jest najlepszy sposób na znalezienie daty "następny, ale jeden najnowszy" w SQL?
- 10. Jaki jest najszybszy sposób na znalezienie wszystkich wystąpień podłańcucha?
- 11. Najlepszy sposób na znalezienie elementów DOM z selektorami css
- 12. Najlepszy sposób na znalezienie elementu wejściowego "następnego" formularza w jQuery?
- 13. Najlepszy sposób na znalezienie pojedynczej liczby w parach lub trójek
- 14. Jaki jest najlepszy sposób wyczyszczenia tablicy łańcuchów?
- 15. Jaki jest najlepszy sposób zamknięcia gałęzi Mercurial?
- 16. Jaki jest najlepszy sposób obsługi wielu działań?
- 17. Jaki jest najlepszy sposób profilowania wykonywania javascript?
- 18. Jaki jest najlepszy sposób wyszukiwania GitHub?
- 19. Jaki jest najlepszy sposób implementacji protokołów?
- 20. Jaki jest najlepszy sposób tworzenia wyszukiwania whois?
- 21. Jaki jest najlepszy sposób przełączania zmiennej binarnej?
- 22. Jaki jest najlepszy sposób generowania mapy witryny?
- 23. Jaki jest najlepszy sposób symulacji java.lang.Thread?
- 24. Jaki jest najlepszy sposób uczenia się WCF?
- 25. Jaki jest najlepszy sposób przetestowania aplikacji szyny?
- 26. Jaki jest najlepszy sposób przetestowania narzędzia RedirectToAction?
- 27. Jaki jest najlepszy sposób wykonywania jQuery .change()
- 28. Jaki jest najlepszy sposób testowania usług WCF?
- 29. Jaki jest najlepszy sposób tworzenia wewnętrznych produktów?
- 30. Jaki jest najlepszy sposób odczytu GetResponseStream()?
Czy możesz wyjaśnić znaczenie 4 stycznia? Czy jest gdzieś odpowiedni opis normy kalendarza ISO? – Tom
Tom: z oficjalnej definicji ISO z pierwszego tygodnia (tygodnia zawierającego pierwszy czwartek roku) wynika, że 4 stycznia jest najpóźniej w tym tygodniu, od którego można rozpocząć 1. –
http://en.wikipedia.org/wiki/ISO_week_date – Tom