Compare commits

..

3 Commits

Author SHA1 Message Date
3a17edfaf0 v0.0.509
All checks were successful
Build Docker and Deploy / Run goext test-suite (push) Successful in 6m2s
2024-08-26 14:35:49 +02:00
3320a9c19d v0.0.508
All checks were successful
Build Docker and Deploy / Run goext test-suite (push) Successful in 4m25s
2024-08-25 17:36:20 +02:00
8dcd8a270a v0.0.507 fix jsonfilter:"-" not working
All checks were successful
Build Docker and Deploy / Run goext test-suite (push) Successful in 7m7s
2024-08-25 15:41:17 +02:00
9 changed files with 158 additions and 5 deletions

4
go.mod
View File

@@ -6,7 +6,7 @@ require (
github.com/gin-gonic/gin v1.10.0
github.com/glebarez/go-sqlite v1.22.0 // only needed for tests -.-
github.com/jmoiron/sqlx v1.4.0
github.com/rs/xid v1.5.0
github.com/rs/xid v1.6.0
github.com/rs/zerolog v1.33.0
go.mongodb.org/mongo-driver v1.16.1
golang.org/x/crypto v0.26.0
@@ -45,7 +45,7 @@ require (
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/montanaflynn/stats v0.7.1 // indirect
github.com/pelletier/go-toml/v2 v2.2.2 // indirect
github.com/pelletier/go-toml/v2 v2.2.3 // indirect
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
github.com/ugorji/go/codec v1.2.12 // indirect

4
go.sum
View File

@@ -175,6 +175,8 @@ github.com/pelletier/go-toml/v2 v2.2.1 h1:9TA9+T8+8CUCO2+WYnDLCgrYi9+omqKXyjDtos
github.com/pelletier/go-toml/v2 v2.2.1/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs=
github.com/pelletier/go-toml/v2 v2.2.2 h1:aYUidT7k73Pcl9nb2gScu7NSrKCSHIDE89b3+6Wq+LM=
github.com/pelletier/go-toml/v2 v2.2.2/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs=
github.com/pelletier/go-toml/v2 v2.2.3 h1:YmeHyLY8mFWbdkNWwpr+qIL2bEqT0o95WSdkNHvL12M=
github.com/pelletier/go-toml/v2 v2.2.3/go.mod h1:MfCQTFTvCcUyyvvwm1+G6H/jORL20Xlb6rzQu9GuUkc=
github.com/phpdave11/gofpdi v1.0.7/go.mod h1:vBmVV0Do6hSBHC8uKUQ71JGW+ZGQq74llk/7bXwjDoI=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
@@ -184,6 +186,8 @@ github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
github.com/rs/xid v1.5.0 h1:mKX4bl4iPYJtEIxp6CYiUuLQ/8DYMoz0PUdtGgMFRVc=
github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
github.com/rs/xid v1.6.0 h1:fV591PaemRlL6JfRxGDEPl69wICngIQ3shQtzfy2gxU=
github.com/rs/xid v1.6.0/go.mod h1:7XoLgs4eV+QndskICGsho+ADou8ySMSjJKDIan90Nz0=
github.com/rs/zerolog v1.31.0 h1:FcTR3NnLWW+NnTwwhFWiJSZr4ECLpqCm6QsEnyvbV4A=
github.com/rs/zerolog v1.31.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss=
github.com/rs/zerolog v1.32.0 h1:keLypqrlIjaFsbmJOBdB/qvyF8KEtCWHwobLp5l/mQ0=

View File

@@ -1,5 +1,5 @@
package goext
const GoextVersion = "0.0.506"
const GoextVersion = "0.0.509"
const GoextVersionTimestamp = "2024-08-22T11:45:02+0200"
const GoextVersionTimestamp = "2024-08-26T14:35:49+0200"

View File

@@ -1353,7 +1353,7 @@ func typeFields(t reflect.Type, tagkey string) structFields {
var jsonfilter []string
jsonfilterTag := sf.Tag.Get("jsonfilter")
if jsonfilterTag != "" && jsonfilterTag != "-" {
if jsonfilterTag != "" {
jsonfilter = strings.Split(jsonfilterTag, ",")
}

15
langext/io.go Normal file
View File

@@ -0,0 +1,15 @@
package langext
import "io"
type nopCloser struct {
io.Writer
}
func (n nopCloser) Close() error {
return nil // no op
}
func WriteNopCloser(w io.Writer) io.WriteCloser {
return nopCloser{w}
}

View File

@@ -2,6 +2,9 @@ package timeext
import "time"
// YearDifference calculates the difference between two timestamps in years.
// = t1 - t2
// returns a float value
func YearDifference(t1 time.Time, t2 time.Time, tz *time.Location) float64 {
yDelta := float64(t1.Year() - t2.Year())
@@ -11,3 +14,31 @@ func YearDifference(t1 time.Time, t2 time.Time, tz *time.Location) float64 {
return yDelta + (processT1 - processT2)
}
// MonthDifference calculates the difference between two timestamps in months.
// = t1 - t2
// returns a float value
func MonthDifference(t1 time.Time, t2 time.Time) float64 {
yDelta := float64(t1.Year() - t2.Year())
mDelta := float64(t1.Month() - t2.Month())
dDelta := float64(0)
t1MonthDays := DaysInMonth(t1)
t2MonthDays := DaysInMonth(t2)
if t2.Year() > t1.Year() || (t2.Year() == t1.Year() && t2.Month() > t1.Month()) {
dDelta -= 1
dDelta += float64(t1MonthDays-t1.Day()) / float64(t1MonthDays)
dDelta += float64(t2.Day()) / float64(t2MonthDays)
} else if t2.Year() < t1.Year() || (t2.Year() == t1.Year() && t2.Month() < t1.Month()) {
dDelta -= 1
dDelta += float64(t1.Day()) / float64(t1MonthDays)
dDelta += float64(t2MonthDays-t2.Day()) / float64(t2MonthDays)
} else {
dDelta += float64(t1.Day()-t2.Day()) / float64(t1MonthDays)
}
return yDelta*12 + mDelta + dDelta
}

View File

@@ -81,3 +81,63 @@ func epsilonEquals(a, b float64) bool {
epsilon := 0.01
return math.Abs(a-b) < epsilon
}
func TestMonthDifferenceSameDate(t *testing.T) {
t1 := time.Date(2022, 1, 1, 0, 0, 0, 0, time.UTC)
t2 := time.Date(2022, 1, 1, 0, 0, 0, 0, time.UTC)
expected := 0.0
result := MonthDifference(t2, t1)
if !epsilonEquals(result, expected) {
t.Errorf("Expected %v, got %v", expected, result)
}
}
func TestMonthDifferenceSameMonth(t *testing.T) {
t1 := time.Date(2022, 1, 1, 0, 0, 0, 0, time.UTC)
t2 := time.Date(2022, 1, 31, 0, 0, 0, 0, time.UTC)
expected := 0.967741935483871 // Approximation of 30/31 days
result := MonthDifference(t2, t1)
if !epsilonEquals(result, expected) {
t.Errorf("Expected %v, got %v", expected, result)
}
}
func TestMonthDifferenceDifferentMonthsSameYear(t *testing.T) {
t1 := time.Date(2022, 1, 1, 0, 0, 0, 0, time.UTC)
t2 := time.Date(2022, 3, 1, 0, 0, 0, 0, time.UTC)
expected := 2.0
result := MonthDifference(t2, t1)
if !epsilonEquals(result, expected) {
t.Errorf("Expected %v, got %v", expected, result)
}
}
func TestMonthDifferenceDifferentYears(t *testing.T) {
t1 := time.Date(2021, 12, 1, 0, 0, 0, 0, time.UTC)
t2 := time.Date(2022, 2, 1, 0, 0, 0, 0, time.UTC)
expected := 2.0
result := MonthDifference(t2, t1)
if !epsilonEquals(result, expected) {
t.Errorf("Expected %v, got %v", expected, result)
}
}
func TestMonthDifferenceT1BeforeT2(t *testing.T) {
t1 := time.Date(2022, 1, 1, 0, 0, 0, 0, time.UTC)
t2 := time.Date(2022, 6, 1, 0, 0, 0, 0, time.UTC)
expected := 5.0
result := MonthDifference(t2, t1)
if !epsilonEquals(result, expected) {
t.Errorf("Expected %v, got %v", expected, result)
}
}
func TestMonthDifferenceT1AfterT2(t *testing.T) {
t1 := time.Date(2022, 6, 1, 0, 0, 0, 0, time.UTC)
t2 := time.Date(2022, 1, 1, 0, 0, 0, 0, time.UTC)
expected := -5.0
result := MonthDifference(t2, t1)
if !epsilonEquals(result, expected) {
t.Errorf("Expected %v, got %v", expected, result)
}
}

View File

@@ -184,3 +184,10 @@ func AddYears(t time.Time, yearCount float64, tz *time.Location) time.Time {
return t.Add(time.Duration(float64(t1.Sub(t0)) * floatCount))
}
func DaysInMonth(t time.Time) int {
// https://stackoverflow.com/a/73882035/1761622
y, m, _ := t.Date()
return time.Date(y, m+1, 0, 0, 0, 0, 0, time.UTC).Day()
}

View File

@@ -191,3 +191,39 @@ func TestCombineDateAndTime_CombineDifferentParts(t *testing.T) {
t.Errorf("Expected %v, got %v", expected, result)
}
}
func TestDaysInMonth_31Days(t *testing.T) {
date := time.Date(2022, 1, 1, 0, 0, 0, 0, time.UTC) // January
expected := 31
result := DaysInMonth(date)
if result != expected {
t.Errorf("Expected %d but got %d", expected, result)
}
}
func TestDaysInMonth_30Days(t *testing.T) {
date := time.Date(2022, 4, 1, 0, 0, 0, 0, time.UTC) // April
expected := 30
result := DaysInMonth(date)
if result != expected {
t.Errorf("Expected %d but got %d", expected, result)
}
}
func TestDaysInMonth_FebruaryLeapYear(t *testing.T) {
date := time.Date(2020, 2, 1, 0, 0, 0, 0, time.UTC) // February in a leap year
expected := 29
result := DaysInMonth(date)
if result != expected {
t.Errorf("Expected %d but got %d", expected, result)
}
}
func TestDaysInMonth_FebruaryNonLeapYear(t *testing.T) {
date := time.Date(2021, 2, 1, 0, 0, 0, 0, time.UTC) // February in a non-leap year
expected := 28
result := DaysInMonth(date)
if result != expected {
t.Errorf("Expected %d but got %d", expected, result)
}
}