DateTime.isocalendar ()의 역수를 찾는 가장 좋은 방법은 무엇입니까?
문제
파이썬 datetime.isocalendar()
메소드는 튜플을 반환합니다 (ISO_year, ISO_week_number, ISO_weekday)
주어진 datetime
물체. 해당 역 함수가 있습니까? 그렇지 않다면, 1 년, 주 숫자 및 요일에 주어진 날짜를 쉽게 계산할 수있는 방법이 있습니까?
해결책
나는 최근 에이 문제를 직접 해결해야 했고이 해결책을 제시했다.
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)
몇 가지 테스트 사례 :
>>> 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)
다른 팁
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)
이것은 @Benjames의 매우 좋은 답변에서 채택되었습니다. 연중 첫날을 알 필요가 없습니다. 당신은 확실히 같은 ISO 연도에있는 날짜와 그 날짜의 ISO 달력 주 및 날의 예를 알아야합니다.
1 월 4 일은 단순히 한 가지 예입니다. 벤이 지적했듯이 Jan의 4 번째는 항상 같은 ISO 년과 그레고리 연도에 속하며 연도의 첫날이기 때문입니다.
몇 주가 모두 같은 길이이므로 원하는 날짜의 ISO와 두 형태로 알고있는 날짜의 ISO 사이의 일과 몇 주를 단순히 빼고 해당 일과 몇 주를 추가 할 수 있습니다. (이 숫자가 긍정적인지 부정적인지는 중요하지 않으므로 12 월 28 일과 같은 다른 '고정일'을 선택할 수 있습니다.)
편집하다
@joso가 도움이되었던 것처럼 Gregorian Year의 첫날은 ISO 연도에 속한 1 월 5 일이 아니기 때문에 이것을 수정했습니다. 설명에서 알 수 있듯이, 어떤 날짜가 참조 지점으로 선택되었는지는 중요하지 않지만 1 월 4 일을 선택하면이 선택이 '마법'을 덜 만듭니다.
Python 3.6 기준으로 새로운 것을 사용할 수 있습니다. %G
, %u
그리고 %V
지침. 보다 문제 12006 그리고 업데이트 된 문서:
%G
ISO 주간의 큰 부분을 포함하는 연도를 대표하는 세기의 ISO 8601 년 (%V
).
%u
ISO 8601 주중 10 진수는 1 월 1 일 월요일입니다.
%V
ISO 8601 주 월요일은 월요일의 첫 번째 요일로 소수점 숫자입니다. 01 주차는 1 월 4 일을 포함하는 주입니다.
연도, 주중 및 주중 번호의 문자열이 주어지면 다음과 같은 날짜를 파악할 수 있습니다.
from datetime import datetime
datetime.strptime('2002 01 1', '%G %V %u').date()
또는 정수 입력이있는 함수로서 :
from datetime import datetime
def date_from_isoweek(iso_year, iso_weeknumber, iso_weekday):
return datetime.strptime(
'{:04d} {:02d} {:d}'.format(iso_year, iso_weeknumber, iso_weekday),
'%G %V %u').date()
Python 3.6에서 시작하여 datetime.strptime()
지원합니다 %G
, %V
그리고 %u
지시문이므로 간단하게 할 수 있습니다 datetime.strptime('2015 1 2', '%G %V %u').date()
. 보다: https://hg.python.org/cpython/rev/acdebfbfbdcf
다음 사람들이 여기에 오는 사람들은 벤의 좋은 해결책의 짧은 단일 디프 버전입니다.
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)
%w는 ISO 주 (1-53)와 동일하지 않은 주 # (0-53)입니다. %W가 작동하지 않는 가장자리 케이스가 있습니다.
Ben James가 게시 한 것과 유사한 솔루션을 생각해 냈지만 단일 기능을 사용했습니다.
import datetime
def getDateFromWeek(year,week,day):
"""Method to retrieve the date from the specified week, year and weekday"""
year_start = datetime.date(year,1,1)
ys_weekday = year_start.weekday()
delta = (week*7)+(day-ys_weekday)
if ys_weekday<4:
delta -= 7
return year_start + datetime.timedelta(days=delta)
2020 년 마지막 주와 2021 년 첫 주와 같은 경계 값으로 테스트했으며 꽤 잘 작동했습니다.
편집 : 이것을 무시하십시오. 가장자리 케이스는 고통입니다. 벤의 솔루션과 함께 가십시오.
좋아, 면밀한 검사에서 나는 그것을 알아 차렸다 strptime
가지다 %W
그리고 %w
매개 변수, 다음은 작동합니다.
def fromisocalendar(y,w,d):
return datetime.strptime( "%04dW%02d-%d"%(y,w-1,d), "%YW%W-%w")
몇 개의 Gotchas : ISO 주 번호는에서 시작됩니다. 1
, 동안 %W
시작 0
. ISO 주일은 시작됩니다 1
(월요일)은 동일합니다 %w
, 그래서 일요일은 아마도 있어야 할 것입니다 0
, 아니다 7
...