Fluent builder system for creating durations and periods with natural language syntax and arithmetic operations. The duration building system distinguishes between precise time-based durations and calendar-based periods.
Core builder class for creating and manipulating durations with fluent syntax.
/**
* Builder for creating durations and periods with fluid syntax
* @param underlying The underlying Period object
*/
class DurationBuilder(val underlying: Period) extends AnyVal {
// Builder arithmetic - maintains DurationBuilder type
def +(that: DurationBuilder): DurationBuilder
def -(that: DurationBuilder): DurationBuilder
// Relative time operations
def ago(): DateTime
def later(): DateTime
def from(dt: DateTime): DateTime
def before(dt: DateTime): DateTime
// Conversion methods
def standardDuration: Duration
def toDuration: Duration
def toPeriod: Period
// Period arithmetic - returns Period
def -(period: ReadablePeriod): Period
def +(period: ReadablePeriod): Period
// Time value extraction
def millis: Long
def seconds: Long
// Duration arithmetic - returns Duration
def -(amount: Long): Duration
def -(amount: ReadableDuration): Duration
def +(amount: Long): Duration
def +(amount: ReadableDuration): Duration
}DurationBuilder Object Factory:
object DurationBuilder {
def apply(underlying: Period): DurationBuilder
}Usage Examples:
import com.github.nscala_time.time.Imports._
// Create duration builders
val duration1 = 2.hours + 30.minutes
val duration2 = 1.hour + 45.minutes
// Builder arithmetic
val combined = duration1 + duration2 // 4 hours 15 minutes
val difference = duration1 - duration2 // 45 minutes
// Relative time operations
val pastTime = duration1.ago() // 2.5 hours ago
val futureTime = duration1.later() // 2.5 hours from now
val fromSpecific = duration1.from(DateTime.parse("2023-01-01T12:00:00"))
// Conversion to different types
val asDuration = duration1.toDuration
val asPeriod = duration1.toPeriod
val millisValue = duration1.millis
val secondsValue = duration1.secondsExtension methods for integers to create duration builders and periods using natural language syntax.
/**
* Adds time unit methods to integers for creating durations and periods
* @param underlying The underlying integer value
*/
implicit class RichInt(val underlying: Int) extends AnyVal {
// Precise time units - return DurationBuilder (can be used as Duration or Period)
def millis: DurationBuilder
def seconds: DurationBuilder
def minutes: DurationBuilder
def hours: DurationBuilder
// Calendar-based units - return Period (variable length based on calendar)
def days: Period
def weeks: Period
def months: Period
def years: Period
// Singular forms for natural language syntax
def milli: DurationBuilder
def second: DurationBuilder
def minute: DurationBuilder
def hour: DurationBuilder
def day: Period
def week: Period
def month: Period
def year: Period
// Period multiplication
def *(period: Period): Period
}Usage Examples:
import com.github.nscala_time.time.Imports._
// Precise duration building (suitable for durations)
val preciseDuration = 2.hours + 30.minutes + 45.seconds
val inMillis = preciseDuration.millis // Get total milliseconds
// Calendar-based periods (variable length)
val calendarPeriod = 1.month + 2.weeks + 3.days
val multipliedPeriod = 5 * 1.day // 5 days
// Mixed usage - builders auto-convert when needed
val now = DateTime.now()
val future1 = now + 2.hours // Add precise duration
val future2 = now + 1.month // Add calendar period
val future3 = now + (1.day + 2.hours) // Mixed period and duration
// Singular forms for readability
val singleUnits = 1.hour + 1.minute + 1.second
val singlePeriods = 1.year + 1.month + 1.dayExtension methods for long values providing duration conversion and arithmetic operations.
/**
* Adds duration conversion and arithmetic methods to long values
* @param underlying The underlying long value (treated as milliseconds)
*/
implicit class RichLong(val underlying: Long) extends AnyVal {
// Conversion methods
def toDateTime: DateTime
def toDuration: Duration
// Duration arithmetic operations
def -(duration: Duration): Duration
def +(duration: Duration): Duration
def *(duration: Duration): Duration
}Usage Examples:
import com.github.nscala_time.time.Imports._
// Convert milliseconds to DateTime (Unix timestamp)
val timestamp = 1672531200000L // Jan 1, 2023 00:00:00 UTC
val dateTime = timestamp.toDateTime
// Convert milliseconds to Duration
val durationInMillis = 3600000L // 1 hour in milliseconds
val duration = durationInMillis.toDuration
// Duration arithmetic with Long values
val baseDuration = Duration.standardHours(2)
val extended = 1800000L + baseDuration // Add 30 minutes (in millis) to 2 hours
val reduced = 5400000L - baseDuration // Subtract 2 hours from 90 minutes
val multiplied = 2L * baseDuration // Multiply duration by 2
// Working with timestamps and durations
val currentTimeMillis = System.currentTimeMillis()
val currentTime = currentTimeMillis.toDateTime
val oneHourLater = currentTime + Duration.standardHours(1)Implicit conversions for seamless integration with Joda Time types.
/**
* Implicit conversions for DurationBuilder integration
*/
trait BuilderImplicits {
/**
* Automatically convert DurationBuilder to Period when Period is expected
*/
implicit def forcePeriod(builder: DurationBuilder): Period
/**
* Automatically convert DurationBuilder to Duration when Duration is expected
*/
implicit def forceDuration(builder: DurationBuilder): Duration
}Usage Examples:
import com.github.nscala_time.time.Imports._
// Implicit conversion in action - no explicit conversion needed
val period: Period = 2.hours + 30.minutes // Automatically converts to Period
val duration: Duration = 2.hours + 30.minutes // Automatically converts to Duration
// Use in method calls expecting specific types
def takePeriod(p: Period): String = p.toString
def takeDuration(d: Duration): Long = d.getMillis
val builder = 1.hour + 30.minutes
val periodResult = takePeriod(builder) // Implicit conversion to Period
val durationResult = takeDuration(builder) // Implicit conversion to DurationDuration: Represents a precise amount of time measured in milliseconds. Always consistent regardless of when it's applied.
val duration = 24.hours.toDuration
// Always exactly 86,400,000 millisecondsPeriod: Represents a calendar-based amount of time that can vary based on when it's applied (due to daylight saving time, leap years, different month lengths, etc.).
val period = 1.day
// Could be 23, 24, or 25 hours depending on DST transitionsBest Practices: