I'm reading in date strings that could be with or without a time zone adjustment: yyyyMMddHHmmssz
or yyyyMMddHHmmss
. When a string is missing a zone, I'll treat it as GMT. I'm not seeing any way to create optional sections in a SimpleDateFormat
, but maybe I'm missing something. Is there a way to do this with a SimpleDateFormat
, or should I just write a new concrete DateFormat
to handle this?
DateTimeFormatter is a replacement for the old SimpleDateFormat that is thread-safe and provides additional functionality.
Class SimpleDateFormat. SimpleDateFormat is a concrete class for formatting and parsing dates in a locale-sensitive manner. It allows for formatting (date -> text), parsing (text -> date), and normalization. SimpleDateFormat allows you to start by choosing any user-defined patterns for date-time formatting.
Class SimpleDateFormat. Deprecated. A class for parsing and formatting dates with a given pattern, compatible with the Java 6 API.
2.2.Date formats are not synchronized. It is recommended to create separate format instances for each thread. If multiple threads access a format concurrently, it must be synchronized externally. So SimpleDateFormat instances are not thread-safe, and we should use them carefully in concurrent environments.
JSR-310 has been delivered with Java 8 which provides enhanced support for parsing temporal values where components may now be optional. Not only can you make the zone optional, but you can also make the time component optional and return the correct temporal unit for the given string.
Consider the following test cases.
public class DateFormatTest { private final DateTimeFormatter formatter = DateTimeFormatter.ofPattern( "yyyy-MM-dd[[ ]['T']HH:mm[:ss][XXX]]"); private TemporalAccessor parse(String v) { return formatter.parseBest(v, ZonedDateTime::from, LocalDateTime::from, LocalDate::from); } @Test public void testDateTime1() { assertEquals(LocalDateTime.of(2014, 9, 23, 14, 20, 59), parse("2014-09-23T14:20:59")); } @Test public void testDateTime2() { assertEquals(LocalDateTime.of(2014, 9, 23, 14, 20), parse("2014-09-23 14:20")); } @Test public void testDateOnly() { assertEquals(LocalDate.of(2014, 9, 23), parse("2014-09-23")); } @Test public void testZonedDateTime() { assertEquals(ZonedDateTime.of(2014, 9, 23, 14, 20, 59, 0, ZoneOffset.ofHoursMinutes(10, 30)), parse("2014-09-23T14:20:59+10:30")); } }
Here the DateTimeFormatter pattern of "yyyy-MM-dd[[ ]['T']HH:mm[:ss][XXX]]"
allows optionals within the square parentheses which can also be nested. Patterns can also be constructed from a DateTimeFormatterBuilder, which the above pattern is demonstrated here:
private final DateTimeFormatter formatter = new DateTimeFormatterBuilder() .parseCaseInsensitive() .append(DateTimeFormatter.ISO_LOCAL_DATE) .optionalStart() .optionalStart() .appendLiteral(' ') .optionalEnd() .optionalStart() .appendLiteral('T') .optionalEnd() .appendOptional(DateTimeFormatter.ISO_TIME) .toFormatter();
This would translate to an expression which looks like the following:
yyyy-MM-dd[[' ']['T']HH:mm[':'ss[.SSS]]].
Optional values can be nested and are also auto closed at the end if still open. Note however that there is no way to provide an exclusive OR on optional parts, thus the above format would actually parse the following value quite fine:
2018-03-08 T11:12
Note the really neat capability that we can reuse existing formatter's as parts of our current format.
I know this is an old post but just for the record...
Apache DateUtils class can help you with that.
String[] acceptedFormats = {"dd/MM/yyyy","dd/MM/yyyy HH:mm","dd/MM/yyyy HH:mm:ss"}; Date date1 = DateUtils.parseDate("12/07/2012", acceptedFormats); Date date2 = DateUtils.parseDate("12/07/2012 23:59:59", acceptedFormats);
Link to the Apache Commons Lang library in Maven repository, you might want to check what's the latest version:
http://mvnrepository.com/artifact/org.apache.commons/commons-lang3
Maven v3.4
<dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-lang3</artifactId> <version>3.4</version> </dependency>
Gradle v3.4
'org.apache.commons:commons-lang3:3.4'
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With