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))
}