years

package module
v0.4.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 29, 2026 License: MIT Imports: 13 Imported by: 0

README

years

Everything has a time. Travel it.

A time toolkit for Go: parsing, formatting, humanizing, and navigating time-based data.

Go Reference Go Version


years bundles the time helpers you keep rewriting: one parser that accepts Go layouts, unix timestamps, and human aliases; zero-safe formatting with canonical layouts; "3h ago" humanization; fluent in-place mutation; and a Voyager for traversing anything that has a time - like calendar-structured file trees.

t, _ := years.JustParse("2024-05-26") // ISO dates & RFC3339 out of the box
t, _ = years.JustParse("1717852417")  // unix timestamps
t, _ = years.JustParse("yesterday")   // human aliases

years.Humanize(t) // "1d ago"

Install

go get github.com/amberpixels/years

Quick Start

package main

import (
	"fmt"

	"github.com/amberpixels/years"
)

func main() {
	created, _ := years.JustParse("2024-05-26 13:45")

	fmt.Println(years.Format(created, years.LayoutHumanDate)) // "May 26, 2024"
	fmt.Println(years.Humanize(created))                      // "2y ago"

	years.Mutate(&created).TruncateToDay().SetYear(2025)
	fmt.Println(years.Format(created, years.LayoutDate)) // "2025-05-26"

	d, _ := years.ParseISODuration("PT1H2M3S")
	fmt.Println(years.FormatDurationClock(d)) // "1:02:03"
}

Parsing

The default parser understands RFC3339 timestamps, 2006-01-02 15:04[:05], plain dates, unix-second timestamps, and aliases - no setup:

t, _ := years.JustParse("2024-05-26T13:45:00Z")
t, _ = years.JustParse("1717852417")
t, _ = years.JustParse("next-week")

// Strict single-layout parsing, like time.Parse:
t, _ = years.Parse("2006-01-02", "2024-05-26")

Aliases resolve against the package clock: today, yesterday, tomorrow, this-week, last-week, next-week, last-weekend, next-weekend, this-month, last-month, next-month, this-year, last-year, next-year.

Layouts may also contain a timestamp part: U@ for unix seconds, U@000 for milliseconds, U@000000 / U@000000000 for micro/nanoseconds:

p := years.NewParser(
	years.AcceptUnixMilli(),
	years.AcceptAliases(),
	years.WithLayouts("2006", "2006-01", "2006-Jan-02"),
)

t, _ = p.Parse("logs-U@000.log", "logs-1717852417000.log") // 2024-06-08 13:13:37 UTC
t, _ = p.JustParse("2020-01")

The global parser is configurable too - SetParserDefaults replaces its options, ExtendParserDefaults appends, ResetParserDefaults restores the out-of-the-box behavior:

years.ExtendParserDefaults(years.WithLayouts("2006, Jan 2"))
t, _ = years.JustParse("2020, Dec 1")

Formatting

Canonical display layouts (so you stop re-typing the reference-time magic strings), plus zero/nil-safe helpers:

t := time.Date(2025, time.April, 30, 13, 45, 0, 0, time.UTC)

years.Format(t, years.LayoutDate)          // "2025-04-30"
years.Format(t, years.LayoutDateTime)      // "2025-04-30 13:45:00"
years.Format(t, years.LayoutDateTimeShort) // "2025-04-30 13:45"
years.Format(t, years.LayoutHuman)         // "Apr 30, 2025 13:45"
years.Format(t, years.LayoutHumanDate)     // "Apr 30, 2025"

years.Format(time.Time{}, years.LayoutDate) // "" - the zero time renders empty
years.FormatPtr(nil, years.LayoutDate)      // "" - nil-safe

Durations

Parse ISO-8601 durations (e.g. YouTube's contentDetails.duration), and render durations media-clock style or in a compact human form:

d, _ := years.ParseISODuration("PT15M30S") // 15m30s
years.FormatDurationClock(d)               // "15:30"
years.FormatDurationClock(time.Hour + 2*time.Minute + 3*time.Second) // "1:02:03"

years.HumanizeDuration(90 * time.Minute) // "1h 30m"
years.HumanizeDuration(45 * time.Second) // "45s"

Relative Time

years.Humanize(time.Now().Add(-3 * time.Hour)) // "3h ago"
years.Humanize(time.Now().Add(48 * time.Hour)) // "in 2d"

// Clock-free variant (no global clock needed; handy in tests):
years.HumanizeFrom(base, base.Add(-5*time.Minute)) // "5m ago"

Humanize reads the package clock (years.Now()), so tests can make it deterministic via years.SetStdClock.

Mutating Time

Mutate wraps a *time.Time with fluent setters and truncation helpers that modify it in place:

t := time.Date(2025, time.April, 30, 13, 45, 59, 0, time.UTC)

years.Mutate(&t).TruncateToWeek(time.Monday) // t is now 2025-04-28 00:00:00
years.Mutate(&t).SetMonth(time.December).SetDay(24).SetHour(18)

Truncation goes down to any unit (TruncateToSecond ... TruncateToYear), setters cover SetYear ... SetNanosecond.

Voyager: Navigating Time-Based Data

Anything implementing Waypoint (an identifier, a time, optional children) can be traversed with a Voyager. Strings work out of the box:

dates := []string{"2024-03-01", "2024-01-01", "2024-02-01"}

v := years.NewVoyager(years.WaypointGroupFromStrings(dates))
_ = v.Traverse(func(w years.Waypoint) {
	fmt.Println(w.Identifier()) // 2024-03-01, 2024-02-01, 2024-01-01
}, years.O_PAST()) // newest first

Non-default layouts are given to the waypoints: years.WaypointGroupFromStrings(dates, "2006, Jan 2").

Files and directories named after dates form navigable calendars. Given a tree like calendar/2024/Jan/2024-01-15.txt:

wf, err := years.NewTimeNamedWaypointFile("calendar", "2006/Jan/2006-01-02.txt")
if err != nil {
	panic(err)
}

v := years.NewVoyager(wf)
_ = v.Traverse(func(w years.Waypoint) {
	fmt.Println(w.Identifier()) // file paths, oldest first
}, years.O_FUTURE(), years.O_LEAVES_ONLY())

// Jump straight to a date (aliases work here too):
found, _ := v.Navigate("yesterday")

Traverse options: O_PAST / O_FUTURE for direction, O_LEAVES_ONLY / O_CONTAINERS_ONLY / O_ALL for node filtering, O_NON_CALENDAR to include nodes without a parsed time. For time from file metadata (modification/creation/access) instead of names, see NewWaypointFile.

Schedules

The schedule subpackage models recurring weekly time windows - working hours, quiet hours, availability:

import "github.com/amberpixels/years/schedule"

work := schedule.Schedule{
	Days:      []time.Weekday{time.Monday, time.Tuesday, time.Wednesday, time.Thursday, time.Friday},
	StartHour: 9,
	EndHour:   17,
	Gaps:      []schedule.TimeRange{{StartHour: 12, EndHour: 13}}, // lunch break
}

work.Contains(t)         // true on a Monday at 10:30
work.SlotsForDay(t)      // [09:00-12:00, 13:00-17:00]
work.AvailableMinutes(t) // 420
work.NextMatchingDay(t)  // next scheduled day

MultiSlotSchedule covers disjoint (even cross-midnight) windows per day, and CompositeSchedule merges several schedules into one.

Week patterns

WeekPattern is a recurring wall-clock predicate - "weekends", "nights" - with no anchor in absolute time (unlike aliases: last-week resolves to one concrete week). ParsePatterns turns a human vocabulary into patterns; comma means union:

patterns, _ := schedule.ParsePatterns("weekends,mornings")

patterns.Contains(t) // true on Saturday 15:00, or on any day at 09:30

The built-in vocabulary (case-insensitive, plural-tolerant): weekday names (monday(s)...), weekend(s), workingday(s)/workday(s)/weekday(s), and the day parts of DefaultDayPartition:

part span
night 22:00-05:00 (wraps midnight)
morning 05:00-12:00
lunchtime 12:00-14:00
afternoon 14:00-17:00
evening 17:00-22:00

The partition covers the full day exactly once (enforced by Validate), so PartOf doubles as a group-by key:

schedule.DefaultDayPartition.PartOf(t).Name // "morning" | "lunchtime" | ...

A cross-midnight span belongs to the day it starts on - Sunday night includes Monday 01:00, the way humans mean it. Patterns read the wall clock of the given time as-is (no timezone field; callers own locality). Domain words and custom partitions plug in via Vocabulary:

vocab := schedule.DefaultVocabulary()
vocab.Extra = map[string]schedule.WeekPatterns{"officehours": {{
	Days:  []time.Weekday{time.Monday, time.Tuesday, time.Wednesday, time.Thursday, time.Friday},
	Spans: []schedule.DaySlot{{Start: schedule.TimeOfDay{Hour: 9}, End: schedule.TimeOfDay{Hour: 17}}},
}}}

patterns, _ := vocab.ParsePatterns("officehours")

Feedback

years is a solo, opinionated project - but if you stumbled upon it and have ideas, questions, or bug reports, an issue is always welcome :)

License

MIT © amberpixels

Documentation

Index

Constants

View Source
const (
	// LayoutDate is a calendar date: "2006-01-02".
	LayoutDate = "2006-01-02"
	// LayoutDateTime is a date with full wall-clock time: "2006-01-02 15:04:05".
	LayoutDateTime = "2006-01-02 15:04:05"
	// LayoutDateTimeShort is a date with minute precision: "2006-01-02 15:04".
	LayoutDateTimeShort = "2006-01-02 15:04"
	// LayoutHuman is a friendly date+time: "Jan 2, 2006 15:04".
	LayoutHuman = "Jan 2, 2006 15:04"
	// LayoutHumanDate is a friendly date: "Jan 2, 2006".
	LayoutHumanDate = "Jan 2, 2006"
)

Canonical display layouts shared across amberpixels apps, centralized here so callers stop re-typing the Go reference-time magic strings. These are the formatting counterparts to the parser: build a time with Parse/JustParse, render it with Format and one of these layouts.

View Source
const (
	LayoutTimestampSeconds      = "U@"
	LayoutTimestampMilliseconds = "U@000"
	LayoutTimestampMicroseconds = "U@000000"
	LayoutTimestampNanoseconds  = "U@000000000"
)

Variables

View Source
var DateUnitsDict = struct {
	Day   DateUnit
	Month DateUnit
	Year  DateUnit

	UnixSecond      DateUnit
	UnixMillisecond DateUnit
	UnixMicrosecond DateUnit
	UnixNanosecond  DateUnit
}{
	Day:   Day,
	Month: Month,
	Year:  Year,

	UnixSecond:      UnixSecond,
	UnixMillisecond: UnixMillisecond,
	UnixMicrosecond: UnixMicrosecond,
	UnixNanosecond:  UnixNanosecond,
}

DateUnitsDict holds all available DateUnits.

DefaultLayouts are the common, unambiguous Go layouts the default parser understands out of the box, so years.JustParse handles the ISO-8601 forms apps see most often (RFC3339 timestamps and plain dates) without per-call setup. Ordered most-specific first so the first successful match is the intended one. RFC3339Nano is listed alone because its trailing-.9 form already matches timestamps with or without a fractional second.

View Source
var DefaultParser = func() *Parser {
	return NewParser(defaultParserOptions...)
}

DefaultParser makes a default parser

View Source
var ErrInvalidISODuration = errors.New("invalid ISO-8601 duration")

ErrInvalidISODuration is returned by ParseISODuration for input that is not a supported ISO-8601 duration.

View Source
var LayoutFormatDict = struct {
	GoFormat      LayoutFormat
	UnixTimestamp LayoutFormat
}{
	GoFormat:      LayoutFormatGo,
	UnixTimestamp: LayoutFormatUnixTimestamp,
}

LayoutFormatDict holds all available LayoutFormats.

Functions

func ExtendParserDefaults

func ExtendParserDefaults(opts ...ParserOption)

func Format added in v0.0.10

func Format(t time.Time, layout string) string

Format renders t using layout, returning "" for the zero time so callers don't emit a meaningless "0001-01-01". It is the formatting counterpart to JustParse.

func FormatDurationClock added in v0.0.10

func FormatDurationClock(d time.Duration) string

FormatDurationClock renders d in colon-separated media style: "M:SS" when under an hour (e.g. "15:30") and "H:MM:SS" otherwise (e.g. "1:02:03"). Negative durations are treated as zero. Sub-second remainders are truncated.

func FormatPtr added in v0.0.10

func FormatPtr(t *time.Time, layout string) string

FormatPtr is the nil-safe variant of Format: a nil (or zero) time yields "".

func Humanize added in v0.0.10

func Humanize(t time.Time) string

Humanize renders t relative to the current time (the package clock, see Now), automatically choosing past ("3d ago") or future ("in 3d") phrasing; gaps under a minute render as "just now". It is the Go counterpart to the "time ago" helpers usually hand-written on the frontend. For deterministic results in tests, override the clock via SetStdClock or use HumanizeFrom.

func HumanizeDuration added in v0.0.10

func HumanizeDuration(d time.Duration) string

HumanizeDuration renders d as a compact, human-friendly approximation: the two most-significant non-zero units, e.g. 2h5m3s -> "2h 5m", 90m -> "1h 30m", 1d30m -> "1d 30m", 45s -> "45s". A duration with a single non-zero unit renders it alone (3h -> "3h"). Sub-second durations render as "0s". The sign is dropped (magnitude only); use Humanize/HumanizeFrom for signed, relative "ago"/"in" phrasing.

func HumanizeFrom added in v0.0.10

func HumanizeFrom(base, t time.Time) string

HumanizeFrom is Humanize with an explicit base time instead of the package clock, so it needs no clock and is convenient for tests: it describes t as seen from base ("3d ago" when t precedes base, "in 3d" when it follows).

func JustParse added in v0.0.2

func JustParse(value string) (time.Time, error)

JustParse calls JustParse of a default parser.

func JustParseRaw added in v0.0.5

func JustParseRaw(value any) (time.Time, error)

JustParseRaw attempts to convert or parse any value into a time.Time. - If value is time.Time (or custom type convertible to time.Time) the underlined time.Time is returned. - If value is a string or custom string type, passes to JustParse. - If value implements fmt.Stringer, uses its String() to be parsed via JustParse. - If value is a numeric type (int, uint, float), stringifies and passes to JustParse. - If value is nil, it returns a zero time.Time. Returns an error for unsupported types.

func Now added in v0.0.9

func Now() time.Time

Now returns the current time according to the package-level clock. By default it is equivalent to time.Now(); tests can override the source via SetStdClock, making any code that relies on years.Now() deterministic.

func Parse

func Parse(layout, value string) (time.Time, error)

Parse calls Parse of a default parser.

func ParseISODuration added in v0.0.10

func ParseISODuration(s string) (time.Duration, error)

ParseISODuration parses an ISO-8601 duration string into a time.Duration. It accepts the day+time subset (PnDTnHnMnS); calendar components (weeks, months, years) are rejected. An empty string is a zero duration with no error; any other input that carries no components (e.g. "P", "PT") is an error.

func ResetParserDefaults

func ResetParserDefaults()

func SetParserDefaults

func SetParserDefaults(opts ...ParserOption)

func SetStdClock

func SetStdClock(c Clock)

SetStdClock sets the default clock to use. Note: this considered to be called from tests, so time.Now() is mockable.

Types

type Clock

type Clock interface {
	Now() time.Time
}

type DateUnit

type DateUnit int

DateUnit stays for the unit of a date like Day/Month/Year/etc.

const (
	// Day as day of the month
	// TODO(nice-to-have) support day of the week + day of the year.
	Day  DateUnit = 1 << iota
	Week          // not supported yet
	Month
	Quarter // not supported yet
	Year

	// UnixSecond as well as UnixMillisecond, UnixMicrosecond, UnixNanosecond
	// are special units for Unix timestamps.
	UnixSecond
	UnixMillisecond
	UnixMicrosecond
	UnixNanosecond
)
const UnitUndefined DateUnit = 0

func (DateUnit) Defined

func (du DateUnit) Defined() bool

func (DateUnit) String

func (du DateUnit) String() string

type LayoutDetails

type LayoutDetails struct {
	// MinimalUnit e.g. Day for "2006-01-02" and Month for "2006-01"
	MinimalUnit DateUnit

	// Format is the format of the time used in the layout
	Format LayoutFormat

	// Units met in layout
	Units []DateUnit
}

LayoutDetails stores parsed meta information about given layout string. e.g. "2006-02-01".

func ParseLayout

func ParseLayout(layout string) *LayoutDetails

ParseLayout parses given layout string and returns LayoutDetails.

Note: it's a pretty hacky/weak function, but we're OK with it for now.

func (*LayoutDetails) HasUnit

func (lm *LayoutDetails) HasUnit(q DateUnit) bool

type LayoutFormat

type LayoutFormat int
const (
	// LayoutFormatGo is a format that is supported by Go time.Parse.
	LayoutFormatGo LayoutFormat = 1 << iota
	// LayoutFormatUnixTimestamp is a format that parses time from Unix timestamp (seconds or milliseconds).
	LayoutFormatUnixTimestamp
)
const LayoutFormatUndefined LayoutFormat = 0

func (LayoutFormat) String

func (lf LayoutFormat) String() string

type MutatingTime

type MutatingTime struct {
	// contains filtered or unexported fields
}

MutatingTime is a wrapper around a time.Time pointer, providing fluent setter methods that mutate the underlying time.

Example:

t, _ := time.Parse("2006-01-02 15:04:05", "2025-04-30 13:45:00")
Mutate(&t).SetMonth(time.April).SetYear(2021)
// t is now 2021-04-30 13:45:00.

Use Mutate to obtain a MutatingTime for in-place modifications.

func Mutate

func Mutate(v *time.Time) *MutatingTime

Mutate returns a MutatingTime for the given *time.Time.

func (*MutatingTime) SetDay

func (mt *MutatingTime) SetDay(day int) *MutatingTime

SetDay sets the day of the month to the provided value.

func (*MutatingTime) SetHour

func (mt *MutatingTime) SetHour(hour int) *MutatingTime

SetHour sets the hour (0–23). Panics if out of range.

func (*MutatingTime) SetMillisecond added in v0.0.5

func (mt *MutatingTime) SetMillisecond(ms int) *MutatingTime

SetMillisecond sets the millisecond (0–999) by overriding the nanosecond field. Panics if out of range.

func (*MutatingTime) SetMinute

func (mt *MutatingTime) SetMinute(minute int) *MutatingTime

SetMinute sets the minute (0–59). Panics if out of range.

func (*MutatingTime) SetMonth

func (mt *MutatingTime) SetMonth(month time.Month) *MutatingTime

SetMonth sets the month to the provided value.

func (*MutatingTime) SetNanosecond

func (mt *MutatingTime) SetNanosecond(nano int) *MutatingTime

SetNanosecond sets the nanosecond (0–999,999,999). Panics if out of range.

func (*MutatingTime) SetSecond

func (mt *MutatingTime) SetSecond(second int) *MutatingTime

SetSecond sets the second (0–59). Panics if out of range.

func (*MutatingTime) SetYear

func (mt *MutatingTime) SetYear(year int) *MutatingTime

SetYear sets the year to the provided value.

func (*MutatingTime) Time

func (mt *MutatingTime) Time() time.Time

Time returns the underlying time.Time value.

func (*MutatingTime) TruncateToDay

func (mt *MutatingTime) TruncateToDay() *MutatingTime

TruncateToDay sets the hour, minute, second, and nanosecond to zero.

func (*MutatingTime) TruncateToHour added in v0.0.9

func (mt *MutatingTime) TruncateToHour() *MutatingTime

TruncateToHour sets the minute, second, and nanosecond to zero.

func (*MutatingTime) TruncateToMinute added in v0.0.9

func (mt *MutatingTime) TruncateToMinute() *MutatingTime

TruncateToMinute sets the second and nanosecond to zero.

func (*MutatingTime) TruncateToMonth added in v0.0.9

func (mt *MutatingTime) TruncateToMonth() *MutatingTime

TruncateToMonth moves the time to the first day of its month at 00:00:00.

func (*MutatingTime) TruncateToSecond added in v0.0.9

func (mt *MutatingTime) TruncateToSecond() *MutatingTime

TruncateToSecond sets the nanosecond to zero, keeping everything down to the second.

func (*MutatingTime) TruncateToWeek added in v0.0.9

func (mt *MutatingTime) TruncateToWeek(weekStartsOn time.Weekday) *MutatingTime

TruncateToWeek moves the time back to the start of its week (at 00:00:00), where weekStartsOn selects which weekday begins the week (e.g. time.Monday for ISO-8601 weeks, time.Sunday for US-style weeks).

func (*MutatingTime) TruncateToYear added in v0.0.9

func (mt *MutatingTime) TruncateToYear() *MutatingTime

TruncateToYear moves the time to January 1st of its year at 00:00:00.

type Parser

type Parser struct {
	// contains filtered or unexported fields
}

func NewParser

func NewParser(options ...ParserOption) *Parser

func (*Parser) JustParse

func (p *Parser) JustParse(value string) (time.Time, error)

JustParse is a shortcut for Parse("", value) (so using all parser's accepted layouts).

func (*Parser) JustParsePeriod added in v0.2.0

func (p *Parser) JustParsePeriod(value string) (Period, error)

JustParsePeriod is a shortcut for ParsePeriod("", value).

func (*Parser) Parse

func (p *Parser) Parse(layout, value string) (time.Time, error)

Parse parses time from given value using given layout (or using all parser's accepted layouts if layout is empty).

func (*Parser) ParseEpoch added in v0.0.3

func (p *Parser) ParseEpoch(v int64) (time.Time, bool, error)

ParseEpoch converts the given epoch timestamp int64 as a time.Time, considering input as seconds/milliseconds/microseconds/nanoseconds. Better use one specific configuration: seconds or milliseconds, etc. In case if multiple configurations are enabled, there are edge-cases (both seconds/milli from 1970).

func (*Parser) ParsePeriod added in v0.2.0

func (p *Parser) ParsePeriod(layout, value string) (Period, error)

ParsePeriod parses value into the Period it denotes, using the given layout (or all of the parser's accepted layouts when layout is empty):

  • a registered alias resolves to its calendar period ("yesterday" → that whole day, "last-week" → that whole week);
  • a relative offset ("7d", "2w") resolves to [now − offset, now);
  • a value matching a date-only layout resolves to that whole day;
  • anything else Parse understands (timestamps, epochs) resolves to an instant period.

type ParserOption

type ParserOption func(*Parser)

func AcceptAliases

func AcceptAliases() ParserOption

func AcceptRelativeOffsets added in v0.2.0

func AcceptRelativeOffsets() ParserOption

AcceptRelativeOffsets opts in to duration-offset expressions ("12h", "7d", "2w", "3mo", "1y"). An offset denotes the period of the last N units (see ParsePeriod); the instant Parse returns that period's start, i.e. now − offset.

func AcceptUnixMicro

func AcceptUnixMicro() ParserOption

func AcceptUnixMilli

func AcceptUnixMilli() ParserOption

func AcceptUnixNano

func AcceptUnixNano() ParserOption

func AcceptUnixSeconds

func AcceptUnixSeconds() ParserOption

func GetParserDefaults

func GetParserDefaults() []ParserOption

func WithCustomAliases

func WithCustomAliases(customAliases map[string]func(time.Time) time.Time) ParserOption

WithCustomAliases merges the given aliases into the parser's alias table (custom entries win over same-named core ones). The parser's table is cloned first: the shared core alias map and the caller's map both stay untouched.

func WithCustomClock

func WithCustomClock(c Clock) ParserOption

WithCustomClock opts to enable a custom Clock.

func WithLayouts

func WithLayouts(layouts ...string) ParserOption

type Period added in v0.2.0

type Period struct {
	Start time.Time
	End   time.Time
}

Period is a half-open time interval [Start, End): Start belongs to the period, End does not. Calendar expressions denote periods rather than instants — "yesterday" is a whole day, "last-week" a whole week, and a plain date like "2024-03-06" a day — so parsing them with ParsePeriod yields the full interval; take .Start or .End when a single bound is needed (e.g. a range query's inclusive lower / exclusive upper bound). A point in time (an RFC3339 timestamp, a unix epoch) parses to an instant period whose End equals its Start.

func InstantPeriod added in v0.2.0

func InstantPeriod(t time.Time) Period

InstantPeriod wraps a single point in time as a zero-length Period.

func JustParsePeriod added in v0.2.0

func JustParsePeriod(value string) (Period, error)

JustParsePeriod calls JustParsePeriod of a default parser.

func ParsePeriod added in v0.2.0

func ParsePeriod(layout, value string) (Period, error)

ParsePeriod calls ParsePeriod of a default parser.

func (Period) Contains added in v0.2.0

func (p Period) Contains(t time.Time) bool

Contains reports whether t falls inside the half-open interval; an instant period contains exactly its own point.

func (Period) Duration added in v0.2.0

func (p Period) Duration() time.Duration

func (Period) IsInstant added in v0.2.0

func (p Period) IsInstant() bool

IsInstant reports whether the period is a zero-length point in time.

func (Period) IsZero added in v0.2.0

func (p Period) IsZero() bool

type StdClock

type StdClock struct{}

func (*StdClock) Now

func (c *StdClock) Now() time.Time

type TimeNamedWaypointFile

type TimeNamedWaypointFile struct {
	*WaypointFile
	// contains filtered or unexported fields
}

TimeNamedWaypointFile is a Waypoint implementation for files/directories.

func NewTimeNamedWaypointFile

func NewTimeNamedWaypointFile(
	path string, fullLayout string,
	parentArg ...*TimeNamedWaypointFile,
) (*TimeNamedWaypointFile, error)

func (*TimeNamedWaypointFile) Time

func (w *TimeNamedWaypointFile) Time() time.Time

type TimeNamedWaypointFiles

type TimeNamedWaypointFiles []*TimeNamedWaypointFile

type TraverseDirection

type TraverseDirection string

TraverseDirection is a direction for traversing (e.g. past or future).

const (
	TraverseDirectionPast   TraverseDirection = "past"
	TraverseDirectionFuture TraverseDirection = "future"
)

type TraverseNodesMode

type TraverseNodesMode string

TraverseNodesMode specifies which type of nodes to traverse (e.g. leaves only or containers only).

const (
	TraverseLeavesOnly     TraverseNodesMode = "leaves_only"
	TraverseContainersOnly TraverseNodesMode = "containers_only"
	TraverseAllNodes       TraverseNodesMode = "all"
)

type TraverseOption

type TraverseOption func(*traverseConfig)

TraverseOption defines functional options for the Traverse function.

func O_ALL

func O_ALL() TraverseOption

O_ALL returns a TraverseOption for traversing all nodes.

func O_CONTAINERS_ONLY

func O_CONTAINERS_ONLY() TraverseOption

O_CONTAINERS_ONLY returns a TraverseOption for traversing only container nodes.

func O_FUTURE

func O_FUTURE() TraverseOption

O_FUTURE returns a TraverseOption for traversing in Future direction.

func O_LEAVES_ONLY

func O_LEAVES_ONLY() TraverseOption

O_LEAVES_ONLY returns a TraverseOption for traversing only leaf nodes.

func O_NON_CALENDAR

func O_NON_CALENDAR() TraverseOption

O_NON_CALENDAR returns a TraverseOption for including non calendar nodes.

func O_PAST

func O_PAST() TraverseOption

O_PAST returns a TraverseOption for traversing in Past direction.

type Voyager

type Voyager struct {
	// contains filtered or unexported fields
}

Voyager is a wrapper for a waypoint that allows for traversing through it.

func NewVoyager

func NewVoyager(root Waypoint, parserArg ...*Parser) *Voyager

func (*Voyager) Find

func (v *Voyager) Find(timeStr string) ([]Waypoint, error)

Find returns the all found Waypoints that match given time (as a string) e.g. Find("yesterday") returns all waypoints whose time is in the "yesterday" range.

func (*Voyager) Navigate

func (v *Voyager) Navigate(to string) (Waypoint, error)

Navigate returns the first found Waypoint that matches given time (as a string). E.g. Navigate("yesterday") returns waypoint corresponding to the yesterday's date.

func (*Voyager) Traverse

func (v *Voyager) Traverse(cb func(w Waypoint), opts ...TraverseOption) error

Traverse traverses through a given waypoint (all its children recursively).

type Waypoint

type Waypoint interface {
	// Identifier returns the identifier of the object.
	// E.g. for file waypoints it can be file path.
	Identifier() string

	// Time returns the time of the object.
	Time() time.Time

	// IsContainer returns true if the object can contain other objects.
	// E.g. for directories, it should return true.
	IsContainer() bool

	// Children returns the children of the object if it's a container.
	// E.g. for directories, it should return the list of files and directories inside.
	Children() []Waypoint
}

Waypoint is an interface for objects that have a time.

func AllChildren

func AllChildren(w Waypoint) []Waypoint

AllChildren is a helper function that gets ALL children of a waypoint (recursively).

func NewWaypointGroup

func NewWaypointGroup(identifier string, waypoints ...Waypoint) Waypoint

NewWaypointGroup create a group for given waypoints.

func WaypointGroupFromStrings

func WaypointGroupFromStrings(timeStrings []string, layoutArg ...string) Waypoint

func WaypointsFromStrings

func WaypointsFromStrings(timeStrings []string, layoutArg ...string) []Waypoint

type WaypointFile

type WaypointFile struct {
	// contains filtered or unexported fields
}

WaypointFile is a Waypoint implementation for files/directories.

func NewWaypointFile

func NewWaypointFile(path string, timeGetter func(timeSpec times.Timespec) time.Time) (*WaypointFile, error)

func (*WaypointFile) Children

func (w *WaypointFile) Children() []Waypoint

func (*WaypointFile) Identifier

func (w *WaypointFile) Identifier() string

func (*WaypointFile) IsContainer

func (w *WaypointFile) IsContainer() bool

func (*WaypointFile) Time

func (w *WaypointFile) Time() time.Time

type WaypointFiles

type WaypointFiles []*WaypointFile

type WaypointGroup

type WaypointGroup struct {
	// contains filtered or unexported fields
}

WaypointGroup stands for a simple implementation of Waypoint that is a container for other waypoints.

func (*WaypointGroup) Children

func (wg *WaypointGroup) Children() []Waypoint

func (*WaypointGroup) Identifier

func (wg *WaypointGroup) Identifier() string

func (*WaypointGroup) IsContainer

func (wg *WaypointGroup) IsContainer() bool

func (*WaypointGroup) Time

func (wg *WaypointGroup) Time() time.Time

Time returns group's time. For now group itself doesn't have a specific time. TODO(nice-to-have): this maybe configurable, e.g. no-time/min-time(children)/max-time(children)/time(children[0]), etc.

type WaypointString

type WaypointString struct {
	// contains filtered or unexported fields
}

WaypointString is a Waypoint implementation for a string that represents time.

func NewWaypointString

func NewWaypointString(v string, layoutArg ...string) *WaypointString

func (*WaypointString) Children

func (w *WaypointString) Children() []Waypoint

func (*WaypointString) Identifier

func (w *WaypointString) Identifier() string

func (*WaypointString) IsContainer

func (w *WaypointString) IsContainer() bool

func (*WaypointString) Time

func (w *WaypointString) Time() time.Time

func (*WaypointString) Voyager

func (w *WaypointString) Voyager(parserArg ...*Parser) *Voyager

type WaypointStrings

type WaypointStrings []*WaypointString

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL