Compare commits
8 Commits
3239644cc2
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
| 9302c14a6c | |||
| b9756ed8c4 | |||
| 2b1f2e9be3 | |||
| bef8d77768 | |||
| e36581f205 | |||
| f1397c40b1 | |||
| b1f0eb2769 | |||
| 5d77a9a3d3 |
14
LICENSE
Normal file
14
LICENSE
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
|
||||||
|
Version 2, December 2004
|
||||||
|
|
||||||
|
Copyright (C) 2004 Sam Hocevar <sam@hocevar.net>
|
||||||
|
|
||||||
|
Everyone is permitted to copy and distribute verbatim or modified
|
||||||
|
copies of this license document, and changing it is allowed as long
|
||||||
|
as the name is changed.
|
||||||
|
|
||||||
|
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
|
||||||
|
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||||
|
|
||||||
|
0. You just DO WHAT THE FUCK YOU WANT TO.
|
||||||
|
|
||||||
@@ -6,10 +6,14 @@ general, so I put them here.
|
|||||||
|
|
||||||
Suggestions are welcome.
|
Suggestions are welcome.
|
||||||
|
|
||||||
|
Really I think most of these should probably be in the stdlib.
|
||||||
|
|
||||||
# License
|
# License
|
||||||
|
|
||||||
WTFPL (free software, no restrictions)
|
WTFPL (free software, no restrictions)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Author
|
# Author
|
||||||
|
|
||||||
* [sneak@sneak.berlin](mailto:sneak@sneak.berlin)
|
* [sneak@sneak.berlin](mailto:sneak@sneak.berlin)
|
||||||
|
|||||||
7
go.mod
7
go.mod
@@ -1,5 +1,8 @@
|
|||||||
module git.eeqj.de/sneak/goutil
|
module sneak.berlin/go/util
|
||||||
|
|
||||||
go 1.14
|
go 1.14
|
||||||
|
|
||||||
require github.com/hako/durafmt v0.0.0-20191009132224-3f39dc1ed9f4
|
require (
|
||||||
|
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect
|
||||||
|
github.com/hako/durafmt v0.0.0-20191009132224-3f39dc1ed9f4
|
||||||
|
)
|
||||||
|
|||||||
2
go.sum
2
go.sum
@@ -1,2 +1,4 @@
|
|||||||
|
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 h1:DklsrG3dyBCFEj5IhUbnKptjxatkF07cF2ak3yi77so=
|
||||||
|
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw=
|
||||||
github.com/hako/durafmt v0.0.0-20191009132224-3f39dc1ed9f4 h1:60gBOooTSmNtrqNaRvrDbi8VAne0REaek2agjnITKSw=
|
github.com/hako/durafmt v0.0.0-20191009132224-3f39dc1ed9f4 h1:60gBOooTSmNtrqNaRvrDbi8VAne0REaek2agjnITKSw=
|
||||||
github.com/hako/durafmt v0.0.0-20191009132224-3f39dc1ed9f4/go.mod h1:5Scbynm8dF1XAPwIwkGPqzkM/shndPm79Jd1003hTjE=
|
github.com/hako/durafmt v0.0.0-20191009132224-3f39dc1ed9f4/go.mod h1:5Scbynm8dF1XAPwIwkGPqzkM/shndPm79Jd1003hTjE=
|
||||||
|
|||||||
59
util.go
59
util.go
@@ -1,12 +1,14 @@
|
|||||||
package goutil
|
package util
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
|
"io"
|
||||||
"math"
|
"math"
|
||||||
"os"
|
"os"
|
||||||
"regexp"
|
"regexp"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/asaskevich/govalidator"
|
||||||
"github.com/hako/durafmt"
|
"github.com/hako/durafmt"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -23,6 +25,10 @@ func TimeDiffHuman(first time.Time, second time.Time) string {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func IsValidURL(url string) bool {
|
||||||
|
return govalidator.IsURL(url) && (govalidator.IsRequestURL(url) || govalidator.IsRequestURI(url))
|
||||||
|
}
|
||||||
|
|
||||||
// Does anyone else use uints for things that are always >=0 like counts and
|
// Does anyone else use uints for things that are always >=0 like counts and
|
||||||
func TimeDiffAbsSeconds(first time.Time, second time.Time) uint {
|
func TimeDiffAbsSeconds(first time.Time, second time.Time) uint {
|
||||||
return uint(math.Abs(first.Sub(second).Truncate(time.Second).Seconds()))
|
return uint(math.Abs(first.Sub(second).Truncate(time.Second).Seconds()))
|
||||||
@@ -43,3 +49,54 @@ func Mkdirp(p string) error {
|
|||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// straight outta stackoverflow
|
||||||
|
// https://stackoverflow.com/questions/21060945/simple-way-to-copy-a-file-in-golang
|
||||||
|
func CopyFile(src, dst string) (err error) {
|
||||||
|
in, err := os.Open(src)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer in.Close()
|
||||||
|
out, err := os.Create(dst)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer func() {
|
||||||
|
cerr := out.Close()
|
||||||
|
if err == nil {
|
||||||
|
err = cerr
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
if _, err = io.Copy(out, in); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
err = out.Sync()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const milliInSecond int64 = 1000
|
||||||
|
const microInSecond int64 = 1000000
|
||||||
|
const nsInSecond int64 = 1000000000
|
||||||
|
|
||||||
|
func TimeFromUnixMilli(input int64) time.Time {
|
||||||
|
var wholeSeconds int64 = input / milliInSecond
|
||||||
|
var remainderMillis int64 = input - (wholeSeconds * milliInSecond)
|
||||||
|
var remainderNano int64 = remainderMillis * 1000000
|
||||||
|
return time.Unix(wholeSeconds, remainderNano)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TimeFromUnixMicro(input int64) time.Time {
|
||||||
|
var wholeSeconds int64 = input / microInSecond
|
||||||
|
var remainderMicros int64 = input - (wholeSeconds * microInSecond)
|
||||||
|
var remainderNano int64 = remainderMicros * 1000
|
||||||
|
return time.Unix(wholeSeconds, remainderNano)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TimeFromWebKit(input int64) time.Time {
|
||||||
|
// webkit time is stupid and uses 1601-01-01 for epoch
|
||||||
|
// it's 11644473600 seconds behind unix 1970-01-01 epoch
|
||||||
|
// it's also in microseconds
|
||||||
|
unixMicrosCorrected := input - (11644473600 * 1000000)
|
||||||
|
return TimeFromUnixMicro(unixMicrosCorrected)
|
||||||
|
}
|
||||||
|
|||||||
51
util_test.go
Normal file
51
util_test.go
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
package util
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestFromUnixMilli(t *testing.T) {
|
||||||
|
ms := 1542810446506
|
||||||
|
ts := TimeFromUnixMilli(int64(ms))
|
||||||
|
if ts.UTC().String() != "2018-11-21 14:27:26.506 +0000 UTC" {
|
||||||
|
t.Errorf("Expected time to be '2018-11-21 14:27:26.506 +0000 UTC' got '%s'", ts.UTC().String())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestFromUnixMicro(t *testing.T) {
|
||||||
|
ms := 1542810446506000
|
||||||
|
ts := TimeFromUnixMicro(int64(ms))
|
||||||
|
if ts.UTC().String() != "2018-11-21 14:27:26.506 +0000 UTC" {
|
||||||
|
t.Errorf("Expected time to be '2018-11-21 14:27:26.506 +0000 UTC' got '%s'", ts.UTC().String())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestFromWebkit(t *testing.T) {
|
||||||
|
var wk int64 = 13245202142853170
|
||||||
|
ts := TimeFromWebKit(wk)
|
||||||
|
expected := "2020-09-21 22:49:02.85317 +0000 UTC"
|
||||||
|
if ts.UTC().String() != expected {
|
||||||
|
t.Errorf("Expected time to be '%s' got '%s'", expected, ts.UTC().String())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestNowUnixMicro(t *testing.T) {
|
||||||
|
now := time.Now()
|
||||||
|
nownano := now.UnixNano()
|
||||||
|
nowmicro := nownano / 1000
|
||||||
|
ts := TimeFromUnixMicro(nowmicro)
|
||||||
|
if ts.UTC().String() != now.UTC().String() {
|
||||||
|
t.Errorf("Expected '%s' got '%s'", now.UTC().String(), ts.UTC().String())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestNowUnixMilli(t *testing.T) {
|
||||||
|
now := time.Now()
|
||||||
|
nownano := now.UnixNano()
|
||||||
|
nowmilli := nownano / 1000000
|
||||||
|
ts := TimeFromUnixMilli(nowmilli)
|
||||||
|
if ts.UTC().Format(time.StampMilli) != now.UTC().Format(time.StampMilli) {
|
||||||
|
t.Errorf("Expected '%s' got '%s'", now.UTC().String(), ts.UTC().String())
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user