DateTimeOffsetType.java
/*
*
* The DbUnit Database Testing Framework
* Copyright (C)2002-2019, DbUnit.org
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
package org.dbunit.ext.mssql;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.time.DateTimeException;
import java.time.OffsetDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
import java.time.temporal.TemporalAccessor;
import org.dbunit.dataset.datatype.AbstractDataType;
import org.dbunit.dataset.datatype.TypeCastException;
/**
* @author Richard DiCroce
* @since 2.7.0
*/
public class DateTimeOffsetType extends AbstractDataType
{
public static final int TYPE = -155;
/** @see https://docs.microsoft.com/en-us/sql/t-sql/data-types/datetimeoffset-transact-sql?view=sql-server-2017 */
private static final DateTimeFormatter SQL_SERVER_FORMAT =
DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss[.n] xxx");
public DateTimeOffsetType()
{
super("datetimeoffset", TYPE, OffsetDateTime.class, false);
}
@Override
public Object typeCast(final Object value) throws TypeCastException
{
if (value == null || value instanceof OffsetDateTime)
{
return value;
}
// if a java.time type, attempt a direct conversion
// if that fails, there's not enough info to do the conversion, so don't
// bother trying string parse
if (value instanceof TemporalAccessor)
{
try
{
return OffsetDateTime.from((TemporalAccessor) value);
} catch (final DateTimeException e)
{
throw new TypeCastException(e);
}
}
final String valueAsString = value.toString();
// attempt to parse using ISO 8601 format
DateTimeParseException isoParseException;
try
{
return OffsetDateTime.parse(valueAsString);
} catch (final DateTimeParseException e)
{
isoParseException = e;
}
// attempt to parse using SQL Server's ISO-like format
try
{
return OffsetDateTime.parse(valueAsString, SQL_SERVER_FORMAT);
} catch (final DateTimeParseException e)
{
final TypeCastException toThrow = new TypeCastException(
"Could not parse value using ISO 8601 or SQL Server's format",
e);
toThrow.addSuppressed(isoParseException);
throw toThrow;
}
}
@Override
public Object getSqlValue(final int column, final ResultSet resultSet)
throws SQLException, TypeCastException
{
return resultSet.getObject(column, OffsetDateTime.class);
}
@Override
public void setSqlValue(final Object value, final int column,
final PreparedStatement statement)
throws SQLException, TypeCastException
{
statement.setObject(column, typeCast(value));
}
@Override
public boolean isDateTime()
{
return true;
}
}