• 2020. 8. 3.

    by. 윈썸지니

    반응형

    일자 선택

    프로그램 개발 시 많이 사용되는 것 중에 하나가 날짜 형식 변환 및 계산등을 많이 사용합니다. 

     

    만약 2020/8/2 이런 문자열을 보면 사람은 202082일 이구나로 인식 하지만 프로그램에서는 2020 년은 연도 882 2 일 이라고 알려줘야 합니다.

    그래야  2020/7/31에서 5일 후는 31+ 5 = 36 일이 아니고 85일 이라고 계산이 되어야 힙니다.

    두 날짜 사이의 일수, 시간 , 요일, 매월 첫번째 영업일, 매월 말,  주말에만 동작하는 프로그램 등등등의 많은 날짜 계산은  코딩시 자주 발생하는 일입니다.

     

    날짜 계산을 하려면 먼저 날짜 형식에 대해 알아야 합니다.

    이번 포스팅은 날짜 형식에 다루고 다음 포스팅에서 날짜 계산에 대해 포스팅합니다.

     

    이론만 하면 지루하므로 현재 시간을 구해 보겠습니다.

     

    파이썬에서는 datetime, time 모듈을 사용해서 시간을 다룹니다.

    먼저 현재 시간을 구해 봅니다.

    >>> import time

    >>>

    >>> time.time()

    1596349912.2476141

    >>>

     

    ? 시간을 구했는데 웬 숫자가 나옵니다.  위의 숫자의 의미는 197011000초를 기준으로 현재까지의 초 입니다.

    우리나라 시간이 반영 되었다면 + 9 시간을 기준으로 합니다.

     

    time 모듈에서 time.localtime( ) 를 사용하면 년 월 일 시간 분 초 의 형식을 가진 형태로 변환해 줍니다.

    잘 모르겠는 부분이 tm_wday는 요일로 0 ~ 6 까지의 숫자이며 월 ~ 일요일을 의미합니다. 0은 월요일 입니다. 2는 수요일을 뜻합니다.

    tm_yday 11일 부터의 일 수 입니다. tm_isdst 는 서머타임 적용 여부 입니다.

    >>> time.localtime()

    time.struct_time(tm_year=2020, tm_mon=8, tm_mday=2, tm_hour=16, tm_min=38, tm_sec=43, tm_wday=6, tm_yday=215, tm_isdst=0)

    >>> time.localtime(time.time())

    time.struct_time(tm_year=2020, tm_mon=8, tm_mday=2, tm_hour=16, tm_min=39, tm_sec=15, tm_wday=6, tm_yday=215, tm_isdst=0)

    >>>

     

    잠깐! 표준시에 대해 알아봅니다.

    표준시는 UTC 라고 합니다.

    UTC Coordinated Universal Time 으로 협정세계시로 197211일 부터 시행 되었으며, 197011일을 기준으로 합니다.

     

    우리나라는 여기에 9시간을 더한  UTC + 09:00 시간으로 KST Korea Standard Time 한국 표준시 입니다.

    지금 UTC, KST  이런 것을 설명하는 이유는 현재 시간을 구할 때 동작하는 시스템의 시간으로 가져 옵니다.

    시스템의 시간( Time Zone) UTC 로 설정 되어 있는 시스템도 있고 한국 시간(KST ) 또는 다른 나라 시간으로 설정되어 있을 수 있습니다.

     

    따라서 동작하는 시스템의 시간을 알아야 정확한 시간 계산을 할 수 있습니다.

    또는 시간대를 지정하여 현재 시간을 구할 수 있습니다. 아래 예제로 다룰 예정입니다.

     

    위의 예제에서 localtime() 의 경우 출력이 고정되어 있어서 원하는 형식에 맞게 포맷팅을 따로 해야 하나? 라는 생각을 할 텐데 원하는 형식으로 바꾸어 주는 함수를 제공합니다.

     

    시간을 원하는 형식으로 포맷팅합니다.

    strftime( “포멧”,  시간객체 ) 을 사용하면 시간 객체를 포맷에 맞는 문자열 형식으로 변환해 줍니다.

    아래는 예제 입니다.

    >>> time.strftime( "%Y/%m/%d", time.localtime())

    '2020/08/02’

    >>> time.strftime( "%Y/%m/%d %H:%M:%S", time.localtime())

    '2020/08/02 17:21:12'

    >>> time.strftime( "%Y/%m/%d %I %p", time.localtime())

    '2020/08/02 05 PM'

     

    위의 예제에서 %Y 는 연도 4자리, %m 은 월, %d 는 일 입니다.

    대소문자를 구분하고 대소문자로 다르게 인식 할 수 있으니 주의하세요.

    날짜 포맷 코드 표 입니다.

    지시자

    의미

    %a

    요일을 로케일의 축약된 이름으로.

    Sun, Mon, …, Sat (en_US);

    So, Mo, …, Sa (de_DE)

    %A

    요일을 로케일의 전체 이름으로.

    Sunday, Monday, …, Saturday (en_US);

    Sonntag, Montag, …, Samstag (de_DE)

    %w

    요일을 10진수로, 0은 일요일이고 6은 토요일입니다.

    0, 1, …, 6

    %d

    월중 일(day of the month)0으로 채워진 10진수로.

    01, 02, …, 31

    %b

    월을 로케일의 축약된 이름으로.

    Jan, Feb, …, Dec (en_US);

    Jan, Feb, …, Dez (de_DE)

    %B

    월을 로케일의 전체 이름으로.

    January, February, …, December (en_US);

    Januar, Februar, …, Dezember (de_DE)

    %m

    월을 0으로 채워진 10진수로.

    01, 02, …, 12

    %y

    세기가 없는 해(year)0으로 채워진 10진수로.

    00, 01, …, 99

    %Y

    세기가 있는 해(year)10진수로.

    0001, 0002, …, 2013, 2014, …, 9998, 9999

    %H

    (24시간제)0으로 채워진 십진수로.

    00, 01, …, 23

    %I

    (12시간제)0으로 채워진 십진수로.

    01, 02, …, 12

    %p

    로케일의 오전이나 오후에 해당하는 것.

    AM, PM (en_US);

    am, pm (de_DE)

    %M

    분을 0으로 채워진 십진수로.

    00, 01, …, 59

    %S

    초를 0으로 채워진 10진수로.

    00, 01, …, 59

    %f

    마이크로초를 왼쪽에 0으로 채워진 십진수로.

    000000, 000001, …, 999999

    %z

    ±HHMM[SS[.ffffff]] 형태의 UTC 오프셋 (객체가 나이브하면 빈 문자열).

    (비어 있음), +0000, -0400, +1030, +063415, -030712.345216

    %Z

    시간대 이름 (객체가 나이브하면 빈 문자열).

    (비어 있음), UTC, EST, CST

    %j

    연중 일(day of the year)0으로 채워진 십진수로.

    001, 002, …, 366

    %U

    연중 주 번호(일요일이 주의 시작)0으로 채워진 10진수로. 첫 번째 일요일에 선행하는 새해의 모든 날은 주 0으로 간주합니다.

    00, 01, …, 53

    %W

    연중 주 번호(월요일이 주의 시작)를 십진수로. 첫 번째 월요일에 선행하는 새해의 모든 말은 주 0으로 간주합니다.

    00, 01, …, 53

    %c

    로케일의 적절한 날짜와 시간 표현.

    Tue Aug 16 21:30:00 1988 (en_US);

    Di 16 Aug 21:30:00 1988 (de_DE)

    %x

    로케일의 적절한 날짜 표현.

    08/16/88 (None);

    08/16/1988 (en_US);

    16.08.1988 (de_DE)

    %X

    로케일의 적절한 시간 표현.

    21:30:00 (en_US);

    21:30:00 (de_DE)

    %%

    리터럴 '%' 문자.

    %

    reference : docs.python.org/ko/3/library/datetime.html

     

    strftime() 함수는 시간을 문자열로 변환해 줍니다.

    우리가 과거의 시간이나 미래의 시간을 특정하고 싶을 때는 문자열로 표현된 시간을 시간 객체로 변경 할 수도 있어야 합니다.

     

    strptime 함수를 사용하면 됩니다.

    위의 strftime 의 예제의 결과 값으로 나왔던 값을 다시 시간 객체로 변경해 봅니다.

    strptime(“ 시간 문자열“, “포맷“)  당연히 시간 문자열은 시간 형식에 맞아야 합니다.

    >>> time.strptime( '2020/08/02 17:21:12', "%Y/%m/%d %H:%M:%S" )

    time.struct_time(tm_year=2020, tm_mon=8, tm_mday=2, tm_hour=17, tm_min=21, tm_sec=12, tm_wday=6, tm_yday=215, tm_isdst=-1)

    >>> time.strptime( "2020/08/02 05 PM", "%Y/%m/%d %I %p" )

    time.struct_time(tm_year=2020, tm_mon=8, tm_mday=2, tm_hour=17, tm_min=0, tm_sec=0, tm_wday=6, tm_yday=215, tm_isdst=-1)

    >>>

     

    832일은 없으므로 오류가 발생 합니다.

    >>> time.strptime( "2020/08/32 17:21:12", "%Y/%m/%d %H:%M:%S" )

    Traceback (most recent call last):

      File "<pyshell#48>", line 1, in <module>

        time.strptime( "2020/08/32 17:21:12", "%Y/%m/%d %H:%M:%S" )

      File "C:\Users\hyejin\AppData\Local\Programs\Python\Python38\lib\_strptime.py", line 562, in _strptime_time

        tt = _strptime(data_string, format)[0]

      File "C:\Users\hyejin\AppData\Local\Programs\Python\Python38\lib\_strptime.py", line 349, in _strptime

        raise ValueError("time data %r does not match format %r" %

    ValueError: time data '2020/08/32 17:21:12' does not match format '%Y/%m/%d %H:%M:%S'

    >>>

     

    이번에는 datetime 모듈을 사용해 봅니다.

    먼저 datetime datetime 클래스와 timezone 클래스를 import 합니다.

    >>> from datetime import datetime, timezone

     

    오늘 일자를 구합니다. time 모듈과는 다르게 출력이 됩니다. today() 는 동작하는 시스템의 타임존을 따릅니다.

    >>> datetime.today()

    datetime.datetime(2020, 8, 2, 18, 0, 57, 555494)

     

    today() 와 같은 역할이지만 시간대를 설정할 수 있습니다. 기본은 현 시스템의 타임존 입니다. KST 입니다.

    >>> datetime.now()

    datetime.datetime(2020, 8, 2, 18, 1, 6, 199995)

     

    UTC 시간으로 현재 시간을 구하고 싶다면 아래와 같이 타임존을 인수로 전달해 줍니다.

    아래 예제는 3.8.2 버전으로 테스트 한 예제 입니다.

    3.6 이전 버전에는 datetime 모듈에 timezone 클래스가 없어서 pytz 라이브러리를 설치해서 시용해야 합니다.

    >>> datetime.now(timezone.utc)

    datetime.datetime(2020, 8, 2, 9, 1, 48, 518510, tzinfo=datetime.timezone.utc)

     

    datetime(year, month, day, hour=0, minute=0, second=0, microsecond=0 ) 은 특정 시간을 인수로 넣어서 시간 객체를 생성 할 수 있습니다.

    >>> x = datetime( 2020, 8, 2 )

    >>> x

    datetime.datetime(2020, 8, 2, 0, 0)

    >>> x = datetime( 2020, 8, 2, 18, 1, 6 )

    >>> x

    datetime.datetime(2020, 8, 2, 18, 1, 6)

    >>>  

     

    시간을 문자열로, 문자열을 시간으로 변환하는 방법은 time 에서 사용했던 함수와 동일합니다.

    >>> datetime.now().strftime( "%Y/%m/%d %H:%M:%S")

    '2020/08/02 18:57:12’

    >>> datetime.strptime( "2020/08/02 17:21:12", "%Y/%m/%d %H:%M:%S" )

    datetime.datetime(2020, 8, 2, 17, 21, 12)

    >>>

     

    datetime 객체는 각 속성별로 값을 추출할 수 있습니다.

    예제를 확인합니다

     

    연도를 추출합니다.

    >>> datetime.today().year

    2020

     

    월을 추출합니다.

    >>> x = datetime.today()

    >>> x.month

    8

    >>>

    x.year, x.month, x.day, x.hour, x.minute, x.second, x.microsecond 로 접근 할 수 있습니다.

     

    이상 날짜 표현에 대해 알아 보았습니다.

     

    다음 포스팅에서는 날짜 계산에 대한 포스팅입니다.

    반응형