duration

package
v1.21.0 Latest Latest
Warning

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

Go to latest
Published: Mar 27, 2026 License: MIT Imports: 12 Imported by: 0

README

Duration Package

License Go Version Coverage

The duration package provides an enhanced time.Duration type for Go, extending the standard library's capabilities by introducing native support for "days" (d) as a time unit in both parsing and formatting. It offers robust serialization for multiple data formats (JSON, YAML, TOML, CBOR, Text), seamless integration with configuration tools like Viper, and advanced utilities such as PID-controlled duration range generation and precise truncation. For extreme time scales requiring durations up to billions of years, the big sub-package provides a second-precision alternative based on int64 representing seconds.


Table of Contents


Overview

While Go's standard time.Duration is highly efficient, it lacks native support for the "days" unit in string representations and doesn't provide built-in serialization for many common formats. This package bridges that gap by providing a Duration type that is a direct alias of time.Duration, ensuring full compatibility while adding high-level features for modern application development.

Design Philosophy
  1. Seamless Compatibility: By using a type alias for time.Duration, this package ensures that its Duration type can be cast back and forth with zero overhead and used directly with standard library functions via the .Time() method.
  2. Human-Centric Design: We prioritize human-readable configuration. Allowing "7d" instead of "168h" makes system configurations significantly easier to maintain and understand.
  3. Extensible Serialization: Support for various encoding formats is baked-in, making the type a first-class citizen for APIs and configuration files.
  4. Scalar Scaling: The package architecture recognizes the trade-off between precision and range. While the main package offers nanosecond precision (±290 years), the big sub-package offers second-level precision (±292 billion years) using a seconds-based int64.
Key Features
  • Extended Time Units: Full support for the d (days) unit in Parse and String methods.
  • Multi-Format Serialization: Native support for JSON, YAML, TOML, CBOR, and Text encoding.
  • Adaptive Range Generation: Generate sequences of durations between two points using a Proportional-Integral-Derivative (PID) controller.
  • Viper & Mapstructure Integration: Includes a ViperDecoderHook for effortless loading of durations from configuration files.
  • Precise Truncation: Specialized methods to truncate durations to the nearest Day, Hour, Minute, Second, Millisecond, or Microsecond.
  • Complementary big Package: Handles durations up to ~292 billion years by using seconds as the base unit.
Key Benefits
  • Enhanced Readability: Express complex durations like "2d4h30m" directly in code and configuration.
  • Configuration Consistency: Standardize duration handling across JSON, YAML, and TOML without manual parsing logic.
  • Safe Large Durations: Use the big sub-package to safely handle long-term durations that would overflow a standard 64-bit nanosecond counter.
  • Advanced Timing Control: Leverage PID theory for smooth backoff and interval adjustments.

Architecture

Package Structure
duration/                    # Root package (Nanosecond precision)
├── big/                     # Sub-package (Second precision for large ranges)
│   ├── doc.go               # big documentation
│   ├── model.go             # big.Duration type (int64 seconds)
│   ├── interface.go         # big constructors and parsing
│   ├── parse.go             # big string parsing logic
│   ├── format.go            # big string formatting
│   ├── encode.go            # big serialization (JSON, YAML, TOML, CBOR, Text)
│   ├── operation.go         # big arithmetic and PID range generation
│   ├── truncate.go          # big rounding and truncation logic
│   └── ...                  # big tests and examples
├── doc.go                   # Main package documentation
├── model.go                 # Core Duration alias and unit check methods
├── interface.go             # Main constructors and Parse functions
├── parse.go                 # Internal parsing logic for extended units
├── format.go                # Internal formatting logic (String(), Days(), etc.)
├── encode.go                # Multi-format serialization implementation
├── truncate.go              # Unit-specific truncation (TruncateDays(), etc.)
├── operation.go             # PID-controlled range generation implementation
└── ...                      # Unit tests, integration tests, and examples
Package Architecture

The package architecture centers on extending the int64 nanosecond representation used by time.Duration, while providing a parallel int64 seconds-based representation in the big sub-package.

graph TD
    subgraph "Core Components"
        MD[duration.Duration <br/> int64 nanoseconds]
        BD[big.Duration <br/> int64 seconds]
    end

    subgraph "Standard Library Interop"
        TD[time.Duration]
        MD <-->|Alias - Zero Cost| TD
        BD -- ".Time() / ParseDuration()" --> TD
    end

    subgraph "Capabilities"
        Ser[Serialization <br/> JSON, YAML, TOML, CBOR, Text]
        Parse[Extended Parsing <br/> 'd' unit support]
        Ops[Advanced Ops <br/> PID Ranges, Truncation]
        Viper[Config Integration <br/> ViperDecoderHook]
    end

    MD --- Ser
    MD --- Parse
    MD --- Ops
    MD --- Viper

    BD --- Ser
    BD --- Parse
    BD --- Ops
    BD --- Viper
Dataflow

The dataflow illustrates how input strings or values are transformed into duration objects and subsequently utilized or exported.

sequenceDiagram
    participant Input as String / Bytes / Numeric / JSON / YAML
    participant Factory as Factory / Unmarshaler (Parse, Days, Unmarshal*)
    participant Dur as Duration Object (Nanos vs Seconds)
    participant Logic as Logic (Truncate, Range, Checks)
    participant Output as Export (String, time.Duration, Marshaled Data)

    Input->>Factory: Ingest raw data
    Factory->>Dur: Create typed object
    Dur->>Logic: Apply operations
    Logic->>Dur: Updated state
    Dur->>Output: Export to desired format
Data Representation
Feature duration.Duration big.Duration
Precision 1 Nanosecond 1 Second
Max Range ~290 Years ~292 Billion Years
Memory Size 8 Bytes (int64) 8 Bytes (int64)
Parsing Units ns, us, ms, s, m, h, d s, m, h, d
Compatibility Direct (Alias) Via Conversion (with overflow check)

Performance

The package is optimized for minimal overhead. Core arithmetic is as fast as standard int64 operations, and parsing/formatting are optimized to reduce allocations.

Benchmarks
Operation Benchmark Name Iterations Time/Op Memory Allocations
Formatting BenchmarkDuration_String > 4.6M 288.8 ns/op 16 B/op 2 allocs/op
Parsing BenchmarkParse > 5.5M 205.1 ns/op 0 B/op 0 allocs/op
Unit Factory BenchmarkDuration_Days > 1000M 0.3868 ns/op 0 B/op 0 allocs/op
Unit Factory BenchmarkDuration_Hours > 1000M 0.3710 ns/op 0 B/op 0 allocs/op
Unit Factory BenchmarkDuration_Minutes > 1000M 0.3709 ns/op 0 B/op 0 allocs/op
Unit Factory BenchmarkDuration_Seconds > 1000M 0.3564 ns/op 0 B/op 0 allocs/op
Truncation BenchmarkDuration_Truncate/Days > 1000M 0.3417 ns/op 0 B/op 0 allocs/op
Truncation BenchmarkDuration_Truncate/Hours > 1000M 0.3996 ns/op 0 B/op 0 allocs/op
Truncation BenchmarkDuration_Truncate/Minutes > 1000M 0.3845 ns/op 0 B/op 0 allocs/op
Truncation BenchmarkDuration_Truncate/Seconds > 1000M 0.3750 ns/op 0 B/op 0 allocs/op

Results from an Intel(R) Core(TM) i7-4700HQ CPU @ 2.40GHz.


Subpackages

big

The big sub-package handles durations on an astronomical scale. By defining the base unit as one second instead of one nanosecond, it extends the representable time range from 290 years to over 292 billion years.

Key Features:

  • API Parity: Methods like Parse, String, and Unmarshal behave consistently with the main package.
  • Serialization: Full support for JSON, YAML, TOML, CBOR, Text.
  • Advanced Logic: Includes PID-controlled range generation tailored for large-scale intervals.
  • Truncation: Methods to round to the nearest second, minute, hour, or day.

Documentation: big/README.md.


Use Cases

1. Adaptive Backoff Strategies

Using the PID controller to generate a smooth progression of retry intervals.

import (
	"fmt"
	
	"github.com/nabbar/golib/duration"
)

start := duration.Seconds(1)
target := duration.Minutes(10)

// Generate sequence using Proportional, Integral, Derivative rates
intervals := start.RangeTo(target, 0.1, 0.01, 0.05)

for _, wait := range intervals {
    fmt.Printf("Backoff: %s\n", wait)
    // time.Sleep(wait.Time())
}
2. Human-Readable Retention Policies

Easily define long-term storage retention in configuration files using "days".

import (
    "github.com/nabbar/golib/duration"
    "github.com/nabbar/golib/duration/big"
)

type RetentionPolicy struct {
    HotStorage  duration.Duration `json:"hot_storage"`  // e.g., "7d"
    ColdStorage big.Duration      `json:"cold_storage"` // e.g., "3650d"
}
3. Precise Log Truncation

Aligning event timestamps or durations to the nearest unit for grouping.

import (
	"fmt"
	
	"github.com/nabbar/golib/duration"
)

d, _ := duration.Parse("1h23m45s")
fmt.Println(d.TruncateHours())   // "1h0m0s"
fmt.Println(d.TruncateMinutes()) // "1h23m0s"

Quick Start

Installation
go get github.com/nabbar/golib/duration
Basic Implementation
package main

import (
    "fmt"
	
    "github.com/nabbar/golib/duration"
)

func main() {
    // 1. Parsing extended units
    d, _ := duration.Parse("2d12h")
    fmt.Println(d.String()) // "2d12h0m0s"

    // 2. Unit helper constructors
    d2 := duration.Days(1) + duration.Hours(6)
    
    // 3. Conditional checks
    if d2.IsDays() {
        fmt.Println("Duration is at least 1 day")
    }

    // 4. Stdlib conversion
    stdDur := d2.Time() // Returns time.Duration
}

Best Practices

✅ DO
  • Use duration.Duration for config structs: Enables automatic parsing of "d" units and multi-format serialization.
  • Use big.Duration for astronomical spans: Prevents silent overflow when dealing with centuries or millennia.
  • Check Parsing Errors: Extended units add complexity; always validate return errors from Parse.
  • Use .Time() for Interop: Explicitly convert when passing to time.Sleep or context.WithTimeout.
❌ DON'T
  • Don't ignore the ±290y limit: Standard durations (nanoseconds) will overflow. Switch to big package for long-term values.
  • Don't mix types in arithmetic: While duration.Duration is an alias of time.Duration, explicit conversion is often safer for clarity: d1 + duration.ParseDuration(stdDur).

API Reference

Global Factory Functions (Main)
Function Signature Description
Parse (s string) (Duration, error) Parses a duration string with support for ns, us, ms, s, m, h, d.
ParseByte (p []byte) (Duration, error) Parses a byte array representing a duration.
ParseDuration (d time.Duration) Duration Converts a standard time.Duration into a duration.Duration.
ParseFloat64 (f float64) Duration Converts a float64 (seconds) into a Duration.
ParseUint32 (i uint32) Duration Converts a uint32 (nanoseconds) into a Duration.
Nanoseconds (i int64) Duration Returns a Duration representing i nanoseconds.
Microseconds (i int64) Duration Returns a Duration representing i microseconds.
Milliseconds (i int64) Duration Returns a Duration representing i milliseconds.
Seconds (i int64) Duration Returns a Duration representing i seconds.
Minutes (i int64) Duration Returns a Duration representing i minutes.
Hours (i int64) Duration Returns a Duration representing i hours.
Days (i int64) Duration Returns a Duration representing i days (24h increments).
ViperDecoderHook () libmap.DecodeHookFuncType Returns a decode hook for go-viper/mapstructure.
Instance Methods (Main)
Method Result Description
String() string Returns a human-readable string (e.g., "1d2h3m4s").
Time() time.Duration Returns the underlying standard time.Duration.
Duration() time.Duration Alias for Time().
Days() int64 Returns total number of full days.
Hours() int64 Returns total number of full hours.
Minutes() int64 Returns total number of full minutes.
Seconds() int64 Returns total number of full seconds.
Milliseconds() int64 Returns total number of full milliseconds.
Microseconds() int64 Returns total number of full microseconds.
Nanoseconds() int64 Returns total number of full nanoseconds.
Float64() float64 Returns the raw nanosecond value as float64.
Int64() int64 Returns the raw nanosecond value as int64.
Uint64() uint64 Returns the absolute raw nanosecond value as uint64.
IsDays() bool True if duration >= 24 hours.
IsHours() bool True if duration >= 1 hour.
IsMinutes() bool True if duration >= 1 minute.
IsSeconds() bool True if duration >= 1 second.
IsMilliseconds() bool True if duration >= 1 millisecond.
IsMicroseconds() bool True if duration >= 1 microsecond.
IsNanoseconds() bool True if duration >= 1 nanosecond (non-zero).
TruncateDays() Duration Rounds down toward zero to the nearest day.
TruncateHours() Duration Rounds down toward zero to the nearest hour.
TruncateMinutes() Duration Rounds down toward zero to the nearest minute.
TruncateSeconds() Duration Rounds down toward zero to the nearest second.
TruncateMilliseconds() Duration Rounds down toward zero to the nearest millisecond.
TruncateMicroseconds() Duration Rounds down toward zero to the nearest microsecond.
RangeCtxTo() []Duration Generates PID-controlled sequence with context.
RangeTo() []Duration Generates PID-controlled sequence.
RangeDefTo() []Duration Generates PID-controlled sequence with default rates.
RangeCtxFrom() []Duration Generates reverse PID-controlled sequence with context.
RangeFrom() []Duration Generates reverse PID-controlled sequence.
RangeDefFrom() []Duration Generates reverse PID-controlled sequence with default rates.
MarshalJSON() ([]byte, error) Standard JSON marshaler.
UnmarshalJSON() error Standard JSON unmarshaler.
MarshalYAML() (interface{}, error) Standard YAML (v3) marshaler.
UnmarshalYAML() error Standard YAML (v3) unmarshaler.
MarshalTOML() ([]byte, error) Standard TOML marshaler.
UnmarshalTOML() error Standard TOML unmarshaler.
MarshalText() ([]byte, error) Standard Text marshaler.
UnmarshalText() error Standard Text unmarshaler.
MarshalCBOR() ([]byte, error) Standard CBOR marshaler.
UnmarshalCBOR() error Standard CBOR unmarshaler.

Contributing

Contributions are welcome! Please follow these guidelines:

  1. Code Quality

    • Follow Go best practices and idioms.
    • Maintain or improve code coverage (Target: >85%, currently 88.2%).
    • Pass all tests including race detector.
    • Use gofmt, golangci-lint and gosec.
  2. AI Usage Policy

    • AI must NEVER be used to generate package code or core functionality.
    • AI assistance is limited to:
      • Testing (writing and improving tests).
      • Debugging (troubleshooting and bug resolution).
      • Documentation (comments, README, TESTING.md).
    • All AI-assisted work must be reviewed and validated by humans.
  3. Testing

    • Add tests for new features.
    • Use Ginkgo v2 / Gomega for test framework.
    • Ensure zero race conditions.
    • Maintain coverage above 80%.
  4. Documentation

    • Update GoDoc comments for public APIs.
    • Add examples for new features.
    • Update README.md and TESTING.md if needed.
  5. Pull Request Process

    • Fork the repository.
    • Create a feature branch.
    • Write clear commit messages.
    • Ensure all tests pass.
    • Update documentation.
    • Submit PR with description of changes.

Resources

Package Documentation
Subpackage Documentation
External References

AI Transparency

In compliance with EU AI Act Article 50.4: AI assistance was used for testing, documentation, and bug resolution under human supervision. All core functionality is human-designed and validated.


License

MIT License - See LICENSE file for details.

Copyright (c) 2020-2026 Nicolas JUHEL

Documentation

Overview

Package duration provides an extended time.Duration type that supports parsing and formatting with "days" (d) as a unit. It also integrates seamlessly with various encoding formats (JSON, YAML, TOML, CBOR) and offers advanced features like PID-controlled range generation and precise truncation.

Overview

The standard Go time.Duration is limited to hours as its largest parsed unit. This package solves that by introducing a `Duration` type that behaves like time.Duration but adds support for days in string representations (e.g., "5d12h"). It also provides a robust set of helpers for conversion, comparison, and arithmetic operations.

Features

- **Extended Parsing:** Support for "d" (days) in duration strings (e.g., "1d2h30m"). - **Serialization:** Built-in support for Marshaling/Unmarshaling to/from JSON, YAML, TOML, CBOR, and Text. - **Helper Functions:** Easy constructors like Days(n), Hours(n), Minutes(n), etc. - **Truncation:** methods to truncate durations to days, hours, minutes, seconds, etc. - **Range Generation:** Generate sequences of durations using a PID controller for smooth transitions (useful for backoff strategies). - **Configuration Integration:** Includes a hook for Viper/Mapstructure decoding. - **Big Duration Support:** A sub-package `big` handles durations exceeding the standard int64 limit (±290 years).

Architecture & Data Flow

The core of the package is the `Duration` type, which is a simple type alias for `int64` (same as `time.Duration`). This ensures zero-cost conversion to standard `time.Duration` while allowing method attachment.

+----------------+       +---------------------+      +-------------------+
| Input String   | ----> | Parse() / Unmarshal | ---> | Duration (int64)  |
| "1d2h"         |       +---------------------+      |                   |
+----------------+                                    +---------+---------+
                                                                |
                                                                v
+----------------+       +---------------------+      +---------+---------+
| Output String  | <---- | String() / Marshal  | <----| Operations        |
| "1d2h0m0s"     |       +---------------------+      | - Truncate        |
+----------------+                                    | - Range           |
                                                      | - Convert         |
                                                      +-------------------+

Quick Start

package main

import (
    "fmt"
    "time"
    "github.com/nabbar/golib/duration"
)

func main() {
    // 1. Parsing a duration string with days
    d, err := duration.Parse("2d4h")
    if err != nil {
        panic(err)
    }
    fmt.Println("Parsed:", d) // Output: 2d4h0m0s

    // 2. Creating a duration from integers
    d2 := duration.Days(1) + duration.Hours(12)
    fmt.Println("Constructed:", d2) // Output: 1d12h0m0s

    // 3. Converting to standard time.Duration
    stdDuration := d.Time()
    fmt.Printf("Standard: %v\n", stdDuration) // Output: 52h0m0s

    // 4. Truncating
    fmt.Println("Truncated to days:", d.TruncateDays()) // Output: 2d

    // 5. Checking units
    if d.IsDays() {
        fmt.Println("Duration is at least one day")
    }
}

Use Cases

  1. Configuration Files: Allow users to specify long timeouts or intervals in a human-readable format in config files (JSON, YAML, etc.). Example: `timeout: "7d"` is clearer than `timeout: "168h"`.

  2. Exponential Backoff / Retries: Use `RangeTo` or `RangeCtxTo` to generate a sequence of durations for retry attempts that increase over time using a PID controller logic.

  3. API Responses: Return duration fields in JSON APIs that are easy for humans to read and for clients to parse.

  4. Scheduling: Calculate precise schedules involving days, where standard `time.Duration` logic might be cumbersome due to the lack of a 'day' unit.

Package duration provides an extended duration type with days support and multiple encoding formats.

This package wraps time.Duration and extends it with:

  • Days notation in parsing and formatting (e.g., "5d23h15m13s")
  • Multiple encoding support (JSON, YAML, TOML, CBOR, text)
  • Viper configuration integration
  • Arithmetic operations and helper functions
  • Truncation and rounding to various time units
  • PID controller-based range generation

The package is limited to time.Duration's range (±290 years). For larger durations, use the big sub-package.

Example usage:

import "github.com/nabbar/golib/duration"

// Parse duration with days
d, _ := duration.Parse("5d23h15m13s")
fmt.Println(d.String())  // Output: 5d23h15m13s

// Create durations
timeout := duration.Days(2) + duration.Hours(3)

// Convert to time.Duration
std := timeout.Time()

// Use in JSON
type Config struct {
    Timeout duration.Duration `json:"timeout"`
}
Example (Configuration)

Example_configuration demonstrates how to use duration in a configuration struct with JSON.

package main

import (
	"encoding/json"
	"fmt"
	"log"

	"github.com/nabbar/golib/duration"
)

func main() {
	// Imagine this JSON is from a config file.
	configJSON := `{"timeout": "2d12h"}`

	var config struct {
		Timeout duration.Duration `json:"timeout"`
	}

	if err := json.Unmarshal([]byte(configJSON), &config); err != nil {
		log.Fatalf("Failed to unmarshal config: %v", err)
	}

	fmt.Printf("Timeout is: %s\n", config.Timeout)
	fmt.Printf("In hours: %d hours", config.Timeout.Hours())
}
Output:
Timeout is: 2d12h0m0s
In hours: 60 hours
Example (RetryStrategy)

Example_retryStrategy demonstrates generating a series of durations for a retry mechanism.

package main

import (
	"fmt"

	"github.com/nabbar/golib/duration"
)

func main() {
	start := duration.Seconds(1)
	end := duration.Minutes(1)

	// Generate a backoff sequence.
	// Note: The PID controller parameters here are for demonstration.
	backoffSequence := start.RangeTo(end, 0.5, 0.1, 0.1)

	fmt.Println("Retry intervals:")
	for i, d := range backoffSequence {
		fmt.Printf("Attempt %d: wait %s\n", i+1, d.String())
	}
}

Index

Examples

Constants

This section is empty.

Variables

View Source
var DefaultRateDerivative float64 = 0.05

DefaultRateDerivative is the default derivative rate for the PID controller used in range generation.

View Source
var DefaultRateIntegral float64 = 0.01

DefaultRateIntegral is the default integral rate for the PID controller used in range generation.

View Source
var DefaultRateProportional float64 = 0.1

DefaultRateProportional is the default proportional rate for the PID controller used in range generation.

Functions

func ViperDecoderHook

func ViperDecoderHook() libmap.DecodeHookFuncType

ViperDecoderHook is a libmap.DecodeHookFuncType that is used to decode strings into libdur.Duration values. It takes a reflect.Type, a reflect.Type, and an interface{} as parameters, and returns an interface{} and an error. If the data type is not a string, it returns the data as is and a nil error. If the target type is not a libdur.Duration, it returns the data as is and a nil error. Otherwise, it formats/decodes/parses the data and returns the new value.

Types

type Duration

type Duration time.Duration

func Days

func Days(i int64) Duration

Days returns a Duration representing i days.

The returned Duration is a new Duration and does not modify the underlying time.Duration.

The function panics if i is larger than math.MaxInt64 or smaller than -math.MaxInt64.

The duration is calculated by multiplying i by 24 hours (1 day).

Example

ExampleDays demonstrates creating a duration using the Days helper function.

package main

import (
	"fmt"

	"github.com/nabbar/golib/duration"
)

func main() {
	// Create a duration of 2 days.
	d := duration.Days(2)
	fmt.Println(d)
}
Output:
2d

func Hours

func Hours(i int64) Duration

Hours returns a Duration representing i hours.

The returned Duration is a new Duration and does not modify the underlying time.Duration.

The function panics if i is larger than math.MaxInt64 or smaller than -math.MaxInt64.

Example

ExampleHours demonstrates creating a duration using the Hours helper function.

package main

import (
	"fmt"

	"github.com/nabbar/golib/duration"
)

func main() {
	// Create a duration of 36 hours.
	d := duration.Hours(36)
	fmt.Println(d)
}
Output:
1d12h0m0s

func Microseconds added in v1.21.0

func Microseconds(i int64) Duration

Microseconds returns a Duration representing i microseconds.

The returned Duration is a new Duration and does not modify the underlying time.Duration.

func Milliseconds added in v1.21.0

func Milliseconds(i int64) Duration

Milliseconds returns a Duration representing i milliseconds.

The returned Duration is a new Duration and does not modify the underlying time.Duration.

func Minutes

func Minutes(i int64) Duration

Minutes returns a Duration representing i minutes.

The returned Duration is a new Duration and does not modify the underlying time.Duration.

The function panics if i is larger than math.MaxInt64 or smaller than -math.MaxInt64.

func Nanoseconds added in v1.21.0

func Nanoseconds(i int64) Duration

Nanoseconds returns a Duration representing i nanoseconds.

The returned Duration is a new Duration and does not modify the underlying time.Duration.

func Parse

func Parse(s string) (Duration, error)

Parse parses a string representing a duration and returns a Duration object. It will return an error if the string is invalid.

The string must be in the format "XhYmZs" where X, Y, and Z are integers representing the number of hours, minutes, and seconds respectively. The letters "h", "m", and "s" are optional and can be omitted.

For example, "2h" represents 2 hours, "3m" represents 3 minutes, and "4s" represents 4 seconds.

The function is case insensitive.

Example

ExampleParse demonstrates how to parse a duration string, including days.

package main

import (
	"fmt"
	"log"

	"github.com/nabbar/golib/duration"
)

func main() {
	// Parsing a string with days, hours, minutes, and seconds.
	d, err := duration.Parse("3d6h15m30s")
	if err != nil {
		log.Fatalf("Failed to parse duration: %v", err)
	}
	fmt.Println(d)
}
Output:
3d6h15m30s

func ParseByte

func ParseByte(p []byte) (Duration, error)

ParseByte parses a byte array representing a duration and returns a Duration object. It will return an error if the byte array is invalid.

The byte array must be in the format "XhYmZs" where X, Y, and Z are integers representing the number of hours, minutes, and seconds respectively. The letters "h", "m", and "s" are optional and can be omitted.

For example, "2h" represents 2 hours, "3m" represents 3 minutes, and "4s" represents 4 seconds.

The function is case insensitive.

func ParseDuration

func ParseDuration(d time.Duration) Duration

ParseDuration returns a Duration representing d time.Duration.

The returned Duration is a new Duration and does not modify the underlying time.Duration.

The function is a no-op and simply returns the input time.Duration as a Duration. It can be used to convert a time.Duration to a Duration without modifying the underlying time.Duration.

Example:

d := 5*time.Hour
dd := ParseDuration(d)
fmt.Println(dd) // 5h0m0s

func ParseFloat64 added in v1.17.0

func ParseFloat64(f float64) Duration

ParseFloat64 returns a Duration representing f seconds.

If f is larger than math.MaxInt64, ParseFloat64 returns a Duration representing math.MaxInt64 seconds. If f is smaller than -math.MaxInt64, ParseFloat64 returns a Duration representing -math.MaxInt64 seconds.

Otherwise, ParseFloat64 returns a Duration representing the closest integer to f seconds. The returned Duration is a new Duration and does not modify the underlying float64.

func ParseUint32 added in v1.19.0

func ParseUint32(i uint32) Duration

ParseUint32 returns a Duration representing i nanoseconds. Since Duration is an int64 representing nanoseconds, a uint32 value will always fit within the Duration type without overflow.

func Seconds

func Seconds(i int64) Duration

Seconds returns a Duration representing i seconds.

The returned Duration is a new Duration and does not modify the underlying time.Duration.

The function panics if i is larger than math.MaxInt64 or smaller than -math.MaxInt64.

func (Duration) Days

func (d Duration) Days() int64

Days returns the number of days in the duration. The number of days is calculated by dividing the total number of hours by 24 and rounding down to the nearest integer. If the total number of hours is greater than the maximum value of int64, the maximum value of int64 is returned.

func (Duration) Duration added in v1.21.0

func (d Duration) Duration() time.Duration

Duration returns the time.Duration value. It is equivalent to d.Time().

func (Duration) Float64 added in v1.17.0

func (d Duration) Float64() float64

Float64 returns the underlying int64 value of the duration as a float64.

This can be useful when working with libraries or functions that expect a float64 value, as it allows for easy conversion between the duration package and the required type.

Example:

d := libdur.ParseDuration("1h30m") f := d.Float64() fmt.Println(f) // Output: 5400.0

func (Duration) Hours added in v1.21.0

func (d Duration) Hours() int64

Hours returns the number of hours in the duration. It calculates the total hours from the underlying time.Duration, rounds down to the nearest integer, and converts it to int64. This provides the total duration expressed in full hours.

func (Duration) Int64 added in v1.21.0

func (d Duration) Int64() int64

Int64 returns the duration as a signed 64-bit integer. It simply casts the underlying Duration (which is int64) to int64.

func (Duration) IsDays added in v1.21.0

func (d Duration) IsDays() bool

IsDays checks if the duration is greater than or equal to one day. It returns true if the duration is at least 24 hours.

func (Duration) IsHours added in v1.21.0

func (d Duration) IsHours() bool

IsHours checks if the duration is greater than or equal to one hour. It returns true if the duration is at least 60 minutes.

func (Duration) IsMicroseconds added in v1.21.0

func (d Duration) IsMicroseconds() bool

IsMicroseconds checks if the duration is greater than or equal to one microsecond. It returns true if the duration is at least 1000 nanoseconds.

func (Duration) IsMilliseconds added in v1.21.0

func (d Duration) IsMilliseconds() bool

IsMilliseconds checks if the duration is greater than or equal to one millisecond. It returns true if the duration is at least 1000 microseconds.

func (Duration) IsMinutes added in v1.21.0

func (d Duration) IsMinutes() bool

IsMinutes checks if the duration is greater than or equal to one minute. It returns true if the duration is at least 60 seconds.

Example

ExampleDuration_IsMinutes checks if a duration is at least one minute long.

package main

import (
	"fmt"

	"github.com/nabbar/golib/duration"
)

func main() {
	d1 := duration.Seconds(90)
	d2 := duration.Seconds(30)
	fmt.Printf("90s is at least a minute: %t\n", d1.IsMinutes())
	fmt.Printf("30s is at least a minute: %t\n", d2.IsMinutes())
}
Output:
90s is at least a minute: true
30s is at least a minute: false

func (Duration) IsNanoseconds added in v1.21.0

func (d Duration) IsNanoseconds() bool

IsNanoseconds checks if the duration is greater than or equal to one nanosecond. This is effectively checking if the duration is non-zero (assuming positive duration), as 1ns is the smallest unit.

func (Duration) IsSeconds added in v1.21.0

func (d Duration) IsSeconds() bool

IsSeconds checks if the duration is greater than or equal to one second. It returns true if the duration is at least 1000 milliseconds.

func (Duration) MarshalCBOR

func (d Duration) MarshalCBOR() ([]byte, error)

MarshalCBOR returns the CBOR encoding of the duration.

The CBOR encoding is simply the CBOR encoding of the string representation of the duration.

Example:

d, _ := duration.Parse("1h2m3s") b, err := d.MarshalCBOR()

if err != nil {
    panic(err)
}

fmt.Println(string(b)) // Output: CBOR encoding of "1h2m3s"

func (Duration) MarshalJSON

func (d Duration) MarshalJSON() ([]byte, error)

MarshalJSON returns the JSON encoding of the duration.

The JSON encoding is simply the string representation of the duration wrapped in double quotes.

Example:

d, _ := duration.Parse("1h2m3s") b, err := d.MarshalJSON()

if err != nil {
    panic(err)
}

fmt.Println(string(b)) // Output: "1h2m3s"

func (Duration) MarshalTOML

func (d Duration) MarshalTOML() ([]byte, error)

MarshalTOML returns the TOML encoding of the duration. It returns the JSON encoding of the string representation of the duration.

func (Duration) MarshalText

func (d Duration) MarshalText() ([]byte, error)

MarshalText returns the text encoding of the duration.

The text encoding is simply the string representation of the duration.

Example:

d, _ := duration.Parse("1h2m3s") b, err := d.MarshalText()

if err != nil {
    panic(err)
}

fmt.Println(string(b)) // Output: "1h2m3s"

func (Duration) MarshalYAML

func (d Duration) MarshalYAML() (interface{}, error)

MarshalYAML returns the YAML encoding of the duration.

The YAML encoding is simply the string representation of the duration.

Example:

d, _ := duration.Parse("1h2m3s") y, err := d.MarshalYAML()

if err != nil {
    panic(err)
}

fmt.Println(y) // Output: "1h2m3s"

func (Duration) Microseconds added in v1.21.0

func (d Duration) Microseconds() int64

Microseconds returns the duration as an integer microsecond count. It delegates to the underlying time.Duration.Microseconds() method.

func (Duration) Milliseconds added in v1.21.0

func (d Duration) Milliseconds() int64

Milliseconds returns the duration as an integer millisecond count. It delegates to the underlying time.Duration.Milliseconds() method.

func (Duration) Minutes added in v1.21.0

func (d Duration) Minutes() int64

Minutes returns the number of minutes in the duration. It calculates the total minutes from the underlying time.Duration, rounds down to the nearest integer, and converts it to int64. This provides the total duration expressed in full minutes.

func (Duration) Nanoseconds added in v1.21.0

func (d Duration) Nanoseconds() int64

Nanoseconds returns the duration as an integer nanosecond count. It delegates to the underlying time.Duration.Nanoseconds() method.

func (Duration) RangeCtxFrom added in v1.19.0

func (d Duration) RangeCtxFrom(ctx context.Context, dur Duration, rateP, rateI, rateD float64) []Duration

RangeCtxFrom generates a slice of durations from 'dur' up to the receiver 'd'. It is the reverse of RangeCtxTo, using the same PID-controlled spacing logic.

The context 'ctx' can be used to cancel the generation process. The 'rateP', 'rateI', and 'rateD' parameters configure the PID controller.

The resulting slice is guaranteed to start with 'dur' and end with 'd'.

func (Duration) RangeCtxTo added in v1.19.0

func (d Duration) RangeCtxTo(ctx context.Context, dur Duration, rateP, rateI, rateD float64) []Duration

RangeCtxTo generates a slice of durations from the receiver 'd' to the 'dur' parameter. The spacing between durations is determined by a PID controller, allowing for non-linear intervals. This is useful for scenarios like exponential backoff or other adaptive timing strategies.

The context 'ctx' can be used to cancel the generation process. The 'rateP', 'rateI', and 'rateD' parameters configure the Proportional, Integral, and Derivative components of the PID controller, respectively.

The resulting slice is guaranteed to start with 'd' and end with 'dur'.

func (Duration) RangeDefFrom added in v1.17.0

func (d Duration) RangeDefFrom(dur Duration) []Duration

RangeDefFrom is a convenience wrapper for RangeFrom that uses the default PID controller rates. It generates a slice of durations from 'dur' to the receiver 'd'.

func (Duration) RangeDefTo added in v1.17.0

func (d Duration) RangeDefTo(dur Duration) []Duration

RangeDefTo is a convenience wrapper for RangeTo that uses the default PID controller rates (DefaultRateProportional, DefaultRateIntegral, DefaultRateDerivative). It generates a slice of durations from the receiver 'd' to 'dur'.

func (Duration) RangeFrom added in v1.17.0

func (d Duration) RangeFrom(dur Duration, rateP, rateI, rateD float64) []Duration

RangeFrom is a convenience wrapper for RangeCtxFrom that uses a background context with a 5-second timeout. It generates a slice of durations from 'dur' to the receiver 'd' using the specified PID controller rates.

func (Duration) RangeTo added in v1.17.0

func (d Duration) RangeTo(dur Duration, rateP, rateI, rateD float64) []Duration

RangeTo is a convenience wrapper for RangeCtxTo that uses a background context with a 5-second timeout. It generates a slice of durations from the receiver 'd' to 'dur' using the specified PID controller rates.

func (Duration) Seconds added in v1.21.0

func (d Duration) Seconds() int64

Seconds returns the number of seconds in the duration. It calculates the total seconds from the underlying time.Duration, rounds down to the nearest integer, and converts it to int64. This provides the total duration expressed in full seconds.

func (Duration) String

func (d Duration) String() string

String returns a string representation of the duration. The string is in the format "NdNhNmNs" where N is a number. The days are omitted if n is 0 or negative. The hours, minutes, and seconds are omitted if they are 0.

Example:

d := libdur.ParseDuration("1d2h3m4s") fmt.Println(d.String()) // Output: 1d2h3m4s

func (Duration) Time

func (d Duration) Time() time.Duration

Time returns a time.Duration representation of the duration. It is a simple wrapper around the conversion of the underlying int64 value to a time.Duration.

Time is useful when working with the time package, as it allows for easy conversion between the duration package and the time package.

Example:

d := libdur.ParseDuration("1h30m") td := d.Time() fmt.Println(td) // Output: 1h30m0s

Example

ExampleDuration_Time shows how to convert a custom Duration back to a standard time.Duration.

package main

import (
	"fmt"

	"github.com/nabbar/golib/duration"
)

func main() {
	d := duration.Days(1) + duration.Hours(12)
	stdDur := d.Time()
	fmt.Printf("Standard time.Duration: %v", stdDur)
}
Output:
Standard time.Duration: 36h0m0s

func (Duration) TruncateDays added in v1.15.3

func (d Duration) TruncateDays() Duration

TruncateDays returns the result of rounding d toward zero to a multiple of a day. If d is an exact multiple of a day, it returns d unchanged. Otherwise, it returns the duration d rounded to the nearest multiple of a day. The rounding mode is to round half even up (i.e. if d is halfway between two multiples of a day, it rounds up to the next multiple of a day. For example, TruncateDays(ParseDuration("1.5d")) returns ParseDuration("2d").

Example

ExampleDuration_TruncateDays demonstrates truncating a duration to the nearest whole day.

package main

import (
	"fmt"

	"github.com/nabbar/golib/duration"
)

func main() {
	d, _ := duration.Parse("3d18h")
	trunc := d.TruncateDays()
	fmt.Println(trunc)
}
Output:
3d

func (Duration) TruncateHours added in v1.15.3

func (d Duration) TruncateHours() Duration

TruncateHours returns the result of rounding d toward zero to a multiple of an hour. If d is an exact multiple of an hour, it returns d unchanged. Otherwise, it returns the duration d rounded to the nearest multiple of an hour. The rounding mode is to round half even up (i.e. if d is halfway between two multiples of an hour, it rounds up to the next multiple of an hour. For example, TruncateHours(ParseDuration("1.5h")) returns ParseDuration("2h").

func (Duration) TruncateMicroseconds added in v1.15.3

func (d Duration) TruncateMicroseconds() Duration

TruncateMicroseconds returns the result of rounding d toward zero to a multiple of a microsecond. If d is an exact multiple of a microsecond, it returns d unchanged. Otherwise, it returns the duration d rounded to the nearest multiple of a microsecond. The rounding mode is to round half even up (i.e. if d is halfway between two multiples of a microsecond, it rounds up to the next multiple of a microsecond). For example, TruncateMicroseconds(ParseDuration("1.5µs")) returns ParseDuration("2µs").

func (Duration) TruncateMilliseconds added in v1.15.3

func (d Duration) TruncateMilliseconds() Duration

TruncateMilliseconds returns the result of rounding d toward zero to a multiple of a millisecond. If d is an exact multiple of a millisecond, it returns d unchanged. Otherwise, it returns the duration d rounded to the nearest multiple of a millisecond. The rounding mode is to round half even up (i.e. if d is halfway between two multiples of a millisecond, it rounds up to the next multiple of a millisecond. For example, TruncateMilliseconds(ParseDuration("1.5ms")) returns ParseDuration("2ms").

func (Duration) TruncateMinutes added in v1.15.3

func (d Duration) TruncateMinutes() Duration

TruncateMinutes returns the result of rounding d toward zero to a multiple of a minute. If d is an exact multiple of a minute, it returns d unchanged. Otherwise, it returns the duration d rounded to the nearest multiple of a minute. The rounding mode is to round half even up (i.e. if d is halfway between two multiples of a minute, it rounds up to the next multiple of a minute. For example, TruncateMinutes(ParseDuration("1.5m")) returns ParseDuration("2m").

func (Duration) TruncateSeconds added in v1.15.3

func (d Duration) TruncateSeconds() Duration

TruncateSeconds returns the result of rounding d toward zero to a multiple of a second. If d is an exact multiple of a second, it returns d unchanged. Otherwise, it returns the duration d rounded to the nearest multiple of a second. The rounding mode is to round half even up (i.e. if d is halfway between two multiples of a second, it rounds up to the next multiple of a second. For example, TruncateSeconds(ParseDuration("1.5s")) returns ParseDuration("2s").

func (Duration) Uint64 added in v1.21.0

func (d Duration) Uint64() uint64

Uint64 returns the duration as an unsigned 64-bit integer. If the duration is negative, it returns the absolute value cast to uint64. Otherwise, it returns the duration cast to uint64.

func (*Duration) UnmarshalCBOR

func (d *Duration) UnmarshalCBOR(bytes []byte) error

UnmarshalCBOR parses the CBOR-encoded duration and stores the result in the receiver.

The CBOR encoding is expected to be the CBOR encoding of the string representation of the duration.

Example:

d := &duration.Duration{} b := []byte{CBOR encoding of "1h2m3s"}

if err := d.UnmarshalCBOR(b); err != nil {
    panic(err)
}

fmt.Println(d.String()) // Output: "1h2m3s"

func (*Duration) UnmarshalJSON

func (d *Duration) UnmarshalJSON(bytes []byte) error

UnmarshalJSON parses the JSON-encoded duration and stores the result in the receiver.

The JSON encoding is expected to be a string representation of the duration wrapped in double quotes.

Example:

b := []byte(`"1h2m3s"`) d := &duration.Duration{}

if err := d.UnmarshalJSON(b); err != nil {
    panic(err)
}

fmt.Println(d.String()) // Output: "1h2m3s"

func (*Duration) UnmarshalTOML

func (d *Duration) UnmarshalTOML(i interface{}) error

UnmarshalTOML parses the TOML-encoded duration and stores the result in the receiver.

The TOML encoding is expected to be a string representation of the duration.

func (*Duration) UnmarshalText

func (d *Duration) UnmarshalText(bytes []byte) error

UnmarshalText parses the text-encoded duration and stores the result in the receiver.

The text encoding is expected to be a string representation of the duration.

Example:

d := &duration.Duration{} b := []byte("1h2m3s")

if err := d.UnmarshalText(b); err != nil {
    panic(err)
}

fmt.Println(d.String()) // Output: "1h2m3s"

func (*Duration) UnmarshalYAML

func (d *Duration) UnmarshalYAML(value *yaml.Node) error

UnmarshalYAML parses the YAML-encoded duration and stores the result in the receiver.

The YAML encoding is expected to be a string representation of the duration.

Example:

y := &yaml.Node{Value: "1h2m3s"} d := &duration.Duration{}

if err := d.UnmarshalYAML(y); err != nil {
    panic(err)
}

fmt.Println(d.String()) // Output: "1h2m3s"

Directories

Path Synopsis
Package big provides a custom duration type that extends the standard `time.Duration` to support much larger time scales, up to billions of years.
Package big provides a custom duration type that extends the standard `time.Duration` to support much larger time scales, up to billions of years.

Jump to

Keyboard shortcuts

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