Rich operations on DateTime, LocalDate, LocalTime, and LocalDateTime providing fluent property access, arithmetic operations, and enhanced functionality beyond the standard Joda Time API.
Enhanced DateTime with arithmetic operations, property access, and fluent manipulation.
/**
* Rich DateTime operations with arithmetic and property access
*/
implicit class RichDateTime(underlying: DateTime) {
// Arithmetic operations
def +(duration: Long): DateTime
def -(duration: Long): DateTime
def +(duration: ReadableDuration): DateTime
def -(duration: ReadableDuration): DateTime
def +(period: ReadablePeriod): DateTime
def -(period: ReadablePeriod): DateTime
def +(builder: DurationBuilder): DateTime
def -(builder: DurationBuilder): DateTime
// Property accessors (return DateTime.Property)
def millis: DateTime.Property
def second: DateTime.Property
def minute: DateTime.Property
def hour: DateTime.Property
def day: DateTime.Property
def week: DateTime.Property
def month: DateTime.Property
def year: DateTime.Property
def century: DateTime.Property
def era: DateTime.Property
// Property setters (fluent interface)
def withSecond(second: Int): DateTime
def withMinute(minute: Int): DateTime
def withHour(hour: Int): DateTime
def withDay(day: Int): DateTime
def withWeek(week: Int): DateTime
def withMonth(month: Int): DateTime
def withYear(year: Int): DateTime
def withCentury(century: Int): DateTime
def withEra(era: Int): DateTime
}Usage Examples:
import com.github.nscala_time.time.Imports._
val now = DateTime.now
// Arithmetic operations
val future = now + 2.hours + 30.minutes
val past = now - 1.day - 6.hours
val withDuration = now + Duration.standardMinutes(45)
val withPeriod = now + Period.months(2).plusDays(15)
// Property access and manipulation
val currentYear = now.year.get
val currentMonth = now.month.get
val dayOfWeek = now.dayOfWeek.get
// Fluent property setting
val specific = now
.withYear(2024)
.withMonth(12)
.withDay(25)
.withHour(14)
.withMinute(30)
.withSecond(0)
// Property-based calculations
val startOfDay = now.withTimeAtStartOfDay()
val endOfMonth = now.dayOfMonth.withMaximumValue()
val startOfYear = now.withDayOfYear(1).withTimeAtStartOfDay()Enhanced LocalDate with period arithmetic and property manipulation.
/**
* Rich LocalDate operations with period arithmetic and property access
*/
implicit class RichLocalDate(underlying: LocalDate) {
// Arithmetic operations
def +(period: ReadablePeriod): LocalDate
def -(period: ReadablePeriod): LocalDate
def +(builder: DurationBuilder): LocalDate
def -(builder: DurationBuilder): LocalDate
// Property accessors (return LocalDate.Property)
def day: LocalDate.Property
def week: LocalDate.Property
def month: LocalDate.Property
def year: LocalDate.Property
def century: LocalDate.Property
def era: LocalDate.Property
// Property setters
def withDay(day: Int): LocalDate
def withWeek(week: Int): LocalDate
def withMonth(month: Int): LocalDate
def withYear(year: Int): LocalDate
def withCentury(century: Int): LocalDate
def withEra(era: Int): LocalDate
// Utility methods
def interval: Interval // Create interval for entire day
}Usage Examples:
import com.github.nscala_time.time.Imports._
val today = LocalDate.now
// Arithmetic operations
val nextWeek = today + 1.week
val lastMonth = today - 1.month
val futureDate = today + Period.years(1).plusMonths(6)
// Property manipulation
val specificDate = today
.withYear(2024)
.withMonth(6)
.withDay(15)
// Property queries
val dayOfMonth = today.dayOfMonth.get
val isLeapYear = today.year.isLeap
val daysInMonth = today.dayOfMonth.getMaximumValue
// Interval creation
val dayInterval = today.interval // 00:00:00 to 23:59:59.999 for the day
// Date calculations
val startOfMonth = today.withDayOfMonth(1)
val endOfMonth = today.dayOfMonth.withMaximumValue()
val firstDayOfYear = today.withDayOfYear(1)Enhanced LocalDateTime combining date and time operations.
/**
* Rich LocalDateTime operations with both duration and period arithmetic
*/
implicit class RichLocalDateTime(underlying: LocalDateTime) {
// Arithmetic operations
def +(duration: ReadableDuration): LocalDateTime
def -(duration: ReadableDuration): LocalDateTime
def +(period: ReadablePeriod): LocalDateTime
def -(period: ReadablePeriod): LocalDateTime
def +(builder: DurationBuilder): LocalDateTime
def -(builder: DurationBuilder): LocalDateTime
// Property accessors (similar to DateTime)
def millis: LocalDateTime.Property
def second: LocalDateTime.Property
def minute: LocalDateTime.Property
def hour: LocalDateTime.Property
def day: LocalDateTime.Property
def week: LocalDateTime.Property
def month: LocalDateTime.Property
def year: LocalDateTime.Property
def century: LocalDateTime.Property
def era: LocalDateTime.Property
// Property setters
def withSecond(second: Int): LocalDateTime
def withMinute(minute: Int): LocalDateTime
def withHour(hour: Int): LocalDateTime
def withDay(day: Int): LocalDateTime
def withWeek(week: Int): LocalDateTime
def withMonth(month: Int): LocalDateTime
def withYear(year: Int): LocalDateTime
def withCentury(century: Int): LocalDateTime
def withEra(era: Int): LocalDateTime
}Usage Examples:
import com.github.nscala_time.time.Imports._
val now = LocalDateTime.now
// Mixed arithmetic operations
val future = now + 2.hours + 1.day + 30.minutes
val past = now - Period.months(1) - Duration.standardHours(6)
// Precise time manipulation
val meeting = now
.withHour(14)
.withMinute(30)
.withSecond(0)
.withMillisOfSecond(0)
// Combined date and time operations
val deadline = now
.plusDays(7)
.withHour(17)
.withMinute(0)
.withSecond(0)Enhanced LocalTime with time-specific operations and arithmetic.
/**
* Rich LocalTime operations with period arithmetic and property access
*/
implicit class RichLocalTime(underlying: LocalTime) {
// Arithmetic operations
def +(period: ReadablePeriod): LocalTime
def -(period: ReadablePeriod): LocalTime
def +(builder: DurationBuilder): LocalTime
def -(builder: DurationBuilder): LocalTime
// Property accessors
def millis: LocalTime.Property
def second: LocalTime.Property
def minute: LocalTime.Property
def hour: LocalTime.Property
// Property setters
def withSecond(second: Int): LocalTime
def withMinute(minute: Int): LocalTime
def withHour(hour: Int): LocalTime
def withMillisOfSecond(millis: Int): LocalTime
}Usage Examples:
import com.github.nscala_time.time.Imports._
val currentTime = LocalTime.now
// Time arithmetic
val laterTime = currentTime + 2.hours + 30.minutes
val earlierTime = currentTime - 45.minutes - 30.seconds
// Specific time creation
val meetingTime = LocalTime.MIDNIGHT
.withHour(9)
.withMinute(30)
.withSecond(0)
// Time boundaries
val startOfDay = LocalTime.MIDNIGHT
val noon = LocalTime.NOON
val endOfDay = LocalTime.MIDNIGHT.minusMillis(1)
// Time calculations
val duration = laterTime.toSecondOfDay - currentTime.toSecondOfDay
val timeUntilMidnight = LocalTime.MIDNIGHT.minusMillis(1).toSecondOfDay - currentTime.toSecondOfDayEnhanced Interval with collection generation and manipulation.
/**
* Rich Interval operations with collection generation capabilities
*/
implicit class RichInterval(underlying: Interval) {
/**
* Generate collection of DateTimes by stepping through interval with given period
* @param period The step size for iteration
* @return Iterable collection of DateTime instances
*/
def by[CC[_]](period: ReadablePeriod): CC[DateTime]
}Usage Examples:
import com.github.nscala_time.time.Imports._
val start = DateTime.now
val end = start + 1.week
val interval = start to end
// Generate collections of DateTimes
val dailyTimes = interval.by(1.day) // Every day
val hourlyTimes = interval.by(1.hour) // Every hour
val weeklyTimes = interval.by(1.week) // Every week
// Iterate through time periods
dailyTimes.foreach(dt => println(s"Day: ${dt.toString("yyyy-MM-dd")}"))
// Create schedules
val businessHours = LocalTime.parse("09:00") to LocalTime.parse("17:00")
val workingDays = (start.withTimeAtStartOfDay to end.withTimeAtStartOfDay).by(1.day)
.filter(_.getDayOfWeek <= 5) // Monday to Friday
// Time series analysis
val monthlyInterval = start to (start + 1.year)
val monthlyPoints = monthlyInterval.by(1.month)Rich operations on DateTime, LocalDate, LocalTime, and LocalDateTime properties.
/**
* Enhanced property operations for temporal field manipulation
*/
implicit class RichDateTimeProperty(underlying: DateTime.Property) {
// Additional property methods are inherited from Joda Time
// but enhanced with Scala-friendly access patterns
}
implicit class RichLocalDateProperty(underlying: LocalDate.Property) {
// Enhanced local date property operations
}
implicit class RichLocalTimeProperty(underlying: LocalTime.Property) {
// Enhanced local time property operations
}
implicit class RichLocalDateTimeProperty(underlying: LocalDateTime.Property) {
// Enhanced local date time property operations
}Usage Examples:
import com.github.nscala_time.time.Imports._
val dt = DateTime.now
// Property queries
val year = dt.year.get
val isLeapYear = dt.year.isLeap
val maxDayOfMonth = dt.dayOfMonth.getMaximumValue
val minDayOfMonth = dt.dayOfMonth.getMinimumValue
// Property rounding
val roundedToHour = dt.hourOfDay.roundFloorCopy()
val roundedToDay = dt.dayOfMonth.roundFloorCopy()
// Property arithmetic
val nextMonth = dt.monthOfYear.addToCopy(1)
val lastYear = dt.year.addToCopy(-1)
// Property text handling
val monthName = dt.monthOfYear.getAsText
val dayName = dt.dayOfWeek.getAsText
val shortMonthName = dt.monthOfYear.getAsShortTextimport com.github.nscala_time.time.Imports._
// Business day calculations
def isBusinessDay(date: DateTime): Boolean = {
val dayOfWeek = date.getDayOfWeek
dayOfWeek >= 1 && dayOfWeek <= 5
}
def nextBusinessDay(date: DateTime): DateTime = {
val next = date + 1.day
if (isBusinessDay(next)) next else nextBusinessDay(next)
}
// Quarter calculations
def startOfQuarter(date: DateTime): DateTime = {
val quarterStartMonth = ((date.getMonthOfYear - 1) / 3) * 3 + 1
date.withMonthOfYear(quarterStartMonth).withDayOfMonth(1).withTimeAtStartOfDay()
}
def endOfQuarter(date: DateTime): DateTime = {
startOfQuarter(date).plusMonths(3).minusMillis(1)
}import com.github.nscala_time.time.Imports._
// Age calculations
def calculateAge(birthDate: LocalDate, asOf: LocalDate = LocalDate.now): Int = {
val period = new Period(birthDate, asOf, PeriodType.yearMonthDay())
period.getYears
}
// Duration formatting
def formatDuration(duration: Duration): String = {
val hours = duration.toStandardHours.getHours
val minutes = duration.toStandardMinutes.getMinutes % 60
val seconds = duration.toStandardSeconds.getSeconds % 60
f"${hours}%02d:${minutes}%02d:${seconds}%02d"
}
// Time zone handling
def convertToTimeZone(dt: DateTime, targetZone: DateTimeZone): DateTime = {
dt.withZone(targetZone)
}import com.github.nscala_time.time.Imports._
// Generate recurring schedule
def generateWeeklySchedule(start: DateTime, weeks: Int): List[DateTime] = {
(0 until weeks).map(w => start + (w * 1.week)).toList
}
// Find next occurrence of weekday
def nextWeekday(date: DateTime, targetDayOfWeek: Int): DateTime = {
val currentDayOfWeek = date.getDayOfWeek
val daysToAdd = if (targetDayOfWeek <= currentDayOfWeek) {
targetDayOfWeek + 7 - currentDayOfWeek
} else {
targetDayOfWeek - currentDayOfWeek
}
date + daysToAdd.days
}
// Business hours calculations
case class BusinessHours(start: LocalTime, end: LocalTime)
def isWithinBusinessHours(dt: DateTime, hours: BusinessHours): Boolean = {
val time = dt.toLocalTime
time.isAfter(hours.start) && time.isBefore(hours.end)
}