2017-02-22 63 views
1

Есть ли способ форматирования вывода time.Since() добавить дни, когда aplicable, что-то вроде:время, так как в формате дни, часы, минуты, секунды

[days]d[hours]h[minutes]m[seconds]s 

Текущий формат, кажется, использует только часов, как максимальная единица измерения:

start := time.Unix(1411691219, 0) 
diff := time.Since(start) 

21132h9m41.714117301s 

Но я хотел бы использовать дни вместо часов, чтобы получить что-то вроде:

880d12h9m41.7s 

В настоящее время я использую следующую функцию TimeDiff для получения желаемого результата, но задаюсь вопросом, есть ли простой/лучший/собственный способ достижения этого.

package main 

import (
    "bytes" 
    "fmt" 
    "math" 
    "time" 
) 

func main() { 
    start := time.Unix(1411691219, 0) 
    diff := time.Since(start) 
    fmt.Printf("diff = %s\n", diff) 
    fmt.Printf("diff = %s\n", TimeDiff(start)) 
} 

func TimeDiff(t time.Time) string { 
    diff := time.Since(t) 
    days := diff/(24 * time.Hour) 
    hours := diff % (24 * time.Hour) 
    minutes := hours % time.Hour 
    seconds := math.Mod(minutes.Seconds(), 60) 
    var buffer bytes.Buffer 
    if days > 0 { 
     buffer.WriteString(fmt.Sprintf("%dd", days)) 
    } 
    if hours/time.Hour > 0 { 
     buffer.WriteString(fmt.Sprintf("%dh", hours/time.Hour)) 
    } 
    if minutes/time.Minute > 0 { 
     buffer.WriteString(fmt.Sprintf("%dm", minutes/time.Minute)) 
    } 
    if seconds > 0 { 
     buffer.WriteString(fmt.Sprintf("%.1fs", seconds)) 
    } 
    return buffer.String() 
} 
+3

Это проблема _hard_, поскольку дни имеют разные длительности: не просто прыжок секунд, но переход на летнее время. Если ваш день 24 часа: Хорошо. Проблема становится более очевидной, если вы думаете о отображении временных дельта в единицах месяца или года. – Volker

+0

В настоящее время я в основном хочу знать, какой процесс прошел, а не проводить расчеты даты в отношении дат. – nbari

+0

Связанные: [golang time.Since() с месяцами и годами] (http://stackoverflow.com/questions/36530251/golang-time-since-with-months-and-years/36531443#36531443). – icza

ответ

0

Чтобы ответить на ваш точный вопрос:

package main 

import (
    "fmt" 
    "time" 
) 

func FormatSince(t time.Time) string { 
    const (
     Decisecond = 100 * time.Millisecond 
     Day  = 24 * time.Hour 
    ) 
    ts := time.Since(t) 
    sign := time.Duration(1) 
    if ts < 0 { 
     sign = -1 
     ts = -ts 
    } 
    ts += +Decisecond/2 
    d := sign * (ts/Day) 
    ts = ts % Day 
    h := ts/time.Hour 
    ts = ts % time.Hour 
    m := ts/time.Minute 
    ts = ts % time.Minute 
    s := ts/time.Second 
    ts = ts % time.Second 
    f := ts/Decisecond 
    return fmt.Sprintf("%dd%dh%dm%d.%ds", d, h, m, s, f) 
} 

Выход:

diff = 21136h26m58.574146433s 
diff = 880d16h26m58.6s 

Для Go 1.8 и выше, это дает разницу в абсолютном (UTC) время. Это может не соответствовать разнице в времени настенных часов, на которые может повлиять переход на летнее время. На него также могут влиять корректировки часов системы (часы реального времени).

Начиная с версии 1.9, разница будет вычисляться с использованием монотонных часов, на которые не влияют изменения на настенные часы системы или летнее время.

0

Наивная реализация может быть: https://play.golang.org/p/VsVeIhoLGi

(Обратите внимание на предположение о постоянной продолжительности дня).