Go 언어 time 패키지를 활용한 날짜 및 시간 처리 가이드

Go 언어에서 날짜와 시간 처리는 표준 라이브러리인 time 패키지를 통해 이루어집니다. 이 패키지는 시간의 측정, 표시, 그리고 달력 계산(그레고리력 기반)을 위한 다양한 기능과 타입을 제공합니다.

현재 시간 및 날짜 구성 요소 추출

time.Time은 시간을 표현하는 핵심 구조체입니다. time.Now()를 호출하여 현재 시간 객체를 생성한 뒤, 연도, 월, 일 등의 세부 정보를 쉽게 추출할 수 있습니다.

func displayCurrentDateTime() {
    currentTime := time.Now()
    fmt.Printf("현재 시각: %v\n", currentTime)

    // Date()와 Clock() 메서드를 활용한 구성 요소 추출
    y, m, d := currentTime.Date()
    hh, mm, ss := currentTime.Clock()
    
    fmt.Printf("날짜: %d년 %d월 %d일\n", y, m, d)
    fmt.Printf("시간: %02d시 %02d분 %02d초\n", hh, mm, ss)
}

유닉스 타임스탬프 활용

타임스탬프는 1970년 1월 1일 00:00:00 UTC로부터 경과된 시간을 의미합니다. time 패키지는 초 단위와 나노초 단위의 타임스탬프를 모두 지원하며, 반대로 타임스탬프를 time.Time 객체로 변환하는 기능도 제공합니다.

func handleTimestamps() {
    currentTime := time.Now()
    
    // 타임스탬프 추출
    secTimestamp := currentTime.Unix()
    nanoTimestamp := currentTime.UnixNano()
    
    fmt.Printf("초 단위 타임스탬프: %d\n", secTimestamp)
    fmt.Printf("나노초 단위 타임스탬프: %d\n", nanoTimestamp)

    // 타임스탬프를 시간 객체로 복원
    convertedTime := time.Unix(secTimestamp, 0)
    fmt.Printf("복원된 시간: %v\n", convertedTime)
}

시간 간격과 Duration

time.Duration은 두 시간 지점 사이의 간격을 나노초 단위로 표현하는 타입입니다. 가독성을 위해 패키지 내부에 다양한 상수가 정의되어 있으며, 최대 약 290년 정도의 간격을 표현할 수 있습니다.

const (
    Nanosecond  Duration = 1
    Microsecond          = 1000 * Nanosecond
    Millisecond          = 1000 * Microsecond
    Second               = 1000 * Millisecond
    Minute               = 60 * Second
    Hour                 = 60 * Minute
)

예를 들어 time.Second는 1초를, time.Millisecond는 1밀리초를 의미합니다.

시간 연산 및 비교

시간 객체에 특정 간격을 더하거나 빼고, 두 시간의 선후 관계를 비교하는 다양한 메서드가 제공됩니다.

func timeArithmetic() {
    baseTime := time.Now()
    
    // 시간 더하기 (Add)
    futureTime := baseTime.Add(2 * time.Hour)
    fmt.Printf("2시간 후: %v\n", futureTime)
    
    // 시간 차이 구하기 (Sub)
    targetDate, _ := time.Parse("2006-01-02", "2025-01-01")
    diff := targetDate.Sub(baseTime)
    fmt.Printf("남은 시간 간격: %v\n", diff)
    
    // 시간 비교 (Before, After, Equal)
    fmt.Printf("baseTime이 futureTime 이전인가? %v\n", baseTime.Before(futureTime))
    fmt.Printf("baseTime이 futureTime 이후인가? %v\n", baseTime.After(futureTime))
    
    // Equal은 시区 정보까지 고려하여 비교함 (단순 == 연산자와 다름)
    fmt.Printf("두 시간이 동일한가? %v\n", baseTime.Equal(futureTime))
}

티커(Ticker)를 활용한 주기적 작업

특정 시간 간격으로 반복되는 작업을 수행할 때는 time.Ticker를 사용합니다. 채널을 통해 틱 이벤트를 수신하며, 리소스 누수를 방지하기 위해 사용 후 반드시 Stop()을 호출해야 합니다.

func runPeriodicTask() {
    ticker := time.NewTicker(500 * time.Millisecond)
    defer ticker.Stop()

    count := 0
    for t := range ticker.C {
        fmt.Printf("틱 발생 시각: %v\n", t)
        count++
        if count >= 3 {
            break // 3번 실행 후 루프 탈출
        }
    }
}

시간 포맷팅 및 파싱

Go 언어의 시간 포맷팅은 다른 언어에서 흔히 사용하는 YYYY-MM-DD 방식이 아닙니다. 대신 Go의 탄생일인 2006년 1월 2일 15시 04분 05초를 기준 템플릿으로 사용합니다. (기억법: 1, 2, 3, 4, 5, 6)

func formatTimeExamples() {
    currentTime := time.Now()
    
    // 24시간제 포맷팅
    fmt.Println(currentTime.Format("2006-01-02 15:04:05"))
    
    // 12시간제 포맷팅 (PM/AM 명시)
    fmt.Println(currentTime.Format("2006-01-02 03:04:05 PM"))
    
    // 커스텀 포맷
    fmt.Println(currentTime.Format("2006년 01월 02일 (Mon) 15시 04분"))
}

문자열을 시간 객체로 파싱할 때는 time.Parse 또는 특정 타임존을 고려한 time.ParseInLocation을 사용합니다.

func parseTimeString() {
    loc, err := time.LoadLocation("Asia/Seoul")
    if err != nil {
        fmt.Println("타임존 로딩 실패:", err)
        return
    }
    
    // 지정된 타임존과 포맷에 맞춰 문자열 파싱
    layout := "2006/01/02 15:04"
    timeStr := "2023/10/25 14:30"
    
    parsedTime, err := time.ParseInLocation(layout, timeStr, loc)
    if err != nil {
        fmt.Println("파싱 에러:", err)
        return
    }
    
    fmt.Printf("파싱된 시간 객체: %v\n", parsedTime)
    fmt.Printf("현재 시간과의 차이: %v\n", time.Since(parsedTime))
}

태그: go time 타임스탬프 Duration Ticker

6월 19일 00:48에 게시됨