Mercurial > gemma
view pkg/common/time.go @ 3109:973312bb77c6
Client: Fixed usage of published config to configure the OSM server URL.
author | Sascha L. Teichmann <sascha.teichmann@intevation.de> |
---|---|
date | Thu, 25 Apr 2019 18:39:02 +0200 |
parents | 8c4c1b3fd856 |
children | c86a8e70b40f |
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 = time.RFC3339 DateFormat = "2006-01-02" ) type ValueRangeKind int const ( ValueBelow ValueRangeKind = -1 ValueInside ValueRangeKind = 0 ValueAbove ValueRangeKind = +1 ) func InterpolateValueByTime(t1 time.Time, m1 float64, t2 time.Time, m2 float64) func(time.Time) (float64, ValueRangeKind) { // f(t1) = m1 // f(t2) = m2 // m1 = t1*a + b <=> b = m1 - t1*a // m2 = t2*a + b // m1 - m2 = a*(t1 - t2) // a = (m1 - m2)/(t1 - t2) for t1 != t2 if t1.Equal(t2) { return func(t time.Time) (float64, ValueRangeKind) { switch { case t.Before(t1): return 0, ValueBelow case t.After(t1): return 0, ValueAbove default: return m1 + (m2-m1)/2, ValueInside } } } var min, max time.Time if t1.Before(t2) { min, max = t1, t2 } else { min, max = t2, t1 } a := (m1 - m2) / t1.Sub(t2).Seconds() b := m1 - a*float64(t1.Unix()) return func(t time.Time) (float64, ValueRangeKind) { switch { case t.Before(min): return 0, ValueBelow case t.After(max): return 0, ValueAbove default: return a*float64(t.Unix()) + b, ValueInside } } } func InterpolateTimeByValue(t1 time.Time, m1 float64, t2 time.Time, m2 float64) func(float64) (time.Time, ValueRangeKind) { // 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 { return func(m float64) (time.Time, ValueRangeKind) { switch { case m < m1: return time.Time{}, ValueBelow case m > m1: return time.Time{}, ValueAbove default: return t1.Add(t2.Sub(t1) / 2), ValueInside } } } min, max := math.Min(m1, m2), math.Max(m1, m2) a := t1.Sub(t2).Seconds() / (m1 - m2) b := float64(t1.Unix()) - m1*a return func(m float64) (time.Time, ValueRangeKind) { switch { case m < min: return time.Time{}, ValueBelow case m > max: return time.Time{}, ValueAbove default: return time.Unix(int64(math.Ceil(m*a+b)), 0), ValueInside } } }