85 lines
1.6 KiB
Go
85 lines
1.6 KiB
Go
|
package activitypub
|
||
|
|
||
|
import (
|
||
|
"bytes"
|
||
|
"fmt"
|
||
|
"time"
|
||
|
)
|
||
|
|
||
|
const day = time.Hour * 24
|
||
|
const week = day * 7
|
||
|
const month = week * 4
|
||
|
const year = month * 12
|
||
|
|
||
|
func Days(d time.Duration) float64 {
|
||
|
dd := d / day
|
||
|
h := d % day
|
||
|
return float64(dd) + float64(h)/(24*60*60*1e9)
|
||
|
}
|
||
|
func Weeks(d time.Duration) float64 {
|
||
|
w := d / week
|
||
|
dd := d % week
|
||
|
return float64(w) + float64(dd)/(7*24*60*60*1e9)
|
||
|
}
|
||
|
func Months(d time.Duration) float64 {
|
||
|
m := d / month
|
||
|
w := d % month
|
||
|
return float64(m) + float64(w)/(4*7*24*60*60*1e9)
|
||
|
}
|
||
|
func Years(d time.Duration) float64 {
|
||
|
y := d / year
|
||
|
m := d % year
|
||
|
return float64(y) + float64(m)/(12*4*7*24*60*60*1e9)
|
||
|
}
|
||
|
|
||
|
func marshalXSD(d time.Duration) ([]byte, error) {
|
||
|
if d == 0 {
|
||
|
return []byte{'P','T','0','S'}, nil
|
||
|
}
|
||
|
|
||
|
neg := d < 0
|
||
|
if neg {
|
||
|
d = -d
|
||
|
}
|
||
|
y := Years(d)
|
||
|
d -= time.Duration(y) * year
|
||
|
m := Months(d)
|
||
|
d -= time.Duration(m) * month
|
||
|
dd := Days(d)
|
||
|
d -= time.Duration(dd) * day
|
||
|
H := d.Hours()
|
||
|
d -= time.Duration(H) * time.Hour
|
||
|
M := d.Minutes()
|
||
|
d -= time.Duration(M) * time.Minute
|
||
|
s := d.Seconds()
|
||
|
d -= time.Duration(s) * time.Second
|
||
|
b := bytes.Buffer{}
|
||
|
if neg {
|
||
|
b.Write([]byte{'-'})
|
||
|
}
|
||
|
b.Write([]byte{'P'})
|
||
|
if y > 0 {
|
||
|
b.WriteString(fmt.Sprintf("%dY", int64(y)))
|
||
|
}
|
||
|
if m > 0 {
|
||
|
b.WriteString(fmt.Sprintf("%dM", int64(m)))
|
||
|
}
|
||
|
if dd > 0 {
|
||
|
b.WriteString(fmt.Sprintf("%dD", int64(dd)))
|
||
|
}
|
||
|
|
||
|
if H + M + s > 0 {
|
||
|
b.Write([]byte{'T'})
|
||
|
if H > 0 {
|
||
|
b.WriteString(fmt.Sprintf("%dH", int64(H)))
|
||
|
}
|
||
|
if M > 0 {
|
||
|
b.WriteString(fmt.Sprintf("%dM", int64(M)))
|
||
|
}
|
||
|
if s > 0 {
|
||
|
b.WriteString(fmt.Sprintf("%dS", int64(s)))
|
||
|
}
|
||
|
}
|
||
|
return b.Bytes(), nil
|
||
|
}
|