메뉴 바로가기 검색 및 카테고리 바로가기 본문 바로가기

한빛출판네트워크

IT/모바일 >

타임스탬프, 그리고 파이썬으로 날짜와 시간 다루기

한빛미디어

|

2018-12-12

|

by 이지호

23,753

일반적으로 누군가와 만날 약속을 한다면 만나는 대상과 날짜, 시간 그리고 장소를 알려주고 만납니다. 그럼 이 때 날짜와 시간은 무엇을 기준으로 정하는 것일까요? 날짜야 어찌됐든 시간에 한정한다면 조선시대 세종의 명으로 장영실이 해시계를 만들어 사물에 비치는 그림자의 길이로 시간을 재었던 기록이 남아있습니다.

 

지금이야 시간을 나타낼때 하루는 24시간을 사용하지만 조선시대만 해도 하루는 12시간이 전부였습니다. 사극을 즐겨보는 사람이라면 왕이 밤늦은 시각에 후원을 돌아다니고 있으면 내시가 한 마디하는 것을 기억할 것입니다. '전하, 벌써 자시가 지났사옵니다. 그만 처소로 드시지요'

 

또는 왕이 누군가와 만날 약속을 진시에 보기로 하고 내시에게 '이보시오 상선, 진시까지 얼마나 남았소?' 라고 하면 내시가 '전하, 진시까지 반시진 남았사옵니다'라고 말하기도 합니다.

 

그럼 조선시대에는 분을 다루지 않았을까요? 물론 현재처럼 정확한 분의 개념을 사용하진 않았더라도 대략적인 분의 개념은 존재했습니다. 물론 더 많은 시간 이야기가 있지만 적어도 조선시대에 시간의 개념은 '십이지'로 분류하여 자시부터 해시까지를 시간으로 다루었습니다.

 

그럼 컴퓨터는 날짜와 시간을 어떻게 표현할까요? 정답은 '운영체제' 별로 다릅니다. 선뜻 이해되지 않죠? 컴퓨터는 기본적으로 날짜와 시간을 표현하는 방법이 정해져 있지 않습니다. 그렇기 때문에 '운영체제'별로 날짜와 시간을 표현하는 방법이 다른 것입니다. 윈도우는 1601-01-01 00:00:00 부터 현재 시간까지 몇 100ns 떨어져 있는지를 8바이트로 나타냅니다. 반면 유닉스와 리눅스는 1970-01-01 00:00:00부터 현재 시간까지의 초를 누적한 시간을 사용합니다.

 

이렇게 표현되는 시간을 '타임스탬프'라고 합니다. 타임스탬프는 시간은 되돌아가지 않는다는 점에 근거하여 일반적으로 '증명'을 필요로 하는 것에 자주 사용합니다.

 

그럼 1970년 1월 1일 0시 0분 0초는 어떻게 시작된 것일까요? 유닉스는 최초 개발 이후 시간 정보를 기록하기 위해 임의 날짜를 결정할 필요가 있었는데 공교롭게도 그 날짜를 1970년 1월 1일 0시 0분 0초라고 삼은 것입니다. 많은 사람들이 유닉스 시간이 1970년부터 시작하는 이유를 유닉스의 탄생 시각으로 알고 있지만 그건 사실이 아닙니다. 이미 1960년대 후반에 거칠게 만들어진 유닉스가 있었기 때문이죠.

 

유닉스 타임스탬프를 조금 더 쉽게 이해해볼까요? 여러분이 이 글을 읽는 시점부터 43초 뒤는 몇시 몇분 몇초일까요? 아마도 바로 대답하기 힘들 것입니다. 그런데 1970년 1월 1일 0시 0분 0초부터 43초라면 금방 계산해낼 수 있을 겁니다. 0초부터 시작하니 당연히 쉽게 계산해낼 수 있을 것이고 '초'로부터 분/시/일/월/연까지 계산해낼 수 있으니 유닉스 기준으론 초를 누적하는 것이 당연히 유리할 수 밖에 없습니다.

 

그럼 여러분께 질문을 던져볼게요. 한국에서 1970년 1월 1일 0시 0분 0초는 독일에서도 1970년 1월 1일 0시 0분 0초일까요? 이 질문의 답을 생각해냈다면 여러분은 지구가 둥글다는 사실을 인지했을 겁니다. 지구가 둥글다면 지구상의 어딘가는 태양 또는 달빛을 받는 시간대가 다르기 때문에 지구의 위치별로 시간은 동일하지 않다는 사실을 이해하게 됐을 겁니다.

 

이 때는 기준이 되는 시간이 필요한데 지구에선 이 시간을 크게 2가지 방법으로 나눠서 부릅니다. GMT와 UTC. 1970년 1월 1일 0시 0분 0초라면 GMT는 영국 그리니치 천문대를 기준으로 그리니치 천문대 왼쪽 방향은 – 시간대를, 오른쪽 방향은 + 시간대를 말합니다. 한국은 가슴 아픈 이야기지만 일제시대에 일제에 의해 도쿄와 함께 +9 시간대로 분류하고 있습니다. 반면 UTC는 협정 세계시라고 하는데 세슘의 원자 진동수를 기반으로 하는 시간대를 말하며 일반적으로 GMT와 값이 같습니다.

 

일반적으로 태양을 기준으로 하는 시간을 '태양시'라고 하는데 지구는 자전할 때 대부분은 일정한 속도로 자전하지만 자기장의 영향을 강하게 받을때는 느리게 자전하거나 조금 빠르게 움직이기도 합니다. 이 때문에 '태양시' 기준으로만 하면 정확한 시간을 알 수 없습니다. 이 문제를 해결하기 위해 '태양시'에 지구의 자전을 고려한 보정을 초단위로 하는데 이 시간을 '윤초'라고 합니다.

 

그런데 유닉스 타임스탬프는 이 '윤초'를 고려하지 않기 때문에 정확한 시간을 알 순 없지만 그럼에도 불구하고 태양시 기준으로 시간과 날짜를 표현하기에 좋은 방법입니다.

 

웹 프로그램을 작성하기 위해 많이 사용되고 있는 PHP도 mktime이란 함수로 유닉스 타임스탬프를 반환하고 있고 이 값에 기반하여 날짜와 시간 정보를 표현하는 date 함수도 있으니 유닉스 타임스탬프가 얼마나 처리하기 쉬운지 알 수 있습니다.

 

유닉스 타임스탬프는 시스템이나 프로그램 내부적으로 사용될 때는 다루기 쉽지만 DB에 저장하고 DB에서 확인한다면 예상치 못한 상황에 직면할 수 있습니다. 예를 들어 이런 상황을 고려해보죠. DB에 저장되어 있는 게시물 중 작성일자가 2018년 12월 1일부터 2018년 12월 31일까지 작성된 게시물을 가져오고자 했을때 게시물 작성일자가 1544198052와 같은 유닉스 타임스탬프라면 이 값이 가리키는 날짜/시간 정보는 한 눈으로 이해할 수 없습니다.

 

물론 데이터베이스 설계 입장으로 보면 날짜/시간 정보를 저장하는 컬럼 타입은 DB마다 다르고 이를 다루는 데이터베이스 함수도 다르므로 숫자 형태로 저장하는 것이 이점을 가져올 수도 있으나 장기적인 관점에서 보면 날짜/시간 정보는 시스템 정보의 저장 목적이 아니고 직전에 제시한 문제 등에 부딪치지 않으려면 별도의 날짜/시간 데이터 타입을 사용하는 것이 좋습니다.

 

과거에는 데이터베이스를 사용하는 프로그램에서 날짜/시간 전용 컬럼에 접근해서 값을 가지고 와서 사용하는 것이 꽤 불편했고 이해해야 하는 부분이 적지 않았지만 최근 ORM(객체 관계 맵핑) 솔루션의 사용이 늘어나면서 이러한 전용 컬럼의 값이 프로그램 언어에서 지원하는 날짜/형식 데이터 타입으로 자동 전환되기 때문에 프로그램 구현은 물론이고 SQL을 직접 사용해 날짜/시간을 다룰 수 있으니 과거보다는 분명 나아진 형편일 것입니다.

 

그러나 여전히 유닉스 타임스탬프를 사용해 연산할 일이 없는 것은 아닙니다. 타임스탬프로부터 날짜/시간을 가져오거나 날짜/시간을 타임스탬프로 변환해야 할 수도 있습니다.

 

이러한 작업을 도구의 도움없이 하려면 꽤 시간이 걸리지만 파이썬을 사용하면 이런 일을 쉽게 할 수 있습니다. 여기에서는 아래와 같은 5가지 일을 해봅니다.

 

1. 현재 날짜/시간을 생성하기

2. 특정 날짜/시간을 생성하기

3. 날짜/시간으로부터 타임스탬프 값 얻어오기

4. 타임스탬프로부터 날짜/시간 얻어오기

5. 날짜/시간에 시간을 더하거나 빼기

 

파이썬에선 이러한 작업을 하기 위해 파이썬에 내장된 datetime 모듈을 사용합니다. 아래에서 제시할 코드는 모두 datetime을 사용합니다.

 

1. 현재 날짜/시간을 생성하기

>>> import datetime

>>> current_time = datetime.datetime.now()

>>> current_time

datetime.datetime(2018, 12, 8, 0, 54, 12)

 

2. 특정 날짜/시간을 생성하기

>>> import datetime

>>> old_time = datetime.datetime(2018,12,8,0,54,12)

>>> old_time

datetime.datetime(2018, 12, 8, 0, 54, 12)

 

3. 날짜/시간으로부터 타임스탬프 값 얻어오기

>>> current_time.timestamp()

 

4. 타임스탬프로부터 날짜/시간 얻어오기

>>> new_time = datetime.datetime.fromtimestamp(1544212855)

 

5. 날짜/시간에 시간을 더하거나 빼기

>>> import datetime

>>> # 43초 뒤의 시간 구하기

>>> current_time2 = current_time + datetime.timedelta(seconds=43)

>>> # 1시간 10분 12초 뒤의 시간 구하기

>>> current_time2 = current_time + datetime.timedelta(hours=1, minutes=10, seconds=12)

>>> # 7일 뒤의 시간 구하기

>>> current_time3 = current_time + datetime.timedelta(days=7)

 

앞에 제시한 코드들은 파이썬을 사용해 날짜/시간을 만들고 타임스탬프로의 상호 전환 그리고 시간에 시간을 더하는 것 까지의 내용을 살펴봤습니다. datetime 모듈을 사용하니까 전체 설명해드리면 좋겠지만 이 문서에서는 사용한 메서드나 객체만 설명하겠습니다.

 

파이썬에서 날짜/시간을 한 번에 다루는 datetime 모듈의 객체 datetime 클래스의 인스턴스입니다. 그러니까 타임스탬프로 값을 전환하거나 타임스탬프로부터 날짜/시간은 datetime 객체로 반환된다는 사실을 기억하면 됩니다.

 

다음으로 타임스탬프의 상호 교환입니다. 타임스탬프의 생성은 datetime 클래스의 timestamp 메서드를 인자없이 호출합니다. 타임스탬프로부터 datetime 객체를 생성하는 것은 datetime 클래스의 fromtimestamp 메서드에 datetime 객체로 생성하려는 타임스탬프 값을 전달합니다.

 

이렇게 만들어진 datetime 객체는 임의의 시간을 더하거나 뺄 수 있습니다. 코드에서는 더하는 코드만 보여드렸는데 이 때 사용하는 클래스는 timedelta 클래스입니다. 이 클래스는 임의의 시간 조각을 가진 객체입니다. 시간 조각이란 앞서 코드에서 보는 것처럼 43초, 7일 등의 시간만 가지고 있는 것을 말합니다.

 

지금까지 파이썬으로 날짜/시간을 다루는지 살펴봤습니다. 날짜/시간을 다루는 것은 많은 경우 매우 복잡하고 어렵지만 파이썬을 사용해 위와 같은 작업을 쉽게 할 수 있었습니다. 물론 그 이야기를 하기 이전에 타임스탬프의 역사에 대해 알아보기도 했습니다. 여러분도 파이썬과 함께 재미있는 프로그래밍 생활이 되길 희망합니다.^^

 

Have a Nice Programming with Python!

댓글 입력
자료실