or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

core-types.mddatetime-operations.mdduration-building.mdindex.mdlocal-datetime.mdordering.mdstring-parsing.md
tile.json

string-parsing.mddocs/

String Parsing

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.

Capabilities

Enhanced String Class

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")

Safe Option-Based Parsing

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)

Common Date Format Patterns

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 Date

Custom 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")

Interval Parsing

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}")
}

Error Handling Best Practices

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
}