Last active
March 14, 2022 15:40
-
-
Save dblevins/03df3cd5eb12f2da05997eef80ac4eca to your computer and use it in GitHub Desktop.
Legacy Java 7 version. See recommended Java 8 version https://gist.github.com/dblevins/47f7508e241d775fd7007a4639d6565a
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.text.ParseException; | |
import java.text.SimpleDateFormat; | |
import java.time.LocalDate; | |
import java.time.ZoneId; | |
import java.util.Date; | |
/** | |
* This pattern has the following benefits: | |
* | |
* - Date formats are referenced as a strong type | |
* - Thread-safety handled | |
* - Parse exception is not a checked exception | |
* - Code completion on patterns | |
* - Patterns can be javadoc'ed | |
*/ | |
public enum Dates { | |
/** | |
* <p>Format: yyyy-MM-dd</p> | |
* <p>Example: 2022-03-30</p> | |
*/ | |
yyyy_MM_dd("yyyy-MM-dd"), | |
/** | |
* <p>Format: MMM dd, yyyy</p> | |
* <p>Example: Mar 30, 2022</p> | |
*/ | |
MMM_dd_yyyy("MMM dd, yyyy"); | |
private final ThreadLocal<SimpleDateFormat> instance = new ThreadLocal<>(); | |
private final String formatString; | |
Dates(final String formatString) { | |
this.formatString = formatString; | |
} | |
public Date parse(final String string) { | |
try { | |
return instance().parse(string); | |
} catch (ParseException e) { | |
throw new DateParseException(formatString, string); | |
} | |
} | |
public LocalDate parseLocalDate(final String string) { | |
return parse(string).toInstant() | |
.atZone(ZoneId.systemDefault()) | |
.toLocalDate(); | |
} | |
public String format(final Date date) { | |
return instance().format(date); | |
} | |
public String format(final LocalDate date) { | |
return instance().format(Date.from(date.atStartOfDay() | |
.atZone(ZoneId.systemDefault()) | |
.toInstant())); | |
} | |
private SimpleDateFormat instance() { | |
{ | |
final SimpleDateFormat format = instance.get(); | |
if (format != null) return format; | |
} | |
{ | |
final SimpleDateFormat format = new SimpleDateFormat(formatString); | |
instance.set(format); | |
return format; | |
} | |
} | |
private static class DateParseException extends RuntimeException { | |
public DateParseException(final String formatString, final String string) { | |
super(String.format("Unable to parse date string '%s' using format '%s'", string, formatString)); | |
} | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import org.junit.jupiter.api.Assertions; | |
import org.junit.jupiter.params.ParameterizedTest; | |
import org.junit.jupiter.params.provider.Arguments; | |
import org.junit.jupiter.params.provider.MethodSource; | |
import java.time.LocalDate; | |
import java.util.stream.Stream; | |
import static org.junit.jupiter.params.provider.Arguments.arguments; | |
public class DatesTest { | |
private static Stream<Arguments> data() { | |
return Stream.of( | |
arguments(Dates.yyyy_MM_dd, "2022-03-30"), | |
arguments(Dates.MMM_dd_yyyy, "Mar 30, 2022") | |
); | |
} | |
@ParameterizedTest | |
@MethodSource("data") | |
public void parse(final Dates dateEnum, final String dateString) { | |
final LocalDate expected = LocalDate.of(2022, 3, 30); | |
final LocalDate actual = dateEnum.parse(dateString); | |
Assertions.assertEquals(expected, actual); | |
} | |
@ParameterizedTest | |
@MethodSource("data") | |
public void format(final Dates dateEnum, final String expected) { | |
final LocalDate date = LocalDate.of(2022, 3, 30); | |
final String actual = dateEnum.format(date); | |
Assertions.assertEquals(expected, actual); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment