net.time4j.RoundingOperator Maven / Gradle / Ivy
/*
* -----------------------------------------------------------------------
* Copyright © 2013-2015 Meno Hochschild,
* -----------------------------------------------------------------------
* This file (RoundingOperator.java) is part of project Time4J.
*
* Time4J 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.
*
* Time4J 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 Time4J. If not, see .
* -----------------------------------------------------------------------
*/
package net.time4j;
import net.time4j.engine.ChronoEntity;
import net.time4j.engine.ChronoOperator;
/**
* Rundungsoperator.
*
* @author Meno Hochschild
*/
final class RoundingOperator>
implements ChronoOperator {
//~ Instanzvariablen --------------------------------------------------
private final ProportionalElement, T> element;
private final Boolean up;
private final double stepwidth;
private final boolean longBased;
//~ Konstruktoren -----------------------------------------------------
/**
* Konstruktor.
*
* @param element referencing element
* @param up {@code Boolean.TRUE} if ceiling mode,
* {@code null} if half rounding
* {@code Boolean.FALSE} if floor mode
* @param stepwidth controls limits of rounding
*/
RoundingOperator(
final ProportionalElement, T> element,
Boolean up,
int stepwidth
) {
super();
this.element = element;
this.up = up;
this.stepwidth = stepwidth;
this.longBased = element.getType().equals(Long.class);
}
//~ Methoden ----------------------------------------------------------
@Override
public T apply(T entity) {
double value = entity.get(this.element).doubleValue();
double nv;
if (this.up == null) {
double high = Math.ceil(value / this.stepwidth) * this.stepwidth;
double low = Math.floor(value / this.stepwidth) * this.stepwidth;
nv = ((value - low < high - value) ? low : high);
} else if (this.up.booleanValue()) {
nv = Math.ceil(value / this.stepwidth) * this.stepwidth;
} else {
nv = Math.floor(value / this.stepwidth) * this.stepwidth;
}
Number num;
if (this.longBased) {
num = Long.valueOf((long) nv);
} else {
num = Integer.valueOf((int) nv);
}
return entity.with(lenient(this.element, num));
}
private static >
ChronoOperator lenient(
ProportionalElement element,
Number num
) {
return element.setLenient(element.getType().cast(num));
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy