1   /* Contributed in the public domain.
2    * Licensed to CS GROUP (CS) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * CS licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *   http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.orekit.utils;
18  
19  import java.math.RoundingMode;
20  import java.text.DecimalFormat;
21  import java.text.NumberFormat;
22  
23  /** Formatter used to produce strings from data that are compliant with CCSDS standards.
24   * <p>
25   * Formats a double number to achieve CCSDS formatting standards for: OPM, OMM, OEM, or OCM (502.0-B-3 7.5.6),
26   * CDM (508.0-B-1 6.3.2.2), TDM (503.0-B-2 4.3.4), and ADM (504.0-B-2 6.8.4.1).
27   * This states that the mantissa shall not exceed 16 digits.
28   * </p>
29   * <p>
30   * This does NOT ensure round-trip safety. See {@link AccurateFormatter} for a formatter that ensures round trip safety.
31   * </p>
32   * @author John Ajamian
33   * @since 13.0
34   */
35  public class TruncatedCcsdsFormatter implements Formatter {
36  
37      /** Maximum digits allowed by CCSDS standards. */
38      private static final int MAXIMUM_ODM_DIGITS = 16;
39  
40      /** Used to format double to be compliant with CCSDS standards. */
41      private static final String CCSDS_FORMAT = "0.0##############E0##";
42  
43      /** Used to make sure seconds is only 16 digits. */
44      private static final String SECOND_FORMAT = "00.0#############";
45  
46      /** Public constructor.
47       */
48      public TruncatedCcsdsFormatter() {
49          // nothing to do
50      }
51  
52      /** Format a double number. Formats to CCSDS compliant standards.
53       * @param value number to format
54       * @return number formatted to full accuracy or CCSDS standards
55       */
56      @Override
57      public String toString(final double value) {
58          final DecimalFormat formatter = (DecimalFormat) NumberFormat.getInstance(STANDARDIZED_LOCALE);
59          formatter.applyLocalizedPattern(CCSDS_FORMAT);
60          formatter.setRoundingMode(RoundingMode.HALF_UP);
61          formatter.setMaximumFractionDigits(MAXIMUM_ODM_DIGITS - 1);
62          return formatter.format(value);
63      }
64  
65      /** Formats to CCSDS 16 digit standard for the seconds variable.
66       * {@inheritDoc}
67       */
68      @Override
69      public String toString(final int year, final int month, final int day,
70                             final int hour, final int minute, final double seconds) {
71  
72          final DecimalFormat formatter = (DecimalFormat) NumberFormat.getInstance(STANDARDIZED_LOCALE);
73          formatter.applyLocalizedPattern(SECOND_FORMAT);
74          formatter.setRoundingMode(RoundingMode.DOWN);
75          formatter.setMaximumFractionDigits(MAXIMUM_ODM_DIGITS - 2);
76          formatter.setMinimumIntegerDigits(2);
77  
78          return String.format(STANDARDIZED_LOCALE, DATE_FORMAT,
79                  year, month, day,
80                  hour, minute, formatter.format(seconds));
81      }
82  }