Golang에서 반복 처리 날짜
Golang에서 반복 처리 날짜
안녕하십니까? 이번에 Golang에서 역법을 처리할 기회가 생겨서 저는 그것을 필기로 남겼습니다.
달력을 자유롭게 조종하고 골랑으로 점치기 앱을 쉽게 만들고 싶다.
Golang 시간
Golang에는 표준 프로그램 라이브러리가 있습니다. 표준 시간도 사용할 수 있고 시간 형식도 지원합니다.
예를 들어, 현재의 시간은 아래와 같이 기술할 수 있다.
package main
import (
"fmt"
"time"
)
func main() {
fmt.Println(time.Now())
}
그렇다면 여기서 얻은 현재 시점을 기점으로 일정 날짜를 반복적으로 얻었을 때는 어떻게 해야 할까.
RRLE 정보
실제로 RFC 2445는 중복 설정을 데이터로 저장하는 데 유용한 형태를 지정합니다.
Internet Calendaring and Scheduling Core Object Specification
이번엔 이 RRLE로 중복된 날짜를 얻자.
Golang에는 RRLE을 사용할 수 있는 여러 개의 프로그램 라이브러리가 있습니다.
이번에는 지허브에 비해 스타 수가 많은
rrule-go
를 사용하고 싶다.예를 들어, RRLE는 현재 날짜와 시간에서 일주일의 날짜와 시간을 5번 반복해서 가져오려면 다음과 같이 정의할 수 있습니다.
"DTSTART: 현재 날짜 및 시간\nFREQ = WEEEKLY, INTERVAL = 1; COUNT=5"
또한
rrule-go
이 RRLE를 문자열로 교부하면 데이터를 얻을 수 있습니다.package main
import (
"fmt"
"time"
"github.com/teambition/rrule-go"
)
func main() {
var timesetter string
timesetter = time.Now().Format("20060102T150405Z")
rruleInstance := "DTSTART:" + timesetter + "\n" + "FREQ=WEEKLY;INTERVAL=1;COUNT=5"
s, err := rrule.StrToRRule(rruleInstance)
if err != nil {
fmt.Println("Rrule error",err)
}
fmt.Println(s.All())
}
이렇게 하면 매우 치밀하게 묘사할 수 있다.
RRLE의 표현 방법이 많아서 따라잡을 수 없기 때문에 여기에 위의 예에 남기지만 실제 사용할 때는 용도에 따라 RRLE 문자열을 만들어야 하기 때문에 한 문자열의 함수를 따로 정의하는 것이 편하다고 생각합니다.
예를 들어 RRLE에서 UNTIL을 추출하려면 다음과 같은 느낌이 든다.
package main
import (
"fmt"
"time"
"github.com/teambition/rrule-go"
)
func GetUntil(startData time.Time, endData time.Time, rruleData *string, exdateData *string) (time.Time, error) {
var rruleInstance string
var err error
timeSetter := startData.Format("20060102T150405Z")
if rruleData == nil {
return endTimeData, err
}
rruleInstance = fmt.Sprintf("DTSTART:%s\nRRULE:%s", timeSetter, *rruleData)
if exdateData != nil {
rruleInstance = fmt.Sprintf("%s\nEXDATE:%s", rruleInstance, *exdateData)
}
RRule, err := rrule.StrToRRuleSet(rruleInstance)
if err != nil {
return endData, err
}
Until := RRule.All()[len(RRule.All())-1]
return Until, err
}
실제로 해보세요.
오랜만에 와서 간단한 구체적인 예로 인간의 생물 리듬으로 계산해 보자.
RRLE를 사용하여 주기를 간단하게 계산할 수 있습니다.
출전: CASIO
T
는 각 주기를 가리킨다.또한
t
에 대한 정의는 다음과 같습니다.t = baseday - birthday
Unixtime 을 사용하여 실제 날짜 차를 계산합니다.
왜냐하면 Golang의 표준 Unixtime은 초니까.
24\times 60\times 60 = 86400
이 86400을 아래의 Unixtime로 나누는 것이 좋다.
t := float64(baseday.Unix()/86400 - birthday.Unix()/86400)
설치 후 아래와 같습니다.package main
import (
"fmt"
"math"
"time"
"github.com/teambition/rrule-go"
)
func biorhythm(startData time.Time, count int32, t float64) {
timeSetter := startData.Format("20060102T150405Z")
rrulePhysical := fmt.Sprintf("DTSTART:%s\nFREQ=DAILY;INTERVAL=23;COUNT=%d", timeSetter, count)
rruleSensitivity := fmt.Sprintf("DTSTART:%s\nFREQ=DAILY;INTERVAL=28;COUNT=%d", timeSetter, count)
rruleIntellectual := fmt.Sprintf("DTSTART:%s\nFREQ=DAILY;INTERVAL=33;COUNT=%d", timeSetter, count)
P, _ := rrule.StrToRRule(rrulePhysical)
S, _ := rrule.StrToRRule(rruleSensitivity)
I, _ := rrule.StrToRRule(rruleIntellectual)
fmt.Printf("Physical: ")
fmt.Printf("sin(2πt/T)=%f", math.Sin((t*2*math.Pi)/23))
fmt.Println(P.All())
fmt.Printf("Sensitivity: ")
fmt.Printf("sin(2πt/T)=%f", math.Sin((t*2*math.Pi)/28))
fmt.Println(S.All())
fmt.Printf("Intellectual: ")
fmt.Printf("sin(2πt/T)=%f", math.Sin((t*2*math.Pi)/33))
fmt.Println(I.All())
}
func main() {
birthday := // ? = time.Time型の誕生日をセット
baseday := // ? = time.Time型の基準日をセット
fmt.Println(birthday,baseday)
t := float64(baseday.Unix()/86400 - birthday.Unix()/86400)
biorhythm(birthday, 10, t)
}
플레이 그라운드에서 한번 해볼게요.
2020-11-07 23:00:00 +0000 UTC m=+346896000.000000001
2020-11-14 23:00:00 +0000 UTC m=+347500800.000000001
설정되었습니다.
이런 형태로 RRLE를 사용하면 언어화되기 때문에 간단한 표현으로 주기를 계산할 수 있다.
최후
생물 리듬에 관해서는 통계학적으로 의미 있는 데이터를 얻지 못했으니 주의하세요.
하지만 가설이라도 연예계에 자주 등장한다.
Golang의 프로그램 라이브러리 등에 대해 특성, 용법을 충분히 이해한 토대에서 이 도구를 어떻게 사용하는지는 사용자에 달려 있다.
참고 자료
「Internet Calendaring and Scheduling Core Object Specification」 http://www.ietf.org/rfc/rfc2445.txt
「rrule-go」 https://github.com/teambition/rrule-go
"생물 규칙"https://ja.wikipedia.org/wiki/바이오 리듬
"생물 규칙의 계산"https://keisan.casio.jp/exec/system/1231994137
Reference
이 문제에 관하여(Golang에서 반복 처리 날짜), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://zenn.dev/_kazuya/articles/f6488cdc689aa5텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)