Hone logo
Hone
Problems

Go Time Duration Calculator

This challenge involves creating a Go program that can parse and represent durations of time, similar to Go's built-in time.Duration type. Understanding how to represent and manipulate time intervals is fundamental for scheduling, logging, and many other time-based operations in software.

Problem Description

Your task is to implement a custom type that can represent a duration of time and provide functionalities to:

  1. Parse: Accept a string representation of a duration (e.g., "1h30m", "45s", "2h15m30s") and convert it into your custom duration representation.
  2. Convert: Allow conversion of the duration into different units (seconds, minutes, hours, milliseconds, nanoseconds).
  3. Add/Subtract: Support adding and subtracting durations.

You should aim to mimic the core functionality of Go's time.Duration without directly using it for the internal representation or parsing.

Key Requirements

  • Create a custom type (e.g., MyDuration) to hold the duration. Internally, this type should represent the duration in a consistent base unit (e.g., nanoseconds).
  • Implement a ParseDuration function that takes a string and returns a MyDuration and an error. The parsing should handle common units like ns, µs (or us), ms, s, m, h.
  • Implement methods on MyDuration to:
    • Seconds(): Return the duration in seconds (as float64).
    • Minutes(): Return the duration in minutes (as float64).
    • Hours(): Return the duration in hours (as float64).
    • Milliseconds(): Return the duration in milliseconds (as float64).
    • Nanoseconds(): Return the duration in nanoseconds (as int64).
  • Implement methods or operators to add and subtract MyDuration values. You can choose to implement methods like Add(other MyDuration) and Subtract(other MyDuration), or if you're comfortable, explore operator overloading patterns (though Go doesn't have direct operator overloading for custom types). For this challenge, method-based addition/subtraction is sufficient.
  • Handle potential parsing errors gracefully.

Expected Behavior

The ParseDuration function should correctly interpret various combinations of units and numbers. The conversion methods should provide accurate floating-point representations of the duration in the requested units. Addition and subtraction should produce a new MyDuration representing the combined or difference in time.

Edge Cases to Consider

  • Zero duration: Parsing an empty string or a string representing zero time (e.g., "0s").
  • Negative durations: While time.Duration supports negative values, for this challenge, you can assume positive durations for parsing, but addition/subtraction might result in negative effective durations.
  • Invalid formats: Strings that do not conform to the expected duration format.
  • Extremely large/small durations: Consider the limits of int64 for nanoseconds.
  • Mixed units: Durations like "1h30m15s".

Examples

Example 1:

Input string: "1h30m"
Parsed MyDuration: Represents 1 hour and 30 minutes.
Output (in seconds): 5400.0
Output (in minutes): 90.0
Output (in hours): 1.5
Output (in milliseconds): 5400000.0
Output (in nanoseconds): 5400000000000

Explanation: "1h30m" is parsed into 1 hour and 30 minutes. This is equivalent to 1.5 hours, 90 minutes, 5400 seconds, or 5.4 billion nanoseconds.

Example 2:

Input string: "45s150ms"
Parsed MyDuration: Represents 45 seconds and 150 milliseconds.
Output (in seconds): 45.15
Output (in minutes): 0.7525
Output (in hours): 0.012541666666666667
Output (in milliseconds): 45150.0
Output (in nanoseconds): 45150000000

Explanation: "45s150ms" is parsed into 45 seconds and 150 milliseconds. This is 45.15 seconds, or 45150 milliseconds.

Example 3: (Addition)

Duration A: "10m"
Duration B: "5m30s"

Result of A.Add(B):
Parsed MyDuration: Represents 15 minutes and 30 seconds.
Output (in seconds): 930.0

Explanation: Adding 10 minutes to 5 minutes and 30 seconds results in a total duration of 15 minutes and 30 seconds.

Example 4: (Invalid Input)

Input string: "1 hour and 30 minutes"
Parsed MyDuration: Zero value
Error: "time: invalid duration string '1 hour and 30 minutes'"

Explanation: The input string does not follow the expected format for duration parsing.

Constraints

  • The internal representation of MyDuration must be an int64 representing nanoseconds.
  • Parsing should handle integer and floating-point numbers for durations.
  • The parsing logic should be robust enough to handle common whitespace variations around units (e.g., "1h 30m" is acceptable).
  • Conversion methods (Seconds, Minutes, etc.) should return float64 for precision, except for Nanoseconds() which should return int64.
  • Addition and subtraction methods should return a new MyDuration instance, not modify the existing ones.
  • The parsing function should aim to support standard Go duration units: ns, us, ms, s, m, h.

Notes

  • Think about how to break down the input string into numerical values and their corresponding units. Regular expressions can be helpful, but manual string manipulation is also a viable approach.
  • Be mindful of unit conversions. For example, 1 hour is 3600 seconds, 1 second is 1,000,000,000 nanoseconds.
  • Consider using a helper function for parsing individual number-unit pairs from the input string.
  • For addition and subtraction, ensure you're performing operations on the base unit (nanoseconds) and then converting back if necessary.
Loading editor...
go