Groovy extensions for working with Java 8+ date/time types, providing convenient methods for temporal operations and transformations
—
Static methods for parsing temporal objects from strings with custom patterns and creating temporal objects through factory methods.
Static parsing methods for converting strings to temporal objects using custom DateTimeFormatter patterns.
/**
* Parse text into a LocalDate using the provided pattern.
*/
LocalDate parse(LocalDate type, CharSequence text, String pattern)
/**
* Parse text into a LocalDateTime using the provided pattern.
*/
LocalDateTime parse(LocalDateTime type, CharSequence text, String pattern)
/**
* Parse text into a LocalTime using the provided pattern.
*/
LocalTime parse(LocalTime type, CharSequence text, String pattern)
/**
* Parse text into a MonthDay using the provided pattern.
*/
MonthDay parse(MonthDay type, CharSequence text, String pattern)
/**
* Parse text into an OffsetDateTime using the provided pattern.
*/
OffsetDateTime parse(OffsetDateTime type, CharSequence text, String pattern)
/**
* Parse text into an OffsetTime using the provided pattern.
*/
OffsetTime parse(OffsetTime type, CharSequence text, String pattern)
/**
* Parse text into a Year using the provided pattern.
*/
Year parse(Year type, CharSequence text, String pattern)
/**
* Parse text into a YearMonth using the provided pattern.
*/
YearMonth parse(YearMonth type, CharSequence text, String pattern)
/**
* Parse text into a ZonedDateTime using the provided pattern.
*/
ZonedDateTime parse(ZonedDateTime type, CharSequence text, String pattern)Usage Examples:
import java.time.*
// LocalDate parsing
def date1 = LocalDate.parse('2024-12-25', 'yyyy-MM-dd')
def date2 = LocalDate.parse('Dec 25, 2024', 'MMM dd, yyyy')
def date3 = LocalDate.parse('25/12/24', 'dd/MM/yy')
println "Parsed dates: ${date1}, ${date2}, ${date3}"
// LocalDateTime parsing
def datetime1 = LocalDateTime.parse('2024-12-25 14:30:00', 'yyyy-MM-dd HH:mm:ss')
def datetime2 = LocalDateTime.parse('Dec 25, 2024 2:30 PM', 'MMM dd, yyyy h:mm a')
println "Parsed datetimes: ${datetime1}, ${datetime2}"
// LocalTime parsing
def time1 = LocalTime.parse('14:30:45', 'HH:mm:ss')
def time2 = LocalTime.parse('2:30 PM', 'h:mm a')
def time3 = LocalTime.parse('14:30:45.123', 'HH:mm:ss.SSS')
println "Parsed times: ${time1}, ${time2}, ${time3}"
// Year parsing
def year1 = Year.parse('2024', 'yyyy')
def year2 = Year.parse('24', 'yy')
// YearMonth parsing
def yearMonth1 = YearMonth.parse('2024-12', 'yyyy-MM')
def yearMonth2 = YearMonth.parse('Dec 2024', 'MMM yyyy')
// MonthDay parsing
def monthDay1 = MonthDay.parse('12-25', 'MM-dd')
def monthDay2 = MonthDay.parse('Dec 25', 'MMM dd')
println "Year: ${year1}, YearMonth: ${yearMonth1}, MonthDay: ${monthDay1}"Parsing temporal objects that include timezone or offset information.
Usage Examples:
import java.time.*
// OffsetDateTime parsing
def offsetDateTime1 = OffsetDateTime.parse('2024-12-25T14:30:00+05:30', "yyyy-MM-dd'T'HH:mm:ssXXX")
def offsetDateTime2 = OffsetDateTime.parse('2024-12-25 14:30:00 +0530', 'yyyy-MM-dd HH:mm:ss Z')
// OffsetTime parsing
def offsetTime1 = OffsetTime.parse('14:30:00+05:30', 'HH:mm:ssXXX')
def offsetTime2 = OffsetTime.parse('2:30 PM +0530', 'h:mm a Z')
// ZonedDateTime parsing
def zonedDateTime1 = ZonedDateTime.parse('2024-12-25T14:30:00 America/New_York', "yyyy-MM-dd'T'HH:mm:ss VV")
def zonedDateTime2 = ZonedDateTime.parse('Dec 25, 2024 2:30 PM EST', 'MMM dd, yyyy h:mm a z')
def zonedDateTime3 = ZonedDateTime.parse('2024/12/25 14:30 Eastern Standard Time', 'yyyy/MM/dd HH:mm zzzz')
println "Offset DateTime: ${offsetDateTime1}"
println "Offset Time: ${offsetTime1}"
println "Zoned DateTime: ${zonedDateTime1}"Common DateTimeFormatter pattern symbols for parsing operations.
Usage Examples:
import java.time.*
// Date patterns
def patterns = [
'yyyy-MM-dd', // 2024-12-25
'dd/MM/yyyy', // 25/12/2024
'MMM dd, yyyy', // Dec 25, 2024
'EEEE, MMMM dd, yyyy', // Wednesday, December 25, 2024
'dd-MMM-yy', // 25-Dec-24
'yyyyMMdd', // 20241225
'yyyy-DDD' // 2024-360 (day of year)
]
def dateString = '2024-12-25'
patterns.each { pattern ->
try {
def parsed = LocalDate.parse(dateString, pattern)
println "${pattern}: ${parsed}"
} catch (Exception e) {
println "${pattern}: Failed to parse '${dateString}'"
}
}
// Time patterns
def timePatterns = [
'HH:mm:ss', // 14:30:45
'HH:mm:ss.SSS', // 14:30:45.123
'h:mm a', // 2:30 PM
'H:mm', // 14:30
'HH:mm:ss.SSSSSS', // 14:30:45.123456 (microseconds)
]
def timeString = '14:30:45'
timePatterns.each { pattern ->
try {
def parsed = LocalTime.parse(timeString, pattern)
println "${pattern}: ${parsed}"
} catch (Exception e) {
println "${pattern}: Failed to parse '${timeString}'"
}
}
// Timezone patterns
def zonePatterns = [
'XXX', // +05:30, Z
'XX', // +0530, Z
'X', // +05, Z
'Z', // +0530
'z', // EST, GMT
'zzzz', // Eastern Standard Time
'VV' // America/New_York
]Static factory methods for creating temporal objects.
/**
* Returns the ZoneOffset currently associated with the system default ZoneId.
*/
ZoneOffset systemDefault(ZoneOffset type)
/**
* Creates a Period consisting of the number of years between two Year instances.
*/
Period between(Period type, Year startInclusive, Year endExclusive)
/**
* Creates a Period consisting of the number of years and months between two YearMonth instances.
*/
Period between(Period type, YearMonth startInclusive, YearMonth endExclusive)Usage Examples:
import java.time.*
// System default offset
def systemOffset = ZoneOffset.systemDefault()
println "System default offset: ${systemOffset}"
// Period between years
def startYear = Year.of(2020)
def endYear = Year.of(2024)
def yearPeriod = Period.between(startYear, endYear)
println "Period between years: ${yearPeriod.years} years"
// Period between year-months
def startYearMonth = YearMonth.of(2024, 1) // January 2024
def endYearMonth = YearMonth.of(2024, 7) // July 2024
def monthPeriod = Period.between(startYearMonth, endYearMonth)
println "Period between year-months: ${monthPeriod.months} months"
// More complex year-month periods
def start = YearMonth.of(2023, 10) // October 2023
def end = YearMonth.of(2024, 3) // March 2024
def complexPeriod = Period.between(start, end)
println "Complex period: ${complexPeriod.years} years, ${complexPeriod.months} months"Exception handling for parsing operations.
Exceptions Thrown:
IllegalArgumentException - If the pattern is invalidDateTimeParseException - If the text cannot be parsed using the patternUsage Examples:
import java.time.*
import java.time.format.DateTimeParseException
// Handling parse errors
def invalidDateString = "2024-13-45" // Invalid month and day
def validPattern = "yyyy-MM-dd"
try {
def date = LocalDate.parse(invalidDateString, validPattern)
println "Parsed: ${date}"
} catch (DateTimeParseException e) {
println "Parse error: ${e.message}"
println "Error at index: ${e.errorIndex}"
println "Parsed text: '${e.parsedString}'"
}
// Pattern validation
def invalidPattern = "invalid-pattern"
def validDateString = "2024-12-25"
try {
def date = LocalDate.parse(validDateString, invalidPattern)
println "Parsed: ${date}"
} catch (IllegalArgumentException e) {
println "Invalid pattern: ${e.message}"
}
// Helper method for safe parsing
def safeParse = { String text, String pattern ->
try {
return LocalDate.parse(text, pattern)
} catch (DateTimeParseException | IllegalArgumentException e) {
println "Failed to parse '${text}' with pattern '${pattern}': ${e.message}"
return null
}
}
// Test safe parsing
def result1 = safeParse("2024-12-25", "yyyy-MM-dd") // Success
def result2 = safeParse("invalid", "yyyy-MM-dd") // Failure
def result3 = safeParse("2024-12-25", "invalid") // Failure
println "Results: ${result1}, ${result2}, ${result3}"Complex parsing scenarios with multiple formats and fallback strategies.
Usage Examples:
import java.time.*
import java.time.format.DateTimeParseException
// Multi-format parsing helper
def parseWithMultipleFormats = { String text, List<String> patterns ->
for (pattern in patterns) {
try {
return LocalDate.parse(text, pattern)
} catch (DateTimeParseException e) {
// Try next pattern
}
}
throw new DateTimeParseException("Unable to parse '${text}' with any provided pattern", text, 0)
}
// Test with multiple date formats
def flexiblePatterns = [
'yyyy-MM-dd', // 2024-12-25
'dd/MM/yyyy', // 25/12/2024
'MMM dd, yyyy', // Dec 25, 2024
'dd-MM-yy', // 25-12-24
'yyyyMMdd' // 20241225
]
def testDates = [
'2024-12-25',
'25/12/2024',
'Dec 25, 2024',
'25-12-24',
'20241225',
'invalid-date'
]
testDates.each { dateString ->
try {
def parsed = parseWithMultipleFormats(dateString, flexiblePatterns)
println "${dateString} -> ${parsed}"
} catch (DateTimeParseException e) {
println "${dateString} -> Parse failed"
}
}
// Parsing with locale-specific patterns
import java.util.Locale
def parseWithLocale = { String text, String pattern, Locale locale ->
def formatter = DateTimeFormatter.ofPattern(pattern, locale)
return LocalDate.parse(text, formatter)
}
// Example with different locales (requires proper locale-specific text)
def germanDate = parseWithLocale('25. Dezember 2024', 'dd. MMMM yyyy', Locale.GERMAN)
def frenchDate = parseWithLocale('25 décembre 2024', 'dd MMMM yyyy', Locale.FRENCH)
println "German: ${germanDate}"
println "French: ${frenchDate}"Integration with existing Java 8 time parsing capabilities.
Usage Examples:
import java.time.*
import java.time.format.DateTimeFormatter
// Using predefined formatters with parse extensions
def isoDate = LocalDate.parse('2024-12-25', DateTimeFormatter.ISO_LOCAL_DATE.pattern)
def isoDateTime = LocalDateTime.parse('2024-12-25T14:30:00', DateTimeFormatter.ISO_LOCAL_DATE_TIME.pattern)
// Custom formatter reuse
def customFormatter = DateTimeFormatter.ofPattern('dd/MM/yyyy HH:mm')
def customParsed1 = LocalDateTime.parse('25/12/2024 14:30', customFormatter.pattern)
def customParsed2 = LocalDateTime.parse('31/12/2024 23:59', customFormatter.pattern)
println "Custom parsed: ${customParsed1}, ${customParsed2}"
// Combining with standard parsing
def standardParsed = LocalDate.parse('2024-12-25') // Uses ISO format by default
def extensionParsed = LocalDate.parse('25-12-2024', 'dd-MM-yyyy') // Uses extension method
println "Standard: ${standardParsed}, Extension: ${extensionParsed}"Install with Tessl CLI
npx tessl i tessl/maven-org-codehaus-groovy--groovy-datetime