Пример #1
0
        /// <summary>
        /// Returns the difference TAI - UTC as of the given date, in seconds.
        /// </summary>
        /// <param name="date">The date.</param>
        /// <returns>The difference.</returns>
        public double GetTaiMinusUtc(JulianDate date)
        {
            LeapSecond toFind = new LeapSecond(date, 0.0);

            // Start by assuming we're working with UTC, we'll check later if we're
            // off by one because we really have TAI.
            int index = m_leapSeconds.BinarySearch(toFind, s_compareLeapSecondDate);

            if (index < 0)
            {
                index = ~index;
                --index;
            }

            // Check if we're off by one because we're really working with TAI.
            // If the requested date minus the most recent previous leap second offset is less than the date
            // for the current leap second, then we haven't quite gotten to that leap second yet.
            // This gets a little tricky because JulianDate and its conversion mechanisms try to outsmart us.
            if (date.Standard == TimeStandard.InternationalAtomicTime)
            {
                JulianDate lastDate  = GetDateForIndex(index);
                JulianDate taiCutoff = new JulianDate(lastDate.Day, lastDate.SecondsOfDay, TimeStandard.InternationalAtomicTime);
                taiCutoff += Duration.FromSeconds(GetOffsetForIndex(index));
                if (date < taiCutoff)
                {
                    --index;
                }
            }

            return(GetOffsetForIndex(index));
        }
Пример #2
0
        /// <summary>
        /// Try to convert <paramref name="date"/> from TAI to UTC, if possible.
        /// </summary>
        /// <param name="date">The date, which must be in the TAI
        /// <see cref="TimeStandard"/>.</param>
        /// <param name="result">Out parameter for returning the resulting UTC
        /// <see cref="JulianDate"/>, if it was possible to convert.</param>
        /// <returns><see langword="true"/> if <paramref name="date"/> could be converted
        /// to UTC, otherwise false.</returns>
        internal bool TryConvertTaiToUtc(JulianDate date, out JulianDate result)
        {
            //treat the request date as if it were UTC, and search for the most recent leap second.
            LeapSecond toFind = new LeapSecond(date, 0.0);
            int        index  = m_leapSeconds.BinarySearch(toFind, s_compareLeapSecondDate);

            if (index < 0)
            {
                index = ~index;
                --index;
            }

            //now we have the index of the most recent leap second that is after the requested date
            if (index >= 0)
            {
                double     mostRecentOffset = GetOffsetForIndex(index);
                JulianDate leapSecondDate   = GetDateForIndex(index);

                if (date.Day == leapSecondDate.Day)
                {
                    //if the requested date is on the day of the leap second, we may have to adjust
                    double secondsSinceLeapSecond = date.SecondsOfDay - leapSecondDate.SecondsOfDay;

                    if (secondsSinceLeapSecond >= mostRecentOffset - 1 &&
                        secondsSinceLeapSecond < mostRecentOffset)
                    {
                        //if the requested date is during the moment of a leap second, then we cannot convert to UTC.
                        result = JulianDate.MinValue;
                        return(false);
                    }

                    if (secondsSinceLeapSecond < mostRecentOffset)
                    {
                        //The leap second we found is actually after the desired date, as a result of simply treating the
                        //TAI date as if it were UTC.  So, use the next previous leap second instead.
                        --index;
                    }
                }
            }

            result = new JulianDate(date.Day, date.SecondsOfDay - GetOffsetForIndex(index), TimeStandard.CoordinatedUniversalTime);
            return(true);
        }
Пример #3
0
        /// <summary>
        /// Determines if a given day contains a leap second.
        /// </summary>
        /// <param name="julianDayNumber">The day, specified as a Julian day number.</param>
        /// <returns>true if the day contains a leap second, otherwise false.</returns>
        public bool DoesDayHaveLeapSecond(int julianDayNumber)
        {
            LeapSecond potentialLeapSecond = new LeapSecond(new JulianDate(julianDayNumber, 43200, TimeStandard.CoordinatedUniversalTime), 0.0);

            return(m_leapSeconds.BinarySearch(potentialLeapSecond, s_compareLeapSecondDate) >= 0);
        }