blob: 7bb5380aa6898093815df276992e5ce322524933 [file]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.beanutils2.converters;
import static org.junit.jupiter.api.Assertions.assertEquals;
import java.sql.Timestamp;
import java.util.Calendar;
import java.util.Date;
import org.junit.jupiter.api.Test;
/**
* Test Case for the DateConverter class.
*/
class DateConverterTest extends AbstractDateConverterTest<Date> {
/**
* Gets the expected type
*
* @return The expected type
*/
@Override
protected Class<Date> getExpectedType() {
return Date.class;
}
/**
* Create the Converter with no default value.
*
* @return A new Converter
*/
@Override
protected DateConverter makeConverter() {
return new DateConverter();
}
/**
* Create the Converter with a default value.
*
* @param defaultValue The default value
* @return A new Converter
*/
@Override
protected DateConverter makeConverter(final Date defaultValue) {
return new DateConverter(defaultValue);
}
/**
* Convert from a Calendar to the appropriate Date type
*
* @param value The Calendar value to convert
* @return The converted value
*/
@Override
protected Date toType(final Calendar value) {
return value.getTime();
}
/**
* A pre-epoch {@link Timestamp} carries a non-negative sub-second part in {@code getNanos()}, so decomposing
* {@code getTime()} into whole seconds must floor: integer division truncates toward zero for negative values and
* gains a whole second.
*/
@Test
void testConvertPreEpochSqlTimestamp() {
// 1969-12-31T23:59:59.500Z: getTime() == -500, getNanos() == 500_000_000
final Timestamp timestamp = new Timestamp(-500L);
assertEquals(-500L, makeConverter().convert(getExpectedType(), timestamp).getTime());
}
/**
* For {@code getTime()} in {@code [Long.MIN_VALUE, Long.MIN_VALUE + 807]} the whole-second term
* {@code Math.floorDiv(getTime(), 1000) * 1000} wraps around {@link Long#MIN_VALUE}, but adding the non-negative
* {@code getNanos() / 1_000_000} wraps it back: the two terms reconstruct {@code getTime()} exactly in
* two's-complement arithmetic, so no overflow guard is needed.
*/
@Test
void testConvertExtremePreEpochSqlTimestamp() {
assertEquals(Long.MIN_VALUE, makeConverter().convert(getExpectedType(), new Timestamp(Long.MIN_VALUE)).getTime());
// last value whose whole-second term still wraps
assertEquals(Long.MIN_VALUE + 807, makeConverter().convert(getExpectedType(), new Timestamp(Long.MIN_VALUE + 807)).getTime());
}
}