Safe string parsing capabilities with Option-based returns and custom format support for all major date/time types. Provides both exception-throwing and safe parsing methods with comprehensive format support.
Rich wrapper providing comprehensive date/time parsing functionality for strings.
/**
* Adds date/time parsing methods to strings
* @param s The underlying string value
*/
implicit class RichString(val s: String) extends AnyVal {
// Direct parsing methods (throws exceptions on invalid input)
def toDateTime: DateTime
def toInterval: Interval
def toLocalDate: LocalDate
// Safe parsing methods (returns Option)
def toDateTimeOption: Option[DateTime]
def toLocalDateOption: Option[LocalDate]
def toIntervalOption: Option[Interval]
// Parsing with custom formats (throws exceptions on invalid input)
def toDateTime(format: String): DateTime
def toLocalDate(format: String): LocalDate
// Safe parsing with custom formats (returns Option)
def toDateTimeOption(format: String): Option[DateTime]
def toLocalDateOption(format: String): Option[LocalDate]
// DateTimeFormat-based parsing
def dateTimeFormat(format: String): DateTime
def localDateTimeFormat(format: String): LocalDate
}Usage Examples:
import com.github.nscala_time.time.Imports._
// Direct parsing (throws exceptions for invalid input)
val dateTime1 = "2023-12-25T10:30:00".toDateTime
val localDate1 = "2023-12-25".toLocalDate
val interval1 = "2023-01-01T00:00:00/2023-12-31T23:59:59".toInterval
// Safe parsing (returns Option)
val safeParsing1 = "2023-12-25T10:30:00".toDateTimeOption
val safeParsing2 = "invalid-date".toDateTimeOption // Returns None
val safeParsing3 = "2023-12-25".toLocalDateOption
safeParsing1 match {
case Some(dt) => println(s"Parsed successfully: $dt")
case None => println("Failed to parse")
}
// Custom format parsing
val customDate1 = "25/12/2023".toDateTime("dd/MM/yyyy")
val customDate2 = "Dec 25, 2023".toLocalDate("MMM dd, yyyy")
// Safe custom format parsing
val safeCustom1 = "25/12/2023".toDateTimeOption("dd/MM/yyyy")
val safeCustom2 = "invalid".toDateTimeOption("dd/MM/yyyy") // Returns None
// Using DateTimeFormat patterns
val formatted1 = "2023-12-25T10:30".dateTimeFormat("yyyy-MM-dd'T'HH:mm")
val formatted2 = "25-Dec-2023".localDateTimeFormat("dd-MMM-yyyy")The library provides safe parsing methods that return Option types to handle invalid input gracefully.
/**
* Safe parsing implementation that catches IllegalArgumentException
* and returns None for invalid input
*/
private def toOption[A](f: => A): Option[A] = try {
Some(f)
} catch {
case _: IllegalArgumentException => None
}Safe Parsing Examples:
import com.github.nscala_time.time.Imports._
// Handling multiple date formats safely
val dateStrings = List(
"2023-12-25T10:30:00",
"invalid-date",
"2023-12-25",
"not-a-date-at-all"
)
val parsedDates = dateStrings.map(_.toDateTimeOption)
// Result: List(Some(DateTime), None, Some(DateTime), None)
val validDates = parsedDates.flatten
// Result: List(DateTime, DateTime) - only valid dates
// Pattern matching for safe parsing
def parseAndHandle(dateStr: String): String = {
dateStr.toDateTimeOption match {
case Some(dt) => s"Successfully parsed: ${dt.toString("yyyy-MM-dd")}"
case None => s"Failed to parse: $dateStr"
}
}
// Custom format safe parsing
val customFormats = List(
("25/12/2023", "dd/MM/yyyy"),
("2023-12-25", "yyyy-MM-dd"),
("invalid", "dd/MM/yyyy")
)
val customResults = customFormats.map { case (date, format) =>
date.toDateTimeOption(format)
}
// Result: List(Some(DateTime), Some(DateTime), None)Examples of commonly used date format patterns for parsing.
ISO Date Formats:
// Standard ISO formats (parsed automatically)
"2023-12-25T10:30:00".toDateTime // ISO DateTime
"2023-12-25T10:30:00.123Z".toDateTime // ISO with milliseconds and UTC
"2023-12-25T10:30:00+01:00".toDateTime // ISO with timezone offset
"2023-12-25".toLocalDate // ISO DateCustom Format Examples:
// US date formats
"12/25/2023".toDateTime("MM/dd/yyyy")
"Dec 25, 2023".toLocalDate("MMM dd, yyyy")
"December 25, 2023".toLocalDate("MMMM dd, yyyy")
// European date formats
"25/12/2023".toDateTime("dd/MM/yyyy")
"25.12.2023".toLocalDate("dd.MM.yyyy")
"25-Dec-2023".toLocalDate("dd-MMM-yyyy")
// Time formats
"10:30:45".toLocalTime // ISO time format (if LocalTime parsing available)
"10:30 AM".toTime("hh:mm aa") // 12-hour format with AM/PM
// Combined date-time formats
"25/12/2023 10:30".toDateTime("dd/MM/yyyy HH:mm")
"Dec 25, 2023 at 10:30 AM".toDateTime("MMM dd, yyyy 'at' hh:mm aa")String parsing support for Joda Time intervals.
import com.github.nscala_time.time.Imports._
// ISO interval formats
val interval1 = "2023-01-01T00:00:00/2023-12-31T23:59:59".toInterval
val interval2 = "2023-01-01/P1Y".toInterval // Start date + period
val interval3 = "P1Y/2023-12-31".toInterval // Period + end date
// Safe interval parsing
val safeInterval1 = "2023-01-01T00:00:00/2023-12-31T23:59:59".toIntervalOption
val safeInterval2 = "invalid-interval".toIntervalOption // Returns None
// Working with parsed intervals
safeInterval1.foreach { interval =>
println(s"Duration: ${interval.toDurationMillis} ms")
println(s"Start: ${interval.getStart}")
println(s"End: ${interval.getEnd}")
}Recommended patterns for handling parsing errors.
import com.github.nscala_time.time.Imports._
// Using for-comprehensions with Option
def parseUserInput(date: String, time: String): Option[DateTime] = {
for {
parsedDate <- date.toLocalDateOption
parsedDateTime <- s"${parsedDate}T${time}".toDateTimeOption
} yield parsedDateTime
}
// Using Try for more detailed error handling
import scala.util.Try
def parseWithTry(dateStr: String): Try[DateTime] = {
Try(dateStr.toDateTime)
}
// Providing default values
def parseWithDefault(dateStr: String, default: DateTime): DateTime = {
dateStr.toDateTimeOption.getOrElse(default)
}
// Multiple format attempts
def parseMultipleFormats(dateStr: String): Option[DateTime] = {
val formats = List("yyyy-MM-dd", "dd/MM/yyyy", "MM/dd/yyyy")
formats.view
.map(format => dateStr.toDateTimeOption(format))
.find(_.isDefined)
.flatten
}