AccurateFormatter.java
/* Copyright 2002-2025 CS GROUP
* Licensed to CS GROUP (CS) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* CS 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
*
* http://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.orekit.utils;
import org.hipparchus.util.RyuDouble;
/** Formatter used to produce strings from data with high accuracy.
* <p>
* When producing test output from computed data, we want the shortest
* decimal representation of a floating point number that maintains
* round-trip safety. That is, a correct parser can recover the exact
* original number.
* </p>
* <p>
* For efficiency, this class uses the {@link RyuDouble Ryƫ} algorithm
* for producing shortest string representation with round-trip safety.
* </p>
* @author Luc Maisonobe
* @since 11.0
*/
public class AccurateFormatter implements Formatter {
/** Low switch level for exponential format in dates (will never be reached due to {@link #LOW_TRUNCATION}). */
private static final int LOW_EXP = -18;
/** Truncation level for seconds, to avoid scientific format. */
private static final double LOW_TRUNCATION = 1.0e-15;
/** Public constructor.
*/
public AccurateFormatter() {
// nothing to do
}
/** Formats to full accuracy.
* {@inheritDoc}
*/
@Override
public String toString(final double value) {
return format(value);
}
/** Formats the seconds variable with maximum precision needed.
* {@inheritDoc}
*/
@Override
public String toString(final int year, final int month, final int day,
final int hour, final int minute, final double seconds) {
return format(year, month, day, hour, minute, seconds);
}
/** Format a date.
* @param year year
* @param month month
* @param day day
* @param hour hour
* @param minute minute
* @param seconds seconds
* @return date formatted to full accuracy
* @deprecated As of 13.0, because static method does not utilize inheritance benefits from {@link Formatter} and
* does not check format standards of date time. Use {@link #toString(int, int, int, int, int, double)} instead.
*/
@Deprecated
public static String format(final int year, final int month, final int day,
final int hour, final int minute, final double seconds) {
final double truncated = seconds < LOW_TRUNCATION ? 0.0 : seconds;
final String s = RyuDouble.doubleToString(truncated, LOW_EXP, RyuDouble.DEFAULT_HIGH_EXP);
return String.format(STANDARDIZED_LOCALE, DATE_FORMAT,
year, month, day,
hour, minute, s.charAt(1) == '.' ? "0" + s : s);
}
/** Format a double number.
* @param value number to format
* @return number formatted to full accuracy
* @deprecated As of 13.0, because Static method does not utilize inheritance benefits from {@link Formatter}.
* Use {@link #toString(double)} instead.
*/
@Deprecated
public static String format(final double value) {
return RyuDouble.doubleToString(value);
}
}