KR_DateTime - somaz94/python-study GitHub Wiki

Python λ‚ μ§œμ™€ μ‹œκ°„ κ°œλ… 정리


1️⃣ datetime λͺ¨λ“ˆ

κ°€μž₯ 일반적으둜 μ‚¬μš©λ˜λŠ” λ‚ μ§œ/μ‹œκ°„ 처리 λͺ¨λ“ˆμ΄λ‹€.

from datetime import datetime, date, time, timedelta

# ν˜„μž¬ λ‚ μ§œμ™€ μ‹œκ°„
now = datetime.now()
print(now)  # 2024-01-20 15:30:00.123456

# νŠΉμ • λ‚ μ§œ/μ‹œκ°„ 생성
dt = datetime(2024, 1, 20, 15, 30)
print(dt)  # 2024-01-20 15:30:00

# λ‚ μ§œ 뢄리
print(dt.year)    # 2024
print(dt.month)   # 1
print(dt.day)     # 20
print(dt.hour)    # 15
print(dt.minute)  # 30

# date와 time 객체 생성
today = date.today()
current_time = time(14, 30, 0)

# datetime 객체 μ‘°ν•©
combined = datetime.combine(today, current_time)

βœ… νŠΉμ§•:

  • λ‚ μ§œ/μ‹œκ°„ 생성
  • 속성 μ ‘κ·Ό
  • ν˜„μž¬ μ‹œκ°„ 쑰회
  • λ‚ μ§œμ™€ μ‹œκ°„ 뢄리 및 μ‘°ν•©


2️⃣ λ‚ μ§œ/μ‹œκ°„ μ—°μ‚°

datetime 객체와 timedelta 객체λ₯Ό μ‚¬μš©ν•˜μ—¬ λ‚ μ§œμ™€ μ‹œκ°„ 연산을 μˆ˜ν–‰ν•  수 μžˆλ‹€.

# timedelta μ‚¬μš©
now = datetime.now()
tomorrow = now + timedelta(days=1)
next_week = now + timedelta(weeks=1)
two_hours_later = now + timedelta(hours=2)

# λ‚ μ§œ 차이 계산
date1 = date(2024, 1, 1)
date2 = date(2024, 12, 31)
diff = date2 - date1
print(diff.days)  # 365

# 볡합 timedelta 생성
complex_delta = timedelta(
    days=2,
    hours=3,
    minutes=45,
    seconds=30
)

# timedelta 속성
print(complex_delta.total_seconds())  # 초 λ‹¨μœ„ 총 μ‹œκ°„

βœ… νŠΉμ§•:

  • λ‚ μ§œ κ°„ μ—°μ‚°
  • μ‹œκ°„ 간격 계산
  • timedelta ν™œμš©
  • 볡합 μ‹œκ°„ 간격 처리
  • 초 λ‹¨μœ„ λ³€ν™˜


3️⃣ ν˜•μ‹ν™”μ™€ νŒŒμ‹±

λ‚ μ§œμ™€ μ‹œκ°„μ„ λ‹€μ–‘ν•œ ν˜•μ‹μ˜ λ¬Έμžμ—΄λ‘œ λ³€ν™˜ν•˜κ±°λ‚˜ λ°˜λŒ€λ‘œ λ¬Έμžμ—΄μ—μ„œ λ‚ μ§œ/μ‹œκ°„ 객체둜 λ³€ν™˜ν•  수 μžˆλ‹€.

# λ‚ μ§œ/μ‹œκ°„ ν˜•μ‹ν™”
now = datetime.now()
formatted = now.strftime("%Y-%m-%d %H:%M:%S")
print(formatted)  # 2024-01-20 15:30:00

# λ¬Έμžμ—΄μ„ λ‚ μ§œ/μ‹œκ°„μœΌλ‘œ νŒŒμ‹±
date_string = "2024-01-20 15:30:00"
parsed = datetime.strptime(date_string, "%Y-%m-%d %H:%M:%S")

# μ£Όμš” ν˜•μ‹ μ§€μ •μž
# %Y: 연도 (2024)
# %m: μ›” (01-12)
# %d: 일 (01-31)
# %H: μ‹œκ°„ (00-23)
# %M: λΆ„ (00-59)
# %S: 초 (00-59)
# %A: μš”μΌ 이름
# %B: μ›” 이름
# %c: ν˜„μ§€ν™”λœ λ‚ μ§œμ™€ μ‹œκ°„
# %x: ν˜„μ§€ν™”λœ λ‚ μ§œ
# %X: ν˜„μ§€ν™”λœ μ‹œκ°„
# %j: λ…„ 쀑 일(001-366)
# %W: λ…„ 쀑 μ£Ό(00-53)
# %Z: μ‹œκ°„λŒ€ 이름

# λ‹€μ–‘ν•œ ν˜•μ‹ 예제
print(now.strftime("%Yλ…„ %mμ›” %d일 %Hμ‹œ %MλΆ„"))  # 2024λ…„ 01μ›” 20일 15μ‹œ 30λΆ„
print(now.strftime("%A, %B %d, %Y"))  # Saturday, January 20, 2024
print(now.strftime("%c"))  # ν˜„μ§€ν™”λœ ν‘œν˜„
print(now.strftime("주차: %W, 일차: %j"))  # 주차: 03, 일차: 020

βœ… νŠΉμ§•:

  • λ‹€μ–‘ν•œ ν˜•μ‹ 지원
  • λ¬Έμžμ—΄ λ³€ν™˜
  • μœ μ—°ν•œ νŒŒμ‹±
  • κ΅­μ œν™” 지원
  • μ‚¬μš©μž μ •μ˜ ν˜•μ‹


4️⃣ μ‹œκ°„λŒ€ 처리

pytz λͺ¨λ“ˆμ„ μ‚¬μš©ν•˜μ—¬ λ‹€μ–‘ν•œ μ‹œκ°„λŒ€ κ°„μ˜ λ³€ν™˜κ³Ό 처리λ₯Ό ν•  수 μžˆλ‹€.

from datetime import datetime
import pytz

# μ‹œκ°„λŒ€ λͺ©λ‘
print(pytz.all_timezones)

# νŠΉμ • μ‹œκ°„λŒ€μ˜ ν˜„μž¬ μ‹œκ°„
seoul_tz = pytz.timezone('Asia/Seoul')
seoul_time = datetime.now(seoul_tz)
print(seoul_time)

# μ‹œκ°„λŒ€ λ³€ν™˜
utc_time = datetime.now(pytz.UTC)
local_time = utc_time.astimezone(seoul_tz)

# μ‹œκ°„λŒ€ 인식 λ‚ μ§œ/μ‹œκ°„ 객체 생성
aware_dt = seoul_tz.localize(datetime(2024, 1, 20, 15, 30))

# μ—¬λŸ¬ μ‹œκ°„λŒ€ 비ꡐ
timezones = [
    'America/New_York',
    'Europe/London',
    'Asia/Tokyo',
    'Australia/Sydney'
]

utc_now = datetime.now(pytz.UTC)
print(f"UTC μ‹œκ°„: {utc_now.strftime('%Y-%m-%d %H:%M:%S %Z')}")

for tz_name in timezones:
    tz = pytz.timezone(tz_name)
    local_time = utc_now.astimezone(tz)
    print(f"{tz_name}: {local_time.strftime('%Y-%m-%d %H:%M:%S %Z')}")

βœ… νŠΉμ§•:

  • μ‹œκ°„λŒ€ λ³€ν™˜
  • UTC 지원
  • pytz ν™œμš©
  • μ‹œκ°„λŒ€ 인식 객체
  • 닀쀑 μ‹œκ°„λŒ€ 비ꡐ


5️⃣ μ‹€μš©μ μΈ 예제

μ‹€μ œ κ°œλ°œμ—μ„œ 자주 μ‚¬μš©λ˜λŠ” λ‚ μ§œ/μ‹œκ°„ 처리 μ˜ˆμ œλ‹€.

from datetime import datetime, date, timedelta
import pytz

# λ‚˜μ΄ 계산 ν•¨μˆ˜
def calculate_age(birthdate):
    today = date.today()
    age = today.year - birthdate.year
    if today.month < birthdate.month or \
       (today.month == birthdate.month and today.day < birthdate.day):
        age -= 1
    return age

birthdate = date(1990, 6, 15)
age = calculate_age(birthdate)
print(f"λ‚˜μ΄: {age}μ„Έ")

# νŠΉμ • κΈ°κ°„ λ‚΄ λͺ¨λ“  μ›”μš”μΌ μ°ΎκΈ°
def get_all_mondays(start_date, end_date):
    mondays = []
    current = start_date
    
    # μ‹œμž‘μΌμ΄ μ›”μš”μΌμ΄ μ•„λ‹ˆλ©΄ λ‹€μŒ μ›”μš”μΌμ„ 찾음
    if current.weekday() != 0:  # 0은 μ›”μš”μΌ
        days_until_monday = 7 - current.weekday()
        current += timedelta(days=days_until_monday)
    
    # μ’…λ£ŒμΌκΉŒμ§€ 7일씩 μ¦κ°€ν•˜λ©° μ›”μš”μΌ μΆ”κ°€
    while current <= end_date:
        mondays.append(current)
        current += timedelta(days=7)
        
    return mondays

start = date(2024, 1, 1)
end = date(2024, 3, 31)
mondays = get_all_mondays(start, end)
print("2024λ…„ 1μ›”λΆ€ν„° 3μ›”κΉŒμ§€μ˜ λͺ¨λ“  μ›”μš”μΌ:")
for monday in mondays:
    print(monday.strftime("%Y-%m-%d"))

# 두 이벀트 κ°„μ˜ κ²ΉμΉ˜λŠ” μ‹œκ°„ 계산
def get_overlapping_duration(event1_start, event1_end, event2_start, event2_end):
    latest_start = max(event1_start, event2_start)
    earliest_end = min(event1_end, event2_end)
    
    if latest_start >= earliest_end:
        return timedelta(0)  # κ²ΉμΉ˜λŠ” λΆ€λΆ„ μ—†μŒ
        
    return earliest_end - latest_start

# 이벀트 μ‹œκ°„ μ„€μ •
event1_start = datetime(2024, 1, 20, 10, 0)
event1_end = datetime(2024, 1, 20, 12, 0)
event2_start = datetime(2024, 1, 20, 11, 0)
event2_end = datetime(2024, 1, 20, 13, 0)

overlap = get_overlapping_duration(event1_start, event1_end, event2_start, event2_end)
print(f"κ²ΉμΉ˜λŠ” μ‹œκ°„: {overlap}")

βœ… νŠΉμ§•:

  • λ‚˜μ΄ 계산
  • λ‚ μ§œ 비ꡐ
  • μš”μΌ 기반 필터링
  • κΈ°κ°„ 계산
  • 이벀트 μ‹œκ°„ 처리


6️⃣ time λͺ¨λ“ˆ

μ €μˆ˜μ€€ μ‹œκ°„ ν•¨μˆ˜μ™€ μ„±λŠ₯ 츑정에 μœ μš©ν•œ λͺ¨λ“ˆμ΄λ‹€.

import time

# ν˜„μž¬ μ‹œκ°„ (μœ λ‹‰μŠ€ νƒ€μž„μŠ€νƒ¬ν”„)
timestamp = time.time()
print(f"ν˜„μž¬ νƒ€μž„μŠ€νƒ¬ν”„: {timestamp}")

# ν˜„μž¬ μ‹œκ°„ λ¬Έμžμ—΄
time_string = time.ctime()
print(f"ν˜„μž¬ μ‹œκ°„: {time_string}")

# μ„±λŠ₯ μΈ‘μ •
def measure_performance(func, *args, **kwargs):
    start = time.perf_counter()  # 고해상도 μ„±λŠ₯ μΉ΄μš΄ν„°
    result = func(*args, **kwargs)
    end = time.perf_counter()
    execution_time = end - start
    return result, execution_time

# 예제 ν•¨μˆ˜
def calculate_sum(n):
    return sum(range(n))

result, execution_time = measure_performance(calculate_sum, 10000000)
print(f"κ²°κ³Ό: {result}, μ‹€ν–‰ μ‹œκ°„: {execution_time:.6f}초")

# μΌμ‹œ μ •μ§€
print("3초 λŒ€κΈ° μ‹œμž‘...")
time.sleep(3)
print("λŒ€κΈ° μ™„λ£Œ!")

# ꡬ쑰체 μ‹œκ°„
struct_time = time.localtime()
print(f"연도: {struct_time.tm_year}")
print(f"μ›”: {struct_time.tm_mon}")
print(f"일: {struct_time.tm_mday}")
print(f"μ‹œ: {struct_time.tm_hour}")
print(f"λΆ„: {struct_time.tm_min}")
print(f"초: {struct_time.tm_sec}")
print(f"μš”μΌ: {struct_time.tm_wday}")  # 0은 μ›”μš”μΌ

βœ… νŠΉμ§•:

  • νƒ€μž„μŠ€νƒ¬ν”„ 처리
  • μ‹œκ°„ μ§€μ—° (sleep)
  • 고해상도 μ„±λŠ₯ μΈ‘μ •
  • μ‹œκ°„ ꡬ쑰체 처리
  • μ‹œμŠ€ν…œ μˆ˜μ€€ μ‹œκ°„ ν•¨μˆ˜


7️⃣ λ‚ μ§œμ™€ μ‹œκ°„ 라이브러리

Pythonμ—μ„œ λ‚ μ§œμ™€ μ‹œκ°„ 처리λ₯Ό μœ„ν•œ μΆ”κ°€ λΌμ΄λΈŒλŸ¬λ¦¬μ™€ κ³ κΈ‰ κΈ°λŠ₯을 μ‚΄νŽ΄λ³Έλ‹€.

# dateutil 라이브러리 - κ°•λ ₯ν•œ λ‚ μ§œ/μ‹œκ°„ νŒŒμ‹±κ³Ό μ—°μ‚°
from dateutil import parser, rrule, relativedelta
from datetime import datetime

# μœ μ—°ν•œ λ¬Έμžμ—΄ νŒŒμ‹±
dt = parser.parse("Jan 20, 2024")
print(dt)  # 2024-01-20 00:00:00

dt = parser.parse("20-01-2024")
print(dt)  # 2024-01-20 00:00:00

dt = parser.parse("2024/01/20 15:30:45")
print(dt)  # 2024-01-20 15:30:45

# μƒλŒ€μ  λ‚ μ§œ 계산
now = datetime.now()
next_month = now + relativedelta.relativedelta(months=1)
previous_year = now - relativedelta.relativedelta(years=1)
next_birthday = now + relativedelta.relativedelta(month=6, day=15)

# λ³΅μž‘ν•œ κ·œμΉ™ 기반 λ‚ μ§œ 반볡
# λ§€μ›” 첫 번째 μ›”μš”μΌ κ΅¬ν•˜κΈ°
mondays = list(rrule.rrule(
    rrule.MONTHLY,
    byweekday=rrule.MO(1),  # λ§€μ›” 첫 번째 μ›”μš”μΌ
    dtstart=datetime(2024, 1, 1),
    until=datetime(2024, 12, 31)
))

print("2024λ…„ λ§€μ›” 첫 번째 μ›”μš”μΌ:")
for monday in mondays:
    print(monday.strftime("%Y-%m-%d"))

# arrow 라이브러리 - μ‚¬μš©ν•˜κΈ° μ‰¬μš΄ λ‚ μ§œ/μ‹œκ°„ 처리
import arrow

# 생성 및 ν˜•μ‹ν™”
now = arrow.now()
print(now)  # 2024-01-20T15:30:45.123456+09:00

# ν˜•μ‹ν™”
print(now.format("YYYY-MM-DD HH:mm:ss"))  # 2024-01-20 15:30:45

# μ‹œκ°„λŒ€ λ³€ν™˜
tokyo = now.to('Asia/Tokyo')
new_york = now.to('America/New_York')

# μƒλŒ€μ  μ‹œκ°„
tomorrow = now.shift(days=1)
last_week = now.shift(weeks=-1)

# 인간 μΉœν™”μ  ν‘œν˜„
print(now.humanize())  # just now
print(tomorrow.humanize())  # in a day
print(last_week.humanize())  # a week ago

βœ… νŠΉμ§•:

  • μœ μ—°ν•œ λ‚ μ§œ νŒŒμ‹±
  • μƒλŒ€μ  λ‚ μ§œ/μ‹œκ°„ 계산
  • 주기적 λ‚ μ§œ 생성
  • λ‹€μ–‘ν•œ ν˜•μ‹ν™” μ˜΅μ…˜
  • 인간 μΉœν™”μ  μ‹œκ°„ ν‘œν˜„
  • κ³ κΈ‰ μ‹œκ°„λŒ€ 처리


8️⃣ λ°μ΄ν„°λ² μ΄μŠ€μ™€ λ‚ μ§œ/μ‹œκ°„

λ°μ΄ν„°λ² μ΄μŠ€ μ‹œμŠ€ν…œκ³Ό μƒν˜Έμž‘μš©ν•  λ•Œ λ‚ μ§œμ™€ μ‹œκ°„μ„ μ²˜λ¦¬ν•˜λŠ” 방법을 μ•Œμ•„λ³Έλ‹€.

import sqlite3
from datetime import datetime

# λ°μ΄ν„°λ² μ΄μŠ€ μ—°κ²°
conn = sqlite3.connect("example.db")
cursor = conn.cursor()

# ν…Œμ΄λΈ” 생성
cursor.execute('''
CREATE TABLE IF NOT EXISTS events (
    id INTEGER PRIMARY KEY,
    name TEXT,
    start_time TIMESTAMP,
    end_time TIMESTAMP
)
''')

# λ‚ μ§œ/μ‹œκ°„ 데이터 μ‚½μž…
def add_event(name, start_time, end_time):
    cursor.execute(
        "INSERT INTO events (name, start_time, end_time) VALUES (?, ?, ?)",
        (name, start_time.strftime("%Y-%m-%d %H:%M:%S"), end_time.strftime("%Y-%m-%d %H:%M:%S"))
    )
    conn.commit()

# 이벀트 μΆ”κ°€
add_event("회의", datetime(2024, 1, 20, 14, 0), datetime(2024, 1, 20, 15, 0))
add_event("μ›Œν¬μƒ΅", datetime(2024, 1, 22, 9, 0), datetime(2024, 1, 24, 17, 0))

# λ‚ μ§œ/μ‹œκ°„ 기반 쿼리
def get_events_by_date(target_date):
    cursor.execute(
        """
        SELECT * FROM events 
        WHERE date(start_time) <= date(?) AND date(end_time) >= date(?)
        """,
        (target_date.strftime("%Y-%m-%d"), target_date.strftime("%Y-%m-%d"))
    )
    return cursor.fetchall()

# νŠΉμ • λ‚ μ§œμ˜ 이벀트 검색
events = get_events_by_date(datetime(2024, 1, 22))
for event in events:
    print(f"이벀트: {event[1]}, μ‹œμž‘: {event[2]}, μ’…λ£Œ: {event[3]}")

# 정리
conn.close()

βœ… νŠΉμ§•:

  • λ°μ΄ν„°λ² μ΄μŠ€ λ‚ μ§œ/μ‹œκ°„ μ €μž₯
  • λ‚ μ§œ ν˜•μ‹ λ³€ν™˜
  • μ‹œκ°„ 기반 쿼리
  • λ‚ μ§œ λ²”μœ„ 검색
  • SQLκ³Ό Python μ‹œκ°„ 객체 톡합


μ£Όμš” 팁

βœ… λͺ¨λ²” 사둀:

  • UTC μ‚¬μš© ꢌμž₯ (특히 μ—¬λŸ¬ μ‹œκ°„λŒ€ μ‚¬μš©μž λŒ€μƒ μ• ν”Œλ¦¬μΌ€μ΄μ…˜)
  • ISO ν˜•μ‹ ν™œμš© (ꡭ제 ν‘œμ€€)
  • μ‹œκ°„λŒ€ λ³€ν™˜ μ‹œ pytz λ˜λŠ” zoneinfo(Python 3.9+) μ‚¬μš©
  • λ‚ μ§œ λΉ„κ΅λŠ” date 객체 μ‚¬μš©
  • μ‹œκ°„ 츑정은 time.perf_counter() κ³ λ € (높은 정확도)
  • λŒ€μš©λŸ‰ λ‚ μ§œ μ²˜λ¦¬λŠ” Pandas ν™œμš©
  • λ¬Έμžμ—΄ νŒŒμ‹±μ—λŠ” dateutil.parser κ³ λ €
  • μ‚¬μš©μž μΉœν™”μ  ν‘œμ‹œμ—λŠ” arrow.humanize() ν™œμš©
  • DB μ €μž₯ μ‹œ UTC μ‹œκ°„ μ‚¬μš© 및 ν‘œμ€€ ν˜•μ‹ μ€€μˆ˜
  • μœ€λ…„κ³Ό 윀초 κ³ λ € (특히 μ²œλ¬Έν•™μ  계산)
  • 역사적 λ‚ μ§œ λ‹€λ£° λ•Œ 달λ ₯ μ‹œμŠ€ν…œ 차이 인지
  • λ‚ μ§œ/μ‹œκ°„ μ—°μ‚° κ²°κ³Ό 검증 (월말/연말 λ“± μ˜ˆμ™Έ 상황)
  • μ„±λŠ₯ μ€‘μš” μ‹œ time λͺ¨λ“ˆ μ‚¬μš©
  • 병렬 처리 μ‹œ thread-safe μ‹œκ°„ ν•¨μˆ˜ μ‚¬μš©


⚠️ **GitHub.com Fallback** ⚠️