DateTimeComponents.java

  1. /* Copyright 2002-2013 CS Systèmes d'Information
  2.  * Licensed to CS Systèmes d'Information (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.time;

  18. import java.io.Serializable;

  19. import org.apache.commons.math3.util.FastMath;
  20. import org.orekit.utils.Constants;

  21. /** Holder for date and time components.
  22.  * <p>This class is a simple holder with no processing methods.</p>
  23.  * <p>Instance of this class are guaranteed to be immutable.</p>
  24.  * @see AbsoluteDate
  25.  * @see DateComponents
  26.  * @see TimeComponents
  27.  * @author Luc Maisonobe
  28.  */
  29. public class DateTimeComponents implements Serializable, Comparable<DateTimeComponents> {

  30.     /** Serializable UID. */
  31.     private static final long serialVersionUID = 5061129505488924484L;

  32.     /** Date component. */
  33.     private final DateComponents date;

  34.     /** Time component. */
  35.     private final TimeComponents time;

  36.     /** Build a new instance from its components.
  37.      * @param date date component
  38.      * @param time time component
  39.      */
  40.     public DateTimeComponents(final DateComponents date, final TimeComponents time) {
  41.         this.date = date;
  42.         this.time = time;
  43.     }

  44.     /** Build an instance from raw level components.
  45.      * @param year year number (may be 0 or negative for BC years)
  46.      * @param month month number from 1 to 12
  47.      * @param day day number from 1 to 31
  48.      * @param hour hour number from 0 to 23
  49.      * @param minute minute number from 0 to 59
  50.      * @param second second number from 0.0 to 60.0 (excluded)
  51.      * @exception IllegalArgumentException if inconsistent arguments
  52.      * are given (parameters out of range, february 29 for non-leap years,
  53.      * dates during the gregorian leap in 1582 ...)
  54.      */
  55.     public DateTimeComponents(final int year, final int month, final int day,
  56.                               final int hour, final int minute, final double second)
  57.         throws IllegalArgumentException {
  58.         this.date = new DateComponents(year, month, day);
  59.         this.time = new TimeComponents(hour, minute, second);
  60.     }

  61.     /** Build an instance from raw level components.
  62.      * @param year year number (may be 0 or negative for BC years)
  63.      * @param month month enumerate
  64.      * @param day day number from 1 to 31
  65.      * @param hour hour number from 0 to 23
  66.      * @param minute minute number from 0 to 59
  67.      * @param second second number from 0.0 to 60.0 (excluded)
  68.      * @exception IllegalArgumentException if inconsistent arguments
  69.      * are given (parameters out of range, february 29 for non-leap years,
  70.      * dates during the gregorian leap in 1582 ...)
  71.      */
  72.     public DateTimeComponents(final int year, final Month month, final int day,
  73.                               final int hour, final int minute, final double second)
  74.         throws IllegalArgumentException {
  75.         this.date = new DateComponents(year, month, day);
  76.         this.time = new TimeComponents(hour, minute, second);
  77.     }

  78.     /** Build an instance from raw level components.
  79.      * <p>The hour is set to 00:00:00.000.</p>
  80.      * @param year year number (may be 0 or negative for BC years)
  81.      * @param month month number from 1 to 12
  82.      * @param day day number from 1 to 31
  83.      * @exception IllegalArgumentException if inconsistent arguments
  84.      * are given (parameters out of range, february 29 for non-leap years,
  85.      * dates during the gregorian leap in 1582 ...)
  86.      */
  87.     public DateTimeComponents(final int year, final int month, final int day)
  88.         throws IllegalArgumentException {
  89.         this.date = new DateComponents(year, month, day);
  90.         this.time = TimeComponents.H00;
  91.     }

  92.     /** Build an instance from raw level components.
  93.      * <p>The hour is set to 00:00:00.000.</p>
  94.      * @param year year number (may be 0 or negative for BC years)
  95.      * @param month month enumerate
  96.      * @param day day number from 1 to 31
  97.      * @exception IllegalArgumentException if inconsistent arguments
  98.      * are given (parameters out of range, february 29 for non-leap years,
  99.      * dates during the gregorian leap in 1582 ...)
  100.      */
  101.     public DateTimeComponents(final int year, final Month month, final int day)
  102.         throws IllegalArgumentException {
  103.         this.date = new DateComponents(year, month, day);
  104.         this.time = TimeComponents.H00;
  105.     }

  106.     /** Build an instance from a seconds offset with respect to another one.
  107.      * @param reference reference date/time
  108.      * @param offset offset from the reference in seconds
  109.      * @see #offsetFrom(DateTimeComponents)
  110.      */
  111.     public DateTimeComponents(final DateTimeComponents reference,
  112.                               final double offset) {

  113.         // extract linear data from reference date/time
  114.         int    day     = reference.getDate().getJ2000Day();
  115.         double seconds = reference.getTime().getSecondsInDay();

  116.         // apply offset
  117.         seconds += offset;

  118.         // fix range
  119.         final int dayShift = (int) FastMath.floor(seconds / Constants.JULIAN_DAY);
  120.         seconds -= Constants.JULIAN_DAY * dayShift;
  121.         day     += dayShift;

  122.         // set up components
  123.         this.date = new DateComponents(day);
  124.         this.time = new TimeComponents(seconds);

  125.     }

  126.     /** Parse a string in ISO-8601 format to build a date/time.
  127.      * <p>The supported formats are all date formats supported by {@link DateComponents#parseDate(String)}
  128.      * and all time formats supported by {@link TimeComponents#parseTime(String)} separated
  129.      * by the standard time separator 'T', or date components only (in which case a 00:00:00 hour is
  130.      * implied). Typical examples are 2000-01-01T12:00:00Z or 1976W186T210000.
  131.      * </p>
  132.      * @param string string to parse
  133.      * @return a parsed date/time
  134.      * @exception IllegalArgumentException if string cannot be parsed
  135.      */
  136.     public static DateTimeComponents parseDateTime(final String string) {

  137.         // is there a time ?
  138.         final int tIndex = string.indexOf('T');
  139.         if (tIndex > 0) {
  140.             return new DateTimeComponents(DateComponents.parseDate(string.substring(0, tIndex)),
  141.                                           TimeComponents.parseTime(string.substring(tIndex + 1)));
  142.         }

  143.         return new DateTimeComponents(DateComponents.parseDate(string), TimeComponents.H00);

  144.     }

  145.     /** Compute the seconds offset between two instances.
  146.      * @param dateTime dateTime to subtract from the instance
  147.      * @return offset in seconds between the two instants
  148.      * (positive if the instance is posterior to the argument)
  149.      * @see #DateTimeComponents(DateTimeComponents, double)
  150.      */
  151.     public double offsetFrom(final DateTimeComponents dateTime) {
  152.         final int dateOffset = date.getJ2000Day() - dateTime.date.getJ2000Day();
  153.         final double timeOffset = time.getSecondsInDay() - dateTime.time.getSecondsInDay();
  154.         return Constants.JULIAN_DAY * dateOffset + timeOffset;
  155.     }

  156.     /** Get the date component.
  157.      * @return date component
  158.      */
  159.     public DateComponents getDate() {
  160.         return date;
  161.     }

  162.     /** Get the time component.
  163.      * @return time component
  164.      */
  165.     public TimeComponents getTime() {
  166.         return time;
  167.     }

  168.     /** {@inheritDoc} */
  169.     public int compareTo(final DateTimeComponents other) {
  170.         final int dateComparison = date.compareTo(other.date);
  171.         if (dateComparison < 0) {
  172.             return -1;
  173.         } else if (dateComparison > 0) {
  174.             return 1;
  175.         }
  176.         return time.compareTo(other.time);
  177.     }

  178.     /** {@inheritDoc} */
  179.     public boolean equals(final Object other) {
  180.         try {
  181.             final DateTimeComponents otherDateTime = (DateTimeComponents) other;
  182.             return (otherDateTime != null) &&
  183.                    date.equals(otherDateTime.date) && time.equals(otherDateTime.time);
  184.         } catch (ClassCastException cce) {
  185.             return false;
  186.         }
  187.     }

  188.     /** {@inheritDoc} */
  189.     public int hashCode() {
  190.         return (date.hashCode() << 16) ^ time.hashCode();
  191.     }

  192.     /** Return a string representation of this pair.
  193.      * <p>The format used is ISO8601.</p>
  194.      * @return string representation of this pair
  195.      */
  196.     public String toString() {
  197.         return date.toString() + 'T' + time.toString();
  198.     }

  199. }