mirror of
https://github.com/gocsaf/csaf.git
synced 2025-12-22 11:55:40 +01:00
Add internal model for time ranges.
This commit is contained in:
parent
31a37a4daf
commit
0e297fc616
1 changed files with 81 additions and 0 deletions
81
internal/models/models.go
Normal file
81
internal/models/models.go
Normal file
|
|
@ -0,0 +1,81 @@
|
|||
// This file is Free Software under the MIT License
|
||||
// without warranty, see README.md and LICENSES/MIT.txt for details.
|
||||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
//
|
||||
// SPDX-FileCopyrightText: 2023 German Federal Office for Information Security (BSI) <https://www.bsi.bund.de>
|
||||
// Software-Engineering: 2023 Intevation GmbH <https://intevation.de>
|
||||
|
||||
// Package models contains helper models used in the tools internally.
|
||||
package models
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
// TimeRange is a time interval.
|
||||
type TimeRange [2]time.Time
|
||||
|
||||
// NewTimeInterval creates a new time range.
|
||||
// The time values will be sorted.
|
||||
func NewTimeInterval(a, b time.Time) TimeRange {
|
||||
if b.Before(a) {
|
||||
a, b = b, a
|
||||
}
|
||||
return TimeRange{a, b}
|
||||
}
|
||||
|
||||
// guessDate tries to guess an RFC 3339 date time from a given string.
|
||||
func guessDate(s string) (time.Time, bool) {
|
||||
for _, layout := range []string{
|
||||
"2006-01-02T15:04:05Z07:00",
|
||||
"2006-01-02T15:04:05",
|
||||
"2006-01-02T15:04",
|
||||
"2006-01-02T15",
|
||||
"2006-01-02",
|
||||
"2006-01",
|
||||
"2006",
|
||||
} {
|
||||
if t, err := time.Parse(s, layout); err == nil {
|
||||
return t, true
|
||||
}
|
||||
}
|
||||
return time.Time{}, false
|
||||
}
|
||||
|
||||
// UnmarshalText implements [encoding/text.TextUnmarshaler].
|
||||
func (tr *TimeRange) UnmarshalText(text []byte) error {
|
||||
|
||||
s := strings.TrimSpace(string(text))
|
||||
// Handle relative case first.
|
||||
if duration, err := time.ParseDuration(s); err == nil {
|
||||
now := time.Now()
|
||||
*tr = NewTimeInterval(now.Add(-duration), now)
|
||||
return nil
|
||||
}
|
||||
|
||||
a, b, found := strings.Cut(s, ",")
|
||||
a, b = strings.TrimSpace(a), strings.TrimSpace(b)
|
||||
|
||||
// Only start date?
|
||||
if !found {
|
||||
start, ok := guessDate(a)
|
||||
if !ok {
|
||||
return fmt.Errorf("%q is not a valid RFC date time", a)
|
||||
}
|
||||
*tr = NewTimeInterval(start, time.Now())
|
||||
}
|
||||
// Real interval
|
||||
start, ok := guessDate(a)
|
||||
if !ok {
|
||||
return fmt.Errorf("%q is not a valid RFC date time", a)
|
||||
}
|
||||
end, ok := guessDate(b)
|
||||
if !ok {
|
||||
return fmt.Errorf("%q is not a valid RFC date time", b)
|
||||
}
|
||||
*tr = NewTimeInterval(start, end)
|
||||
return nil
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue