package org.simpleflatmapper.converter.test.time;
import org.junit.Test;
import org.simpleflatmapper.converter.Converter;
import org.simpleflatmapper.converter.ConverterService;
import java.text.SimpleDateFormat;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.Month;
import java.time.OffsetDateTime;
import java.time.OffsetTime;
import java.time.Year;
import java.time.YearMonth;
import java.time.ZoneId;
import java.time.ZoneOffset;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
import java.time.temporal.ChronoUnit;
import java.time.temporal.Temporal;
import java.util.Calendar;
import java.util.Date;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.simpleflatmapper.converter.test.ConverterServiceTestHelper.testConverter;
public class JavaTimeConverterServiceTest {
@Test
public void testJavaTimeToDate() throws Exception {
long time = System.currentTimeMillis();
final Date date = new Date(time);
final LocalDateTime localDateTime = LocalDateTime.ofInstant(date.toInstant(), ZoneId.systemDefault());
final ZonedDateTime zonedDateTime = localDateTime.atZone(ZoneId.systemDefault());
testConverter(localDateTime, date);
testConverter(localDateTime.toLocalTime(), date);
testConverter(localDateTime.toLocalDate(), trunc(date));
testConverter(date.toInstant(), date);
testConverter(zonedDateTime, date);
testConverter(zonedDateTime.toOffsetDateTime(), date);
testConverter(zonedDateTime.toOffsetDateTime().toOffsetTime(), date);
testConverter(YearMonth.of(2016, Month.FEBRUARY),
new SimpleDateFormat("yyyyMMdd").parse("20160201"));
testConverter(Year.of(2016),
new SimpleDateFormat("yyyyMMdd").parse("20160101"));
}
@Test
public void testDateToJavaTime() throws Exception {
long time = System.currentTimeMillis();
final Date date = new Date(time);
final LocalDateTime localDateTime = LocalDateTime.ofInstant(date.toInstant(), ZoneId.systemDefault());
final ZonedDateTime zonedDateTime = localDateTime.atZone(ZoneId.systemDefault());
testConverter(date, localDateTime);
testConverter(date, localDateTime.toLocalTime());
testConverter(trunc(date), localDateTime.toLocalDate());
testConverter(date, date.toInstant());
testConverter(date, zonedDateTime);
testConverter(date, zonedDateTime.toOffsetDateTime());
testConverter(date, zonedDateTime.toOffsetDateTime().toOffsetTime());
testConverter(new SimpleDateFormat("yyyyMMdd").parse("20160201"),
YearMonth.of(2016, Month.FEBRUARY)
);
testConverter(new SimpleDateFormat("yyyyMMdd").parse("20160201"),
Year.of(2016));
}
@Test
public void testObjectToInstant() throws Exception {
ZoneId zoneId = ZoneId.systemDefault();
Instant instant = Instant.now();
testObjectToInstant(null, null);
testObjectToInstant(instant, instant);
testObjectToInstant(instant.atZone(zoneId), instant);
testObjectToInstant(instant.atZone(zoneId).toInstant(), instant);
testObjectToInstant(instant.atZone(zoneId).toLocalDateTime(), instant);
testObjectToInstant(instant.atZone(zoneId).toOffsetDateTime(), instant);
testObjectToInstant(Date.from(instant), instant.truncatedTo(ChronoUnit.MILLIS));
testObjectToInstant(instant.toEpochMilli(), instant.truncatedTo(ChronoUnit.MILLIS));
try {
testObjectToInstant("a string", instant);
fail();
} catch (IllegalArgumentException e) {
// expected
}
}
private void testObjectToInstant(Object in, Instant out) throws Exception {
testConverter(in, out, Object.class, Instant.class);
}
@Test
public void testObjectToLocalDate() throws Exception {
ZoneId zoneId = ZoneId.systemDefault();
LocalDate localDate = LocalDate.now(zoneId);
testObjectToLocalDate(null, null);
testObjectToLocalDate(localDate, localDate);
testObjectToLocalDate(localDate.atStartOfDay().atZone(zoneId), localDate);
testObjectToLocalDate(localDate.atStartOfDay().atZone(zoneId).toInstant(), localDate);
testObjectToLocalDate(localDate.atStartOfDay().atZone(zoneId).toOffsetDateTime(), localDate);
testObjectToLocalDate(localDate.atStartOfDay(), localDate);
testObjectToLocalDate(Date.from(localDate.atStartOfDay().atZone(zoneId).toInstant()), localDate);
try {
testObjectToLocalDate("a string", localDate);
fail();
} catch (IllegalArgumentException e) {
// expected
}
}
private void testObjectToLocalDate(Object in, LocalDate out) throws Exception {
testConverter(in, out, Object.class, LocalDate.class);
}
@Test
public void testObjectToLocalDateTime() throws Exception {
ZoneId zoneId = ZoneId.systemDefault();
LocalDateTime localDateTime = LocalDateTime.now(zoneId);
testObjectToLocalDateTime(null, null);
testObjectToLocalDateTime(localDateTime, localDateTime);
testObjectToLocalDateTime(localDateTime.atZone(zoneId), localDateTime);
testObjectToLocalDateTime(localDateTime.atZone(zoneId).toInstant(), localDateTime);
testObjectToLocalDateTime(localDateTime.atZone(zoneId).toOffsetDateTime(), localDateTime);
testObjectToLocalDateTime(Date.from(localDateTime.atZone(zoneId).toInstant()), localDateTime.truncatedTo(ChronoUnit.MILLIS));
try {
testObjectToLocalDateTime("a string", localDateTime);
fail();
} catch (IllegalArgumentException e) {
// expected
}
}
private void testObjectToLocalDateTime(Object in, LocalDateTime out) throws Exception {
testConverter(in, out, Object.class, LocalDateTime.class);
}
@Test
public void testObjectToLocalTime() throws Exception {
ZoneId zoneId = ZoneId.systemDefault();
LocalTime localTime = LocalTime.now(zoneId);
ZoneOffset offset = zoneId.getRules().getOffset(localTime.atDate(LocalDate.now()));
testObjectToLocalTime(null, null);
testObjectToLocalTime(localTime, localTime);
testObjectToLocalTime(localTime.atDate(LocalDate.now()), localTime);
testObjectToLocalTime(localTime.atDate(LocalDate.now()).atZone(zoneId), localTime);
testObjectToLocalTime(localTime.atDate(LocalDate.now()).atOffset(offset), localTime);
testObjectToLocalTime(localTime.atDate(LocalDate.now()).toLocalTime(), localTime);
testObjectToLocalTime(localTime.atDate(LocalDate.now()).toInstant(offset), localTime);
testObjectToLocalTime(Date.from(localTime.atDate(LocalDate.now()).toInstant(offset)), localTime.truncatedTo(ChronoUnit.MILLIS));
try {
testObjectToLocalTime("a string", localTime);
fail();
} catch (IllegalArgumentException e) {
// expected
}
}
private void testObjectToLocalTime(Object in, LocalTime out) throws Exception {
testConverter(in, out, Object.class, LocalTime.class);
}
@Test
public void testObjectToOffsetDateTime() throws Exception {
ZoneId zoneId = ZoneId.systemDefault();
OffsetDateTime offsetDateTime = OffsetDateTime.now(zoneId);
testObjectToOffsetDateTime(null, null);
testObjectToOffsetDateTime(offsetDateTime, offsetDateTime);
testObjectToOffsetDateTime(offsetDateTime.toLocalDateTime(), offsetDateTime);
testObjectToOffsetDateTime(offsetDateTime.toInstant(), offsetDateTime);
testObjectToOffsetDateTime(offsetDateTime.atZoneSameInstant(zoneId), offsetDateTime);
testObjectToOffsetDateTime(offsetDateTime.atZoneSameInstant(zoneId), offsetDateTime);
testObjectToOffsetDateTime(offsetDateTime.toLocalDate(), offsetDateTime.truncatedTo(ChronoUnit.DAYS));
testObjectToOffsetDateTime(Date.from(offsetDateTime.toInstant()), offsetDateTime.truncatedTo(ChronoUnit.MILLIS));
try {
testObjectToOffsetDateTime("a string", offsetDateTime);
fail();
} catch (IllegalArgumentException e) {
// expected
}
}
private void testObjectToOffsetDateTime(Object in, OffsetDateTime out) throws Exception {
testConverter(in, out, Object.class, OffsetDateTime.class);
}
@Test
public void testObjectToOffsetTime() throws Exception {
ZoneId zoneId = ZoneId.systemDefault();
OffsetTime offsetTime = OffsetTime.now(zoneId);
testObjectToOffsetTime(null, null);
testObjectToOffsetTime(offsetTime, offsetTime);
testObjectToOffsetTime(offsetTime.atDate(LocalDate.now()), offsetTime);
testObjectToOffsetTime(offsetTime.atDate(LocalDate.now()).atZoneSimilarLocal(zoneId), offsetTime);
testObjectToOffsetTime(offsetTime.atDate(LocalDate.now()).toLocalDateTime(), offsetTime);
testObjectToOffsetTime(offsetTime.atDate(LocalDate.now()).toLocalTime(), offsetTime);
testObjectToOffsetTime(offsetTime.atDate(LocalDate.now()).toInstant(), offsetTime);
testObjectToOffsetTime(Date.from(offsetTime.atDate(LocalDate.now()).toInstant()), offsetTime.truncatedTo(ChronoUnit.MILLIS));
try {
testObjectToOffsetTime("a string", offsetTime);
fail();
} catch (IllegalArgumentException e) {
// expected
}
}
private void testObjectToOffsetTime(Object in, OffsetTime out) throws Exception {
testConverter(in, out, Object.class, OffsetTime.class);
}
@Test
public void testObjectToYear() throws Exception {
ZoneId zoneId = ZoneId.systemDefault();
Date now = new Date();
Year year = Year.from(now.toInstant().atZone(zoneId));
testObjectToYear(null, null);
testObjectToYear(year, year);
testObjectToYear(year.atMonth(6).atEndOfMonth().atTime(1, 0).atZone(zoneId), year);
testObjectToYear(now, year);
testObjectToYear(year.getValue(), year);
try {
testObjectToYear("a string", year);
fail();
} catch (IllegalArgumentException e) {
// expected
}
}
private void testObjectToYear(Object in, Year out) throws Exception {
testConverter(in, out, Object.class, Year.class);
}
@Test
public void testObjectToYearMonth() throws Exception {
ZoneId zoneId = ZoneId.systemDefault();
Date now = new Date();
YearMonth yearMonth = YearMonth.from(now.toInstant().atZone(zoneId));
testObjectToYearMonth(null, null);
testObjectToYearMonth(yearMonth, yearMonth);
testObjectToYearMonth(yearMonth.atEndOfMonth().atTime(1, 0).atZone(zoneId), yearMonth);
testObjectToYearMonth(now, yearMonth);
testObjectToYearMonth(yearMonth.getYear() * 100 + yearMonth.getMonthValue(), yearMonth);
try {
testObjectToYearMonth("a string", yearMonth);
fail();
} catch (IllegalArgumentException e) {
// expected
}
}
private void testObjectToYearMonth(Object in, YearMonth out) throws Exception {
testConverter(in, out, Object.class, YearMonth.class);
}
@Test
public void testObjectToZonedDateTime() throws Exception {
ZoneId zoneId = ZoneId.systemDefault();
ZonedDateTime zonedDateTime = ZonedDateTime.now(zoneId);
testObjectToZonedDateTime(null, null);
testObjectToZonedDateTime(zonedDateTime, zonedDateTime);
testObjectToZonedDateTime(zonedDateTime.toInstant(), zonedDateTime);
testObjectToZonedDateTime(zonedDateTime.toLocalDateTime(), zonedDateTime);
testObjectToZonedDateTime(zonedDateTime.toOffsetDateTime(), zonedDateTime);
testObjectToZonedDateTime(Date.from(zonedDateTime.toInstant()), zonedDateTime.truncatedTo(ChronoUnit.MILLIS));
try {
testObjectToZonedDateTime("a string", zonedDateTime);
fail();
} catch (IllegalArgumentException e) {
// expected
}
}
private void testObjectToZonedDateTime(Object in, ZonedDateTime out) throws Exception {
testConverter(in, out, Object.class, ZonedDateTime.class);
}
@Test
public void testCharacterToTime() throws Exception {
testConvertFromCharSequence(Instant.now(), DateTimeFormatter.ISO_INSTANT);
testConvertFromCharSequence(LocalDate.now(), DateTimeFormatter.ISO_LOCAL_DATE);
testConvertFromCharSequence(LocalDateTime.now(), DateTimeFormatter.ISO_LOCAL_DATE_TIME);
testConvertFromCharSequence(LocalTime.now(), DateTimeFormatter.ISO_LOCAL_TIME);
testConvertFromCharSequence(OffsetDateTime.now(), DateTimeFormatter.ISO_OFFSET_DATE_TIME);
testConvertFromCharSequence(OffsetTime.now(), DateTimeFormatter.ISO_OFFSET_TIME);
testConvertFromCharSequence(Year.now(), DateTimeFormatter.ofPattern("yyyy"));
testConvertFromCharSequence(YearMonth.now(), DateTimeFormatter.ofPattern("yyyy-MM"));
testConvertFromCharSequence(ZonedDateTime.now(), DateTimeFormatter.ISO_ZONED_DATE_TIME);
}
public void testConvertFromCharSequence(Temporal temploral, DateTimeFormatter dateTimeFormatter) throws Exception {
Converter<? super CharSequence, ? extends Temporal> converter =
ConverterService.getInstance().findConverter(CharSequence.class, temploral.getClass(), dateTimeFormatter);
assertEquals(temploral, converter.convert(dateTimeFormatter.format(temploral)));
assertNull(converter.convert(""));
assertNull(converter.convert(null));
DateTimeFormatter failing = DateTimeFormatter.ofPattern("yyyy////dd");
Converter<? super CharSequence, ? extends Temporal> multiConverter =
ConverterService.getInstance().findConverter(CharSequence.class, temploral.getClass(), failing, dateTimeFormatter);
assertEquals(temploral, multiConverter.convert(dateTimeFormatter.format(temploral)));
try {
multiConverter.convert("a");
fail();
} catch (DateTimeParseException e) {
}
}
@Test
public void testTemporalToString() throws Exception {
Converter<? super ZonedDateTime, ? extends CharSequence> converter = ConverterService.getInstance().findConverter(ZonedDateTime.class, CharSequence.class, DateTimeFormatter.ISO_ZONED_DATE_TIME);
ZonedDateTime zonedDateTime = ZonedDateTime.now();
assertEquals(DateTimeFormatter.ISO_ZONED_DATE_TIME.format(zonedDateTime), converter.convert(zonedDateTime));
}
@Test
public void testTemporalToStringNoFormat() throws Exception {
Converter<? super ZonedDateTime, ? extends CharSequence> converter = ConverterService.getInstance().findConverter(ZonedDateTime.class, CharSequence.class);
ZonedDateTime zonedDateTime = ZonedDateTime.now();
assertEquals(zonedDateTime.toString(), converter.convert(zonedDateTime));
}
private Date trunc(Date date) {
Calendar cal = Calendar.getInstance();
cal.setTime(date);
cal.set(Calendar.MILLISECOND, 0);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.HOUR_OF_DAY, 0);
return cal.getTime();
}
}