Mercurial > gemma
view pkg/common/time.go @ 5652:9b3779f649c2 v5.7.1
Bumped version for release.
author | Sascha Wilde <wilde@sha-bang.de> |
---|---|
date | Mon, 07 Aug 2023 17:59:18 +0200 |
parents | b3b990811f2c |
children |
line wrap: on
line source
// This is Free Software under GNU Affero General Public License v >= 3.0 // without warranty, see README.md and license for details. // // SPDX-License-Identifier: AGPL-3.0-or-later // License-Filename: LICENSES/AGPL-3.0.txt // // Copyright (C) 2018, 2019 by via donau // – Österreichische Wasserstraßen-Gesellschaft mbH // Software engineering by Intevation GmbH // // Author(s): // * Sascha L. Teichmann <sascha.teichmann@intevation.de> // * Bernhard E. Reiter <bernhard.reiter@intevation.de> package common import ( "math" "time" ) const ( // time.RFC3339 equals "simplified ISO format as defined by ECMA-262" // https://tc39.github.io/ecma262/#sec-date-time-string-format // and "SHOULD be used in new protocols on the Internet." (RFC section 5.6) // TimeFormat is the preferred time format represention in gemma. TimeFormat = time.RFC3339 // TimeFormatMicro is the same as TimeFormat but also // contains 3 digits for micro seconds. // This is useful for e.g. times in imports and the // respective logs. TimeFormatMicro = "2006-01-02T15:04:05.999Z07:00" // TimeFormatMicroLocal is the same as TimeFormatMicro but // w/o the timezone. Only used for tolerant parsing. TimeFormatMicroLocal = "2006-01-02T15:04:05.000" // DateFormat represents the preferred date format in Gemma. DateFormat = "2006-01-02" ) // TimeParser is a list of time formats. type TimeParser []string // ParseTime parses the time formats known to Gemma. var ParseTime = TimeParser{ TimeFormat, TimeFormatMicro, TimeFormatMicroLocal, DateFormat, }.Parse var utc0 = time.Unix(0, 0) // Parse tries to parse a given string by the entries of the layout // list one after another. The first matching time is returned. // If no layout matches the last error is returned or time zero // if the layout list is empty. func (tg TimeParser) Parse(s string) (time.Time, error) { var err error var t time.Time for _, layout := range tg { if t, err = time.Parse(layout, s); err == nil { break } } return t, err } // InterpolateTime returns a function that linearly interpolates the // time between t1 and t2 for given value m1 to m2. // If m1 is given to the returned function t1 is returned. // If m2 is given to the returned function t2 is returned. // Values between m1 and m2 will result in the proportional // time between t1 and t2. func InterpolateTime(t1 time.Time, m1 float64, t2 time.Time, m2 float64) func(float64) time.Time { // f(m1) = t1 // f(m2) = t2 // t1 = m1*a + b <=> b = t1 - m1*a // t2 = m2*a + b // t1 - t2 = a*(m1 - m2) // a = (t1-t2)/(m1 - m2) for m1 != m2 if m1 == m2 { t := t1.Add(t2.Sub(t1) / 2) return func(float64) time.Time { return t } } a := t1.Sub(t2).Seconds() / (m1 - m2) b := t1.Sub(utc0).Seconds() - m1*a return func(m float64) time.Time { x := m*a + b secs := math.Ceil(x) nsecs := math.Ceil((x - secs) * (999999999 + 1)) return time.Unix(int64(secs), int64(nsecs)) } } // MinTime returns the earlier time of a and b. func MinTime(a, b time.Time) time.Time { if a.Before(b) { return a } return b } // MaxTime returns the later time of a and b. func MaxTime(a, b time.Time) time.Time { if a.After(b) { return a } return b } // OrderTime orders the times a and b ascendingly. func OrderTime(a, b time.Time) (time.Time, time.Time) { if a.Before(b) { return a, b } return b, a } // Dusk returns the beginning of the day the time t is in. func Dusk(t time.Time) time.Time { return time.Date( t.Year(), t.Month(), t.Day(), 0, 0, 0, 0, t.Location()) } // Dawn returns the last time of the day the time t is in. func Dawn(t time.Time) time.Time { return time.Date( t.Year(), t.Month(), t.Day(), 23, 59, 59, 999999999, t.Location()) }