DateTime.isocalendar ()의 역수를 찾는 가장 좋은 방법은 무엇입니까?

StackOverflow https://stackoverflow.com/questions/304256

  •  08-07-2019
  •  | 
  •  

문제

파이썬 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...

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top