feat: add measurement unit converter (#2772)

This commit is contained in:
Srikanth Chekuri 2023-06-06 18:29:56 +05:30 committed by GitHub
parent edf7e9821f
commit 7086f7eafa
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 567 additions and 0 deletions

View File

@ -139,3 +139,4 @@ clear-swarm-data:
test:
go test ./pkg/query-service/app/metrics/...
go test ./pkg/query-service/app/...
go test ./pkg/query-service/converter/...

View File

@ -0,0 +1,16 @@
package converter
// boolConverter is a Converter implementation for bool
type boolConverter struct{}
func NewBoolConverter() Converter {
return &boolConverter{}
}
func (c *boolConverter) Convert(v Value, to Unit) Value {
// There is no conversion to be done for bool
return Value{
F: v.F,
U: to,
}
}

View File

@ -0,0 +1,53 @@
package converter
// Unit represents a unit of measurement
type Unit string
// Value represents a value with a unit of measurement
type Value struct {
F float64
U Unit
}
// Converter converts values from one unit to another
type Converter interface {
Convert(v Value, to Unit) Value
}
// noneConverter is a converter that does not convert
type noneConverter struct{}
func (c *noneConverter) Convert(v Value, to Unit) Value {
return v
}
// Converters
var (
DurationConverter = NewDurationConverter()
DataConverter = NewDataConverter()
DataRateConverter = NewDataRateConverter()
PercentConverter = NewPercentConverter()
BoolConverter = NewBoolConverter()
ThroughputConverter = NewThroughputConverter()
NoneConverter = &noneConverter{}
)
// FromUnit returns a converter for the given unit
func FromUnit(u Unit) Converter {
switch u {
case "ns", "us", "ms", "s", "m", "h", "d":
return DurationConverter
case "bytes", "decbytes", "bits", "decbits", "kbytes", "decKbytes", "mbytes", "decMbytes", "gbytes", "decGbytes", "tbytes", "decTbytes", "pbytes", "decPbytes":
return DataConverter
case "binBps", "Bps", "binbps", "bps", "KiBs", "Kibits", "KBs", "Kbits", "MiBs", "Mibits", "MBs", "Mbits", "GiBs", "Gibits", "GBs", "Gbits", "TiBs", "Tibits", "TBs", "Tbits", "PiBs", "Pibits", "PBs", "Pbits":
return DataRateConverter
case "percent", "percentunit":
return PercentConverter
case "bool", "bool_yes_no", "bool_true_false", "bool_1_0":
return BoolConverter
case "cps", "ops", "reqps", "rps", "wps", "iops", "cpm", "opm", "rpm", "wpm":
return ThroughputConverter
default:
return NoneConverter
}
}

View File

@ -0,0 +1,97 @@
package converter
const (
// base 10 (SI prefixes)
Bit float64 = 1e0
Kilobit = Bit * 1e3
Megabit = Bit * 1e6
Gigabit = Bit * 1e9
Terabit = Bit * 1e12
Petabit = Bit * 1e15
Exabit = Bit * 1e18
Zettabit = Bit * 1e21
Yottabit = Bit * 1e24
Ronnabit = Bit * 1e27
Quettabit = Bit * 1e30
Byte = Bit * 8
Kilobyte = Byte * 1e3
Megabyte = Byte * 1e6
Gigabyte = Byte * 1e9
Terabyte = Byte * 1e12
Petabyte = Byte * 1e15
Exabyte = Byte * 1e18
Zettabyte = Byte * 1e21
Yottabyte = Byte * 1e24
Ronnabyte = Byte * 1e27
Quettabyte = Byte * 1e30
// base 2 (IEC prefixes)
Kibibit = Bit * 1024
Mebibit = Kibibit * 1024
Gibibit = Mebibit * 1024
Tebibit = Gibibit * 1024
Pebibit = Tebibit * 1024
Exbibit = Pebibit * 1024
Zebibit = Exbibit * 1024
Yobibit = Zebibit * 1024
Kibibyte = Byte * 1024
Mebibyte = Kibibyte * 1024
Gibibyte = Mebibyte * 1024
Tebibyte = Gibibyte * 1024
Pebibyte = Tebibyte * 1024
Exbibyte = Pebibyte * 1024
Zebibyte = Exbibyte * 1024
Yobibyte = Zebibyte * 1024
)
// dataConverter is a Converter for data units.
type dataConverter struct {
}
func NewDataConverter() Converter {
return &dataConverter{}
}
func FromDataUnit(u Unit) float64 {
switch u {
case "bytes": // base 2
return Byte
case "decbytes": // base 10
return Byte
case "bits": // base 2
return Bit
case "decbits": // base 10
return Bit
case "kbytes": // base 2
return Kibibyte
case "deckbytes": // base 10
return Kilobyte
case "mbytes": // base 2
return Mebibyte
case "decmbytes": // base 10
return Megabyte
case "gbytes": // base 2
return Gibibyte
case "decgbytes": // base 10
return Gigabyte
case "tbytes": // base 2
return Tebibyte
case "dectbytes": // base 10
return Terabyte
case "pbytes": // base 2
return Pebibyte
case "decpbytes": // base 10
return Petabyte
default:
return 1
}
}
func (c *dataConverter) Convert(v Value, to Unit) Value {
return Value{
F: v.F * FromDataUnit(v.U) / FromDataUnit(to),
U: to,
}
}

View File

@ -0,0 +1,114 @@
package converter
const (
// base 10 (SI prefixes)
BitPerSecond float64 = 1e0
KilobitPerSecond = BitPerSecond * 1e3
MegabitPerSecond = BitPerSecond * 1e6
GigabitPerSecond = BitPerSecond * 1e9
TerabitPerSecond = BitPerSecond * 1e12
PetabitPerSecond = BitPerSecond * 1e15
ExabitPerSecond = BitPerSecond * 1e18
ZettabitPerSecond = BitPerSecond * 1e21
YottabitPerSecond = BitPerSecond * 1e24
BytePerSecond = BitPerSecond * 8
KilobytePerSecond = BytePerSecond * 1e3
MegabytePerSecond = BytePerSecond * 1e6
GigabytePerSecond = BytePerSecond * 1e9
TerabytePerSecond = BytePerSecond * 1e12
PetabytePerSecond = BytePerSecond * 1e15
ExabytePerSecond = BytePerSecond * 1e18
ZettabytePerSecond = BytePerSecond * 1e21
YottabytePerSecond = BytePerSecond * 1e24
// base 2 (IEC prefixes)
KibibitPerSecond = BitPerSecond * 1024
MebibitPerSecond = KibibitPerSecond * 1024
GibibitPerSecond = MebibitPerSecond * 1024
TebibitPerSecond = GibibitPerSecond * 1024
PebibitPerSecond = TebibitPerSecond * 1024
ExbibitPerSecond = PebibitPerSecond * 1024
ZebibitPerSecond = ExbibitPerSecond * 1024
YobibitPerSecond = ZebibitPerSecond * 1024
KibibytePerSecond = BytePerSecond * 1024
MebibytePerSecond = KibibytePerSecond * 1024
GibibytePerSecond = MebibytePerSecond * 1024
TebibytePerSecond = GibibytePerSecond * 1024
PebibytePerSecond = TebibytePerSecond * 1024
ExbibytePerSecond = PebibytePerSecond * 1024
ZebibytePerSecond = ExbibytePerSecond * 1024
YobibytePerSecond = ZebibytePerSecond * 1024
)
// dataRateConverter is a Converter implementation for data rates
type dataRateConverter struct {
}
func NewDataRateConverter() Converter {
return &dataRateConverter{}
}
func FromDataRateUnit(u Unit) float64 {
// See https://github.com/SigNoz/signoz/blob/5a81f5f90b34845f5b4b3bdd46acf29d04bf3987/frontend/src/container/NewWidget/RightContainer/dataFormatCategories.ts#L62-L85
switch u {
case "binBps": // bytes/sec(IEC)
return BytePerSecond
case "Bps": // bytes/sec(SI)
return BytePerSecond
case "binbps": // bits/sec(IEC)
return BitPerSecond
case "bps": // bits/sec(SI)
return BitPerSecond
case "KiBs": // kibibytes/sec
return KibibytePerSecond
case "Kibits": // kibibits/sec
return KibibitPerSecond
case "KBs": // kilobytes/sec
return KilobytePerSecond
case "Kbits": // kilobits/sec
return KilobitPerSecond
case "MiBs": // mebibytes/sec
return MebibytePerSecond
case "Mibits": // mebibits/sec
return MebibitPerSecond
case "MBs": // megabytes/sec
return MegabytePerSecond
case "Mbits": // megabits/sec
return MegabitPerSecond
case "GiBs": // gibibytes/sec
return GibibytePerSecond
case "Gibits": // gibibits/sec
return GibibitPerSecond
case "GBs": // gigabytes/sec
return GigabytePerSecond
case "Gbits": // gigabits/sec
return GigabitPerSecond
case "TiBs": // tebibytes/sec
return TebibytePerSecond
case "Tibits": // tebibits/sec
return TebibitPerSecond
case "TBs": // terabytes/sec
return TerabytePerSecond
case "Tbits": // terabits/sec
return TerabitPerSecond
case "PiBs": // pebibytes/sec
return PebibytePerSecond
case "Pibits": // pebibits/sec
return PebibitPerSecond
case "PBs": // petabytes/sec
return PetabytePerSecond
case "Pbits": // petabits/sec
return PetabitPerSecond
default:
return 1
}
}
func (c *dataRateConverter) Convert(v Value, to Unit) Value {
return Value{
F: v.F * FromDataRateUnit(v.U) / FromDataRateUnit(to),
U: to,
}
}

View File

@ -0,0 +1,67 @@
package converter
import (
"testing"
"github.com/stretchr/testify/assert"
)
func TestDataRate(t *testing.T) {
dataRateConverter := NewDataRateConverter()
// names and ids for data rate units
// { name: 'bytes/sec(IEC)', id: 'binBps' },
// { name: 'bytes/sec(SI)', id: 'Bps' },
// { name: 'bits/sec(IEC)', id: 'binbps' },
// { name: 'bits/sec(SI)', id: 'bps' },
// { name: 'kibibytes/sec', id: 'KiBs' },
// { name: 'kibibits/sec', id: 'Kibits' },
// { name: 'kilobytes/sec', id: 'KBs' },
// { name: 'kilobits/sec', id: 'Kbits' },
// { name: 'mebibytes/sec', id: 'MiBs' },
// { name: 'mebibits/sec', id: 'Mibits' },
// { name: 'megabytes/sec', id: 'MBs' },
// { name: 'megabits/sec', id: 'Mbits' },
// { name: 'gibibytes/sec', id: 'GiBs' },
// { name: 'gibibits/sec', id: 'Gibits' },
// { name: 'gigabytes/sec', id: 'GBs' },
// { name: 'gigabits/sec', id: 'Gbits' },
// { name: 'tebibytes/sec', id: 'TiBs' },
// { name: 'tebibits/sec', id: 'Tibits' },
// { name: 'terabytes/sec', id: 'TBs' },
// { name: 'terabits/sec', id: 'Tbits' },
// { name: 'pebibytes/sec', id: 'PiBs' },
// { name: 'pebibits/sec', id: 'Pibits' },
// { name: 'petabytes/sec', id: 'PBs' },
// { name: 'petabits/sec', id: 'Pbits' },
// 8 bits = 1 byte
assert.Equal(t, Value{F: 1, U: "binBps"}, dataRateConverter.Convert(Value{F: 8, U: "binbps"}, "binBps"))
// 1024 bytes = 1 kbytes
assert.Equal(t, Value{F: 1, U: "KiBs"}, dataRateConverter.Convert(Value{F: 1024, U: "binBps"}, "KiBs"))
// 1 byte = 8 bits
assert.Equal(t, Value{F: 8, U: "binbps"}, dataRateConverter.Convert(Value{F: 1, U: "binBps"}, "binbps"))
// 1 mbytes = 1024 kbytes
assert.Equal(t, Value{F: 1, U: "MiBs"}, dataRateConverter.Convert(Value{F: 1024, U: "KiBs"}, "MiBs"))
// 1 kbytes = 1024 bytes
assert.Equal(t, Value{F: 1024, U: "binBps"}, dataRateConverter.Convert(Value{F: 1, U: "KiBs"}, "binBps"))
// 1024 kbytes = 1 mbytes
assert.Equal(t, Value{F: 1, U: "MiBs"}, dataRateConverter.Convert(Value{F: 1024, U: "KiBs"}, "MiBs"))
// 1 mbytes = 1024 * 1024 bytes
assert.Equal(t, Value{F: 1024 * 1024, U: "binBps"}, dataRateConverter.Convert(Value{F: 1, U: "MiBs"}, "binBps"))
// 1024 mbytes = 1 gbytes
assert.Equal(t, Value{F: 1, U: "GiBs"}, dataRateConverter.Convert(Value{F: 1024, U: "MiBs"}, "GiBs"))
// 2048 mbytes = 2 gbytes
assert.Equal(t, Value{F: 2, U: "GiBs"}, dataRateConverter.Convert(Value{F: 2048, U: "MiBs"}, "GiBs"))
// 1 gbytes = 1024 mbytes
assert.Equal(t, Value{F: 1024, U: "MiBs"}, dataRateConverter.Convert(Value{F: 1, U: "GiBs"}, "MiBs"))
// 1 gbytes = 1024 * 1024 kbytes
assert.Equal(t, Value{F: 1024 * 1024, U: "KiBs"}, dataRateConverter.Convert(Value{F: 1, U: "GiBs"}, "KiBs"))
// 1 gbytes = 1024 * 1024 * 1024 bytes
assert.Equal(t, Value{F: 1024 * 1024 * 1024, U: "binBps"}, dataRateConverter.Convert(Value{F: 1, U: "GiBs"}, "binBps"))
// 1024 * 1024 bytes = 1 mbytes
assert.Equal(t, Value{F: 1, U: "MiBs"}, dataRateConverter.Convert(Value{F: 1024 * 1024, U: "binBps"}, "MiBs"))
// 1024 * 1024 kbytes = 1 gbytes
assert.Equal(t, Value{F: 1, U: "GiBs"}, dataRateConverter.Convert(Value{F: 1024 * 1024, U: "KiBs"}, "GiBs"))
// 1024 * 1024 * 1024 bytes = 1 gbytes
assert.Equal(t, Value{F: 1, U: "GiBs"}, dataRateConverter.Convert(Value{F: 1024 * 1024 * 1024, U: "binBps"}, "GiBs"))
}

View File

@ -0,0 +1,47 @@
package converter
import (
"testing"
"github.com/stretchr/testify/assert"
)
func TestData(t *testing.T) {
dataConverter := NewDataConverter()
// 8 bits = 1 byte
assert.Equal(t, Value{F: 1, U: "bytes"}, dataConverter.Convert(Value{F: 8, U: "bits"}, "bytes"))
// 1024 bytes = 1 kbytes
assert.Equal(t, Value{F: 1, U: "kbytes"}, dataConverter.Convert(Value{F: 1024, U: "bytes"}, "kbytes"))
// 1 byte = 8 bits
assert.Equal(t, Value{F: 8, U: "bits"}, dataConverter.Convert(Value{F: 1, U: "bytes"}, "bits"))
// 1 mbytes = 1024 kbytes
assert.Equal(t, Value{F: 1024, U: "kbytes"}, dataConverter.Convert(Value{F: 1, U: "mbytes"}, "kbytes"))
// 1 kbytes = 1024 bytes
assert.Equal(t, Value{F: 1024, U: "bytes"}, dataConverter.Convert(Value{F: 1, U: "kbytes"}, "bytes"))
// 1024 kbytes = 1 mbytes
assert.Equal(t, Value{F: 1, U: "mbytes"}, dataConverter.Convert(Value{F: 1024, U: "kbytes"}, "mbytes"))
// 1 mbytes = 1024 * 1024 bytes
assert.Equal(t, Value{F: 1024 * 1024, U: "bytes"}, dataConverter.Convert(Value{F: 1, U: "mbytes"}, "bytes"))
// 1024 mbytes = 1 gbytes
assert.Equal(t, Value{F: 1, U: "gbytes"}, dataConverter.Convert(Value{F: 1024, U: "mbytes"}, "gbytes"))
// 1 gbytes = 1024 mbytes
assert.Equal(t, Value{F: 1024, U: "mbytes"}, dataConverter.Convert(Value{F: 1, U: "gbytes"}, "mbytes"))
// 1 gbytes = 1024 * 1024 kbytes
assert.Equal(t, Value{F: 1024 * 1024, U: "kbytes"}, dataConverter.Convert(Value{F: 1, U: "gbytes"}, "kbytes"))
// 1 gbytes = 1024 * 1024 * 1024 bytes
assert.Equal(t, Value{F: 1024 * 1024 * 1024, U: "bytes"}, dataConverter.Convert(Value{F: 1, U: "gbytes"}, "bytes"))
// 1024 gbytes = 1 tbytes
assert.Equal(t, Value{F: 1, U: "tbytes"}, dataConverter.Convert(Value{F: 1024, U: "gbytes"}, "tbytes"))
// 1 tbytes = 1024 gbytes
assert.Equal(t, Value{F: 1024, U: "gbytes"}, dataConverter.Convert(Value{F: 1, U: "tbytes"}, "gbytes"))
// 1 tbytes = 1024 * 1024 mbytes
assert.Equal(t, Value{F: 1024 * 1024, U: "mbytes"}, dataConverter.Convert(Value{F: 1, U: "tbytes"}, "mbytes"))
// 1 tbytes = 1024 * 1024 * 1024 kbytes
assert.Equal(t, Value{F: 1024 * 1024 * 1024, U: "kbytes"}, dataConverter.Convert(Value{F: 1, U: "tbytes"}, "kbytes"))
// 1 tbytes = 1024 * 1024 * 1024 * 1024 bytes
assert.Equal(t, Value{F: 1024 * 1024 * 1024 * 1024, U: "bytes"}, dataConverter.Convert(Value{F: 1, U: "tbytes"}, "bytes"))
// 1024 tbytes = 1 pbytes
assert.Equal(t, Value{F: 1, U: "pbytes"}, dataConverter.Convert(Value{F: 1024, U: "tbytes"}, "pbytes"))
// 1 pbytes = 1024 tbytes
assert.Equal(t, Value{F: 1024, U: "tbytes"}, dataConverter.Convert(Value{F: 1, U: "pbytes"}, "tbytes"))
}

View File

@ -0,0 +1,26 @@
package converter
// percentConverter is a converter for percent unit
type percentConverter struct{}
func NewPercentConverter() Converter {
return &percentConverter{}
}
func FromPercentUnit(u Unit) float64 {
switch u {
case "percent":
return 1
case "percentunit":
return 100
default:
return 1
}
}
func (c *percentConverter) Convert(v Value, to Unit) Value {
return Value{
F: v.F * FromPercentUnit(v.U) / FromPercentUnit(to),
U: to,
}
}

View File

@ -0,0 +1,16 @@
package converter
import (
"testing"
"github.com/stretchr/testify/assert"
)
func TestPercentConverter(t *testing.T) {
percentConverter := NewPercentConverter()
assert.Equal(t, Value{F: 1, U: "percent"}, percentConverter.Convert(Value{F: 1, U: "percent"}, "percent"))
assert.Equal(t, Value{F: 100, U: "percent"}, percentConverter.Convert(Value{F: 1, U: "percentunit"}, "percent"))
assert.Equal(t, Value{F: 1, U: "percentunit"}, percentConverter.Convert(Value{F: 100, U: "percent"}, "percentunit"))
assert.Equal(t, Value{F: 0.01, U: "percentunit"}, percentConverter.Convert(Value{F: 1, U: "percent"}, "percentunit"))
}

View File

@ -0,0 +1,17 @@
package converter
// throughputConverter is an implementation of Converter that converts throughput
type throughputConverter struct {
}
func NewThroughputConverter() Converter {
return &throughputConverter{}
}
func (c *throughputConverter) Convert(v Value, to Unit) Value {
// There is no conversion to be done for throughput
return Value{
F: v.F,
U: to,
}
}

View File

@ -0,0 +1,58 @@
package converter
type Duration float64
const (
Nanosecond = Second * 1e-9
Microsecond = Second * 1e-6
Millisecond = Second * 1e-3
Centisecond = Second * 1e-2
Decisecond = Second * 1e-1
Second Duration = 1e0
Minute = Second * 60
Hour = Minute * 60
Day = Hour * 24
Week = Day * 7
)
// durationConverter is an implementation of Converter for durations.
type durationConverter struct {
}
func NewDurationConverter() Converter {
return &durationConverter{}
}
func FromTimeUnit(u Unit) Duration {
switch u {
case "ns":
return Nanosecond
case "us":
return Microsecond
case "ms":
return Millisecond
case "cs":
return Centisecond
case "ds":
return Decisecond
case "s":
return Second
case "m":
return Minute
case "h":
return Hour
case "d":
return Day
case "w":
return Week
default:
return Second
}
}
func (c *durationConverter) Convert(v Value, to Unit) Value {
return Value{
F: v.F * float64(FromTimeUnit(v.U)) / float64(FromTimeUnit(to)),
U: to,
}
}

View File

@ -0,0 +1,55 @@
package converter
import (
"testing"
"github.com/stretchr/testify/assert"
)
func TestDurationConvert(t *testing.T) {
timeConverter := NewDurationConverter()
// 1000 ms = 1 s
assert.Equal(t, Value{F: 1, U: "s"}, timeConverter.Convert(Value{F: 1000, U: "ms"}, "s"))
// 1000000 us = 1 s
assert.Equal(t, Value{F: 1, U: "s"}, timeConverter.Convert(Value{F: 1000000, U: "us"}, "s"))
// 100000 ms = 100 s
assert.Equal(t, Value{F: 100, U: "s"}, timeConverter.Convert(Value{F: 100000, U: "ms"}, "s"))
// 1 s = 1000 ms
assert.Equal(t, Value{F: 1000, U: "ms"}, timeConverter.Convert(Value{F: 1, U: "s"}, "ms"))
// 60 s = 1 m
assert.Equal(t, Value{F: 1, U: "m"}, timeConverter.Convert(Value{F: 60, U: "s"}, "m"))
// 604800000000000 ns = 1 w
assert.Equal(t, Value{F: 1, U: "w"}, timeConverter.Convert(Value{F: 604800000000000, U: "ns"}, "w"))
// 1 m = 60 s
assert.Equal(t, Value{F: 60, U: "s"}, timeConverter.Convert(Value{F: 1, U: "m"}, "s"))
// 60 m = 1 h
assert.Equal(t, Value{F: 1, U: "h"}, timeConverter.Convert(Value{F: 60, U: "m"}, "h"))
// 168 h = 1 w
assert.Equal(t, Value{F: 1, U: "w"}, timeConverter.Convert(Value{F: 168, U: "h"}, "w"))
// 1 h = 60 m
assert.Equal(t, Value{F: 60, U: "m"}, timeConverter.Convert(Value{F: 1, U: "h"}, "m"))
// 24 h = 1 d
assert.Equal(t, Value{F: 1, U: "d"}, timeConverter.Convert(Value{F: 24, U: "h"}, "d"))
// 10080 m = 1 w
assert.Equal(t, Value{F: 1, U: "w"}, timeConverter.Convert(Value{F: 10080, U: "m"}, "w"))
// 1 d = 24 h
assert.Equal(t, Value{F: 24, U: "h"}, timeConverter.Convert(Value{F: 1, U: "d"}, "h"))
// 7 d = 1 w
assert.Equal(t, Value{F: 1, U: "w"}, timeConverter.Convert(Value{F: 7, U: "d"}, "w"))
// 1 w = 7 d
assert.Equal(t, Value{F: 7, U: "d"}, timeConverter.Convert(Value{F: 1, U: "w"}, "d"))
// 1 w = 168 h
assert.Equal(t, Value{F: 168, U: "h"}, timeConverter.Convert(Value{F: 1, U: "w"}, "h"))
// 1 w = 10080 m
assert.Equal(t, Value{F: 10080, U: "m"}, timeConverter.Convert(Value{F: 1, U: "w"}, "m"))
// 604800 s = 1 w
assert.Equal(t, Value{F: 1, U: "w"}, timeConverter.Convert(Value{F: 604800, U: "s"}, "w"))
// 1 w = 604800 s
assert.Equal(t, Value{F: 604800, U: "s"}, timeConverter.Convert(Value{F: 1, U: "w"}, "s"))
// 1 w = 604800000000000 ns
assert.Equal(t, Value{F: 604800000000000, U: "ns"}, timeConverter.Convert(Value{F: 1, U: "w"}, "ns"))
// 1000 us = 1 ms
assert.Equal(t, Value{F: 1, U: "ms"}, timeConverter.Convert(Value{F: 1000, U: "us"}, "ms"))
// 1000000000 ns = 1 s
assert.Equal(t, Value{F: 1, U: "s"}, timeConverter.Convert(Value{F: 1000000000, U: "ns"}, "s"))
}