/*
* Copyright (c) 2017 OBiBa. All rights reserved.
*
* This program and the accompanying materials
* are made available under the terms of the GNU Public License v3.0.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.obiba.magma.type;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.TimeZone;
import org.junit.Test;
import org.obiba.magma.Value;
import org.obiba.magma.ValueType;
import com.google.common.collect.ImmutableList;
import static org.fest.assertions.api.Assertions.assertThat;
public class DateTimeTypeTest extends BaseValueTypeTest {
@Override
ValueType getValueType() {
return DateTimeType.get();
}
@Override
Object getObjectForType() {
return new Date();
}
@Override
boolean isDateTime() {
return true;
}
@Override
boolean isNumeric() {
return false;
}
@Override
Iterable<Class<?>> validClasses() {
return ImmutableList.<Class<?>>of(Date.class, Timestamp.class, Calendar.class);
}
@Test
public void testValueOfSqlDateInstance() {
DateTimeType dt = DateTimeType.get();
assertThat(dt.acceptsJavaClass(java.sql.Date.class)).isTrue();
Date dateValue = new Date();
Value value = dt.valueOf(new java.sql.Date(dateValue.getTime()));
assertThat(dateValue).isEqualTo((Date) value.getValue());
// Make sure the type was normalized
assertThat(value.getValue().getClass().equals(dt.getJavaClass())).isTrue();
}
@Test
public void testValueOfSqlTimestampInstance() {
DateTimeType dt = DateTimeType.get();
assertThat(dt.acceptsJavaClass(Timestamp.class)).isTrue();
Date dateValue = new Date();
Value value = dt.valueOf(new Timestamp(dateValue.getTime()));
assertThat(dateValue).isEqualTo((Date) value.getValue());
// Make sure the type was normalized
assertThat(value.getValue().getClass().equals(dt.getJavaClass())).isTrue();
}
@Test
public void testValueOfCalendarInstance() {
DateTimeType dt = DateTimeType.get();
assertThat(dt.acceptsJavaClass(Calendar.class)).isTrue();
assertThat(dt.acceptsJavaClass(GregorianCalendar.class)).isTrue();
Calendar calendar = GregorianCalendar.getInstance();
Date dateValue = calendar.getTime();
Value value = dt.valueOf(calendar);
assertThat(dateValue).isEqualTo((Date) value.getValue());
}
@Test
public void test_valueOfISODateFormatString() {
assertValueOfUsingDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ");
}
@Test
public void test_valueOfISODateFormatNoMillisecondsString() {
// seconds precision
assertValueOfUsingDateFormat("yyyy-MM-dd'T'HH:mm:ssZ", 1000);
}
@Test
public void test_valueOfISODateFormatNoSecondsString() {
// minutes precision
assertValueOfUsingDateFormat("yyyy-MM-dd'T'HH:mmZ", 1000 * 60);
}
@Test
public void test_valueOfIncorrectISODateFormatString() {
assertValueOfUsingDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSzzz");
}
@Test
public void test_valueOfNoTimeZoneDateFormatString() {
Calendar expected = Calendar.getInstance();
expected.clear();
expected.set(2011, Calendar.JANUARY, 25, 14, 30, 47);
Value value = DateTimeType.get().valueOf("2011-01-25 14:30:47");
assertThat(new Date(expected.getTimeInMillis())).isEqualTo((Date) value.getValue());
}
@Test
public void test_valueOfNoTimeZoneDateFormatStringNoSeconds() {
Calendar expected = Calendar.getInstance();
expected.clear();
expected.set(2011, Calendar.JANUARY, 25, 14, 30);
Value value = DateTimeType.get().valueOf("2011-01-25 14:30");
assertThat(new Date(expected.getTimeInMillis())).isEqualTo((Date) value.getValue());
}
@Test
public void test_valueOfNoTimeZoneSlashDateFormatStringNoSeconds() {
Calendar expected = Calendar.getInstance();
expected.clear();
expected.set(2011, Calendar.JANUARY, 25, 14, 30);
Value value = DateTimeType.get().valueOf("2011/01/25 14:30");
assertThat(new Date(expected.getTimeInMillis())).isEqualTo((Date) value.getValue());
}
@Test
public void test_valueOfThatIncludesZuluTimezone() {
Calendar expected = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
expected.clear();
expected.set(2011, Calendar.JANUARY, 25, 14, 30, 47);
Value value = DateTimeType.get().valueOf("2011-01-25T14:30:47Z");
assertThat(new Date(expected.getTimeInMillis())).isEqualTo((Date) value.getValue());
}
@Test
public void test_iso8601TimeZone() {
Calendar expected = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
expected.clear();
expected.set(2011, Calendar.JANUARY, 25, 14, 30, 47);
Value value = DateTimeType.get().valueOf("2011-01-25T14:30:47+00:00");
assertThat(new Date(expected.getTimeInMillis())).isEqualTo((Date) value.getValue());
}
private void assertValueOfUsingDateFormat(String dateFormat) {
assertValueOfUsingDateFormat(dateFormat, 0);
}
private void assertValueOfUsingDateFormat(String dateFormat, int precision) {
Date dateValue = new Date();
Value value = getValueType().valueOf(new SimpleDateFormat(dateFormat).format(dateValue));
if(precision == 0) {
assertThat(dateValue).isEqualTo((Date) value.getValue());
} else {
// asserts that times are equivalent within "precision" from each other
assertThat(Math.abs(dateValue.getTime() - ((Date) value.getValue()).getTime()) < precision).isTrue();
}
}
}