Преобразование времени. Тип значения микросекунд в миллисекундах
Я использую go-ping (https://github.com/sparrc/go-ping) библиотеку golang для непривилегированного пинга ICMP.
timeout := time.Second*1000
interval := time.Second
count := 5
host := p.ipAddr
pinger, cmdErr := ping.NewPinger(host)
pinger.Count = count
pinger.Interval = interval
pinger.Timeout = timeout
pinger.SetPrivileged(false)
pinger.Run()
stats := pinger.Statistics()
latency = stats.AvgRtt // stats.AvgRtt is time.Duration type
jitter = stats.StdDevRtt// stats.StdDevRtt is time.Duration type
От запуска этого, я получаю латентность в миллисекундах и дрожание в микросекундах. Я хочу, чтобы один и тот же блок для обоих, пусть говорят миллисекунды, поэтому, когда я делаю jitter = stats.StdDevRtt/1000
или jitter = jitter/1000
(для преобразования микросекунд в миллисекунды), то, что я получаю, является джиттером в наносекундах:( Есть ли способ получить одинаковые миллисекунды для как латентность, так и дрожание.
Ответы
Ответ 1
Число до time.Duration
time.Duration
- это тип, имеющий int64
как его базовый тип, который хранит продолжительность в наносекундах.
Если вы знаете значение, но хотите, кроме наносекунд, просто умножьте желаемый блок, например:
d := 100 * time.Microsecond
fmt.Println(d) // Output: 100µs
Вышеупомянутое работает, потому что 100
является нетипизированным constant, и его можно автоматически преобразовать в time.Duration
, у которого int64
базовый тип.
Обратите внимание, что если у вас есть значение как типизированное значение, вы должны использовать явное преобразование типа :
value := 100 // value is of type int
d2 := time.Duration(value) * time.Millisecond
fmt.Println(d2) // Output: 100ms
time.Duration
на номер
Итак, time.Duration
- это всегда наносекунды. Если вам это нужно в миллисекундах, например, все, что вам нужно сделать, это разделить значение time.Duration
на количество наносекунд за миллисекунду:
ms := int64(d2 / time.Millisecond)
fmt.Println("ms:", ms) // Output: ms: 100
Другие примеры:
fmt.Println("ns:", int64(d2/time.Nanosecond)) // ns: 100000000
fmt.Println("µs:", int64(d2/time.Microsecond)) // µs: 100000
fmt.Println("ms:", int64(d2/time.Millisecond)) // ms: 100
Попробуйте примеры на Go Playground.
Если ваш дрожание (длительность) меньше единицы, в которую вы хотите преобразовать ее, вам нужно использовать деление с плавающей запятой, иначе будет выполняться целочисленное деление, которое отсекает часть дроби. Подробнее см.: Голанский округ до ближайшего 0,05.
Преобразуйте джиттер и блок в float64
перед делением:
d := 61 * time.Microsecond
fmt.Println(d) // Output: 61µs
ms := float64(d) / float64(time.Millisecond)
fmt.Println("ms:", ms) // Output: ms: 0.061
Вывод (попробуйте на Go Playground):
61µs
ms: 0.061
Ответ 2
Тип переменных latency
и jitter
равен time.Duration
, который в определение его базовый тип - int64 и выражается в наносекунд.
Когда вы используете функции печати, вызывается метод String
типа time.Duration
и он использует h
, s
, m
, µ
, n
при печати продолжительности, вот документация для метода String
:
// String returns a string representing the duration in the form "72h3m0.5s".
// Leading zero units are omitted. As a special case, durations less than one
// second format use a smaller unit (milli-, micro-, or nanoseconds) to ensure
// that the leading digit is non-zero. The zero duration formats as 0s.
В временном пакете есть предварительно определенные константы, которые вы можете использовать для преобразования переменной продолжительности в предпочитаемую единицу времени, например
latencyInMicroSeconds := int64(jitter / time.Microsecond)
Обратите внимание, что мы преобразовали его в тип int
, потому что, если вы его не будете в типе time.Duration
, и значение этого типа считается находящимся в nano-втором блоке, но теперь это микро-секунда, вызывают дополнительную проблему в вычислениях, если вы собираетесь использовать функции временного пакета.