기본 콘텐츠로 건너뛰기

pandas_ta를 적용한 통계적 인덱스 지표

[python] 날짜와 시간 다루기: datetime 패키지

날짜와 시간 다루기: datetime 패키지

내용

datetime 패키지는 4개의 클래스로 구성됩니다.

표 1. datetime패키지의 클래스
클래스내용
datetime() 날짜와 시간을 저장
date() 날짜만 저장
time() 시간만 저장
timedelta() 시간 구간의 정보를 저장
import datetime as dt

datetime 클래스

datetime 클래스는 인스턴스 생성없이 적용할 수 있는 클래스메서드(Classmethod)입니다. 이 클래스는 년, 월, 일, 시, 분, 초, 마이크로초등의 인수를 전달할 수 있으며 모두 정수입니다.

dt.datetime(2024, 10, 25, 13, 20)
datetime.datetime(2024, 10, 25, 13, 20)

이 클래스의 메소드 now()는 실행시의 날짜와 시간을 반환합니다.

a=dt.datetime.now()
a
datetime.datetime(2024, 10, 25, 18, 2, 12, 658796)

다음의 속성을 사용하여 결과를 분리하여 나타낼 수 있습니다.

표 2. datetime 클래스의 속성과 메서드
속성내용메서드내용
year 연도 반환 weekday() 요일반환(0 ~ 6 &rarrr; 월 ~ 금)
month 월 반환 strftime() 문자열 반환
day일 반환 date() 날짜정보만 가지는 date 클래스 객체 반환
hour, minute 시, 분 반환 time() 시간 정보만 time 클래스 객체 반환
second, microsecond 초, 마이크로 초 반환strptime()문자열을 datetime 객체로 전환
a.year, a.month, a.day
(2024, 10, 25)
a.hour, a.minute, a.second, a.microsecond
(18, 2, 12, 658796)
a.weekday()
4
a.date()
datetime.date(2024, 10, 25)

strftime() 메서드를 적용하여 문자열로 전환을 위한 객체의 호출을 위해 다음의 기호를 사용합니다(참조).

표 3. 날짜와 시간을 호출 기호
속성내용
%Y, %y4자리 연도 숫자, 2자리 연도
%m2자리 월 숫자
%d2자리 일 숫자
%H24시간 형식 2자리 시간 숫자
%M2자리 분 숫자
%S2자리 초 숫자
%A영어로 된 요일 문자열
%B영어로 된 월 문자열
print(a.strftime("%Y-%m-%d"))
print(a.strftime("%y-%m-%d"))
2024-10-25
24-10-25
a.strftime("%B, %A")
'October, Friday'

반대로 문자열을 datetime 클래스 객체로 만들기 위해 strptime() 메서드를 사용합니다.

x="2024-10-21"
type(x), x
(str, '2024-10-21')
y=dt.datetime.strptime(x, "%Y-%m-%d")
y, type(y)
(datetime.datetime(2024, 10, 21, 0, 0), datetime.datetime)

date 클래스

date 클래스는 날짜 객체를 생성하며 인수로 정수인 year, month, day를 전달합니다.

datetime.date(year, month, day)

이 클래스로 나타낼 수 있는 최대와 최소의 날짜는 속성 max, min를 사용하여 확인할 수 있습니다.

mx=dt.date.max
mn=dt.date.min
print(f"최소: {mn}, 최대: {mx}")
최소: 0001-01-01, 최대: 9999-12-31

메서드 today()는 현재 날짜를 나타냅니다

dt.date.today()
datetime.date(2024, 10, 25)

위와 같이 현재의 시간은 time.time() 함수로 확인할 수 있습니다. 이 함수는 1970년 1월 1일 0시 0분 0초로부터 현재의 시간을 초로 전환하여 반환합니다.

import time
preSec=time.time()
preSec
1729854897.0117917

위 결과는 date 클래스의 메서드 fromtimestamp()로 정상적인 날짜로 환원할 수 있습니다. 즉, 이 메서드의 인수는 기준일로부터 계산되는 초(second)입니다.

dt.date.fromtimestamp(preSec)
datetime.date(2024, 10, 25)

메서드 date.fromordinal()는 fromtimestamp()와 유사하지만 기준이 1년 1월 1일이고 전달해주는 정수는 day이다. 즉, fromordinal() 함수는 일기준이 된다.

dt.date.fromtimestamp(100)
datetime.date(1970, 1, 1)
dt.date.fromordinal(100)
datetime.date(1, 4, 10)

data 클래스 속성으로 표 2에서 나타낸 year, month, day를 사용할 수 있습니다.

d=dt.date(2010, 7, 10)
d.year, d.month, d.day
(2010, 7, 10)
표 4. data 클래스 메서드
메서드내용
replce(year, month, day) 전달한 인수값이 객체에 대응되는 부분을 치환
timetuple() 객체의 모든 정보를 반환
toordinal() 1년 1월 1일 을 기준으로 객체의 날짜까지 경과한 일수를 반환
weekday() 요일을 정수로 반환, 0 ~ 6 → 월 ~ 일
isoweekday() 요일을 정수로 반환, 1 ~ 7 → 월 ~ 일
isocalendar() 객체의 년, 경과한 주(week)수, 요일(isoweekday()와 같음)을 반환
isoformat(),
__str__()
'YYYY-MM-DD' 형식의 문자열로 반화
ctime() 문자열로 반환(위와 다른 형식)
strftime(형식),
__format__(형식)
형식과 같이 문자열로 반환
d=dt.date(2023, 12, 2)
d
datetime.date(2023, 12, 2)
d1=d.replace(year=2024)
d1
datetime.date(2024, 12, 2)
d1.timetuple()
time.struct_time(tm_year=2024, tm_mon=12, tm_mday=2, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=0, tm_yday=337, tm_isdst=-1)
d1.timetuple()[0]
2024
d.toordinal()
738856
d.weekday(), d.isoweekday()
(5, 6)
a=d.isoformat()
a
'2023-12-02'
type(a)
str
dt.datetime.strptime(a, '%Y-%m-%d')
datetime.datetime(2023, 12, 2, 0, 0)
d.__str__()
'2023-12-02'
d.ctime()
'Sat Dec  2 00:00:00 2023'
d.strftime("%y/%m/%d")
'23/12/02'
d.__format__("%y/%m/%d")
'23/12/02'

timedelta 클래스

위의 소개한 datetime, date 클래스를 사용하여 같은 형태의 객체들 사이의 연산이 가능합니다.

d=dt.datetime(2023, 12, 2)
d1=dt.datetime(2024, 2, 7)
d-d1
datetime.timedelta(days=-67)
d=dt.date(2023, 12, 2)
d1=dt.date(2024, 2, 7)
d-d1
datetime.timedelta(days=-67)
d=dt.datetime(2023, 12, 2)
d1=dt.date(2024, 2, 7)
d-d1
TypeError: unsupported operand type(s) for -: 'datetime.datetime' and 'datetime.date'

위 결과와 같이 두 datatime 또는 date 객체들 사이의 차이를 나타내는 자료형은 timedelta입니다. 역으로 두 객체와 datetime.timedelta() 클래스로 생성한 객체와의 연산이 가능합니다.

timedelta(days=0, seconds=0, microseconds=0, milliseconds=0, minutes=0, hours=0, weeks=0)

d=dt.date(2023, 12, 2)
timeD=d-dt.timedelta(days=3)
timeD
datetime.date(2023, 11, 29)

위 timedelta()의 인수들에서 month와 year는 없습니다. 즉, 이들에 의한 계산은 이루어지지 않습니다.

timeD=d-dt.timedelta(weeks=3)
timeD
datetime.date(2023, 11, 11)
timeD=d-dt.timedelta(months=3)
timeD
TypeError: 'months' is an invalid keyword argument for __new__()"

이 클래스에 전달한 인수값은 다음과 같이 날짜, 초, 마이크로초로 환산하여 반환합니다.

  • 1usec=1000 msec
  • 1 min = 60 sec
  • 1 hr= 3600 sec
  • 1 week = 7days
a=dt.timedelta(seconds=10)
b=dt.timedelta(minutes=5)
c=dt.timedelta(hours=5)
d=dt.timedelta(days=3)
e=dt.timedelta(weeks=3)
print(f"sec to sec: {a}\nmin to sec: {b}\nhour to sec: {c}\ndya to day : {d}\nweek to day: {e}")
sec to sec: 0:00:10
min to sec: 0:05:00
hour to sec: 5:00:00
dya to day : 3 days, 0:00:00
week to day: 21 days, 0:00:00

위 객체들의 자료형은 모두 timedelta입니다.

a, b, c, d, e
(datetime.timedelta(seconds=10),
 datetime.timedelta(seconds=300),
 datetime.timedelta(seconds=18000),
 datetime.timedelta(days=3),
 datetime.timedelta(days=21))

위 결과와 같이 timedelta 객체(인스턴스)는 .day, .second, .microsecond 속성을 소유합니다.

d=dt.timedelta(days=3, seconds=45, microseconds=2)
d
datetime.timedelta(days=3, seconds=45, microseconds=2)
d.day, d.second, d.microsecond
(3, 45, 2)

timedelta 객체는 +, - 연산 뿐만 아니라 *, / 연산도 가능합니다.

d=dt.datetime.now()
d
datetime.datetime(2024, 10, 26, 9, 45, 15, 418320)
d_del=dt.timedelta(days=5)
d1=d+d_del
d1
datetime.datetime(2024, 10, 31, 9, 45, 15, 418320)
d1.day
31
d2=d-2*d_del
d2
datetime.datetime(2024, 10, 16, 9, 45, 15, 418320)
d_del/2
datetime.timedelta(days=2, seconds=43200)
d3=d+d_del/2
d3
datetime.datetime(2024, 10, 28, 21, 45, 15, 418320)

str()repr() 함수를 적용하여 문자열로 형변환할 수 있습니다. repr()의 경우는 객체에 정보를 포함합니다.

d4=str(d3)
d4, type(d4)
('2024-10-28 21:45:15.418320', str)
d5=repr(d3)
d5, type(d5)
('datetime.datetime(2024, 10, 28, 21, 45, 15, 418320)', str)

timedelta() 클래스의 메서드 total_seconds()를 적용하여 전달한 모든 인수를 초로 환산할 수 있습니다.

dt.timedelta(days=365).total_seconds()
31536000.0

댓글

이 블로그의 인기 게시물

[Linear Algebra] 유사변환(Similarity transformation)

유사변환(Similarity transformation) n×n 차원의 정방 행렬 A, B 그리고 가역 행렬 P 사이에 식 1의 관계가 성립하면 행렬 A와 B는 유사행렬(similarity matrix)이 되며 행렬 A를 가역행렬 P와 B로 분해하는 것을 유사 변환(similarity transformation) 이라고 합니다. $$\tag{1} A = PBP^{-1} \Leftrightarrow P^{-1}AP = B $$ 식 2는 식 1의 양변에 B의 고유값을 고려한 것입니다. \begin{align}\tag{식 2} B - \lambda I &= P^{-1}AP – \lambda P^{-1}P\\ &= P^{-1}(AP – \lambda P)\\ &= P^{-1}(A - \lambda I)P \end{align} 식 2의 행렬식은 식 3과 같이 정리됩니다. \begin{align} &\begin{aligned}\textsf{det}(B - \lambda I ) & = \textsf{det}(P^{-1}(AP – \lambda P))\\ &= \textsf{det}(P^{-1}) \textsf{det}((A – \lambda I)) \textsf{det}(P)\\ &= \textsf{det}(P^{-1}) \textsf{det}(P) \textsf{det}((A – \lambda I))\\ &= \textsf{det}(A – \lambda I)\end{aligned}\\ &\begin{aligned}\because \; \textsf{det}(P^{-1}) \textsf{det}(P) &= \textsf{det}(P^{-1}P)\\ &= \textsf{det}(I)\end{aligned}\end{align} 유사행렬의 특성 유사행렬인 두 정방행렬 A와 B는 'A ~ B' 와 같...

유리함수 그래프와 점근선 그리기

내용 유리함수(Rational Function) 점근선(asymptote) 유리함수 그래프와 점근선 그리기 유리함수(Rational Function) 유리함수는 분수형태의 함수를 의미합니다. 예를들어 다음 함수는 분수형태의 유리함수입니다. $$f(x)=\frac{x^{2} - 1}{x^{2} + x - 6}$$ 분수의 경우 분모가 0인 경우 정의할 수 없습니다. 이와 마찬가지로 유리함수 f(x)의 정의역은 분모가 0이 아닌 부분이어야 합니다. 그러므로 위함수의 정의역은 분모가 0인 부분을 제외한 부분들로 구성됩니다. sympt=solve(denom(f), a); asympt [-3, 2] $$-\infty \lt x \lt -3, \quad -3 \lt x \lt 2, \quad 2 \lt x \lt \infty$$ 이 정의역을 고려해 그래프를 작성을 위한 사용자 정의함수는 다음과 같습니다. def validX(x, f, symbol): ① a=[] b=[] for i in x: try: b.append(float(f.subs(symbol, i))) a.append(i) except: pass return(a, b) #x는 임의로 지정한 정의역으로 불연속선점을 기준으로 구분된 몇개의 구간으로 전달할 수 있습니다. #그러므로 인수 x는 2차원이어야 합니다. def RationalPlot(x, f, sym, dp=100): fig, ax=plt.subplots(dpi=dp) # ② for k in x: #③ x4, y4=validX(k, f, sym) ax.plot(x4, y4) ax.spines['left'].set_position(('data', 0)) ax.spines['right...

부분분수의 미분

내용 방법 1 방법 2 방법 3 부분분수의 미분 분수의 미분은 일정한 공식 을 적용하여 계산할 수 있습니다. 그러나 분수 자체가 단순한 표현으로 이루어지지 않았다면 미분 과정이나 결과는 매우 복잡할 수 있습니다. 만약 복잡한 분수 함수를 간단한 분수들로 분해할 수 있다면 계산이 보다 간편해질 것입니다. 이와 같이 분해된 간단한 분수들을 부분분수 라고 합니다. 예를 들어 다음 두 분수의 합을 계산해 봅니다. $$\begin{align} \frac{1}{x+1}+\frac{2}{x-1}&=\frac{x-1+2(x+1)}{(x+1)(x-1)}\\ &=\frac{3x+1}{x^2-1} \end{align}$$ 위 과정은 3개 이상의 여러 분수에서도 이루어질 수 있습니다. 또한 역으로 진행될 수 있습니다. 즉, 분수를 부분 분수로 분할할 수 있습니다. 그러나 이러한 과정은 대수분수 (분자의 가장 큰 차수가 분모의 최고의 차수보다 작은 분수)에서만 이루어질 수 있습니다. 예를 들어 $\displaystyle \frac {x^2+2}{x^2-1}$의 경우는 분자와 분모의 차수는 2차로 같습니다. 이러한 경우 다음과 같이 분리할 수 있습니다. $$\frac{x^2+2}{x^2-1}=1+\frac{3}{x^2-1}$$ 위의 식 중 $\displaystyle \frac{3}{x^2-1}$은 분자의 차수가 분모의 차수 보다 낮은 대수 분수이므로 부분 분수로 분리할 수 있습니다. 이와같이 부분 분수로 분해하는 방법은 다음과 같이 몇 가지로 구분할 수 있습니다. 방법 1 위 예의 결과 $\displaystyle \frac{3x+1}{x^2-1}$의 경우를 역으로 생각해 봅니다. 분모의 인수분해가 가능하면 그 분모의 인수에 의해 다음과 같이 분해할 수 있습니다. $$\begin{align} \frac{3x+1}{x^2-1}&=\frac{3x+1}{(x+1)(x-1)}\\ &=\frac{A}{x+1...