1682 lines · 77.0 KB · C#
RawDownload
//******************************************************************************************************//  Ticks.cs - Gbtc////  Copyright © 2014, Grid Protection Alliance.  All Rights Reserved.////  Licensed to the Grid Protection Alliance (GPA) under one or more contributor license agreements. See//  the NOTICE file distributed with this work for additional information regarding copyright ownership.//  The GPA licenses this file to you under the MIT License (MIT), 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.opensource.org/licenses/MIT////  Unless agreed to in writing, the subject software distributed under the License is distributed on an//  "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the//  License for the specific language governing permissions and limitations.////  Code Modification History://  ----------------------------------------------------------------------------------------------------//  11/12/2004 - J. Ritchie Carroll//       Initial version of source generated.//  08/04/2009 - Josh L. Patterson//       Edited Code Comments.//  09/14/2009 - Stephen C. Wills//       Added new header and license agreement.//  12/14/2012 - Starlynn Danyelle Gilliam//       Modified Header.//  02/16/2014 - Steven E. Chisholm//       In-lined a large portion of the smaller methods. Also fixed errors //       in Equals(object) and CompareTo(object)//  02/18/2014 - J. Ritchie Carroll//       Added sub-second distribution functions for common use.////****************************************************************************************************** #region [ Contributor License Agreements ] /**************************************************************************\   Copyright © 2009 - J. Ritchie Carroll   All rights reserved.     Redistribution and use in source and binary forms, with or without   modification, are permitted provided that the following conditions   are met:        * Redistributions of source code must retain the above copyright        notice, this list of conditions and the following disclaimer.             * Redistributions in binary form must reproduce the above        copyright notice, this list of conditions and the following        disclaimer in the documentation and/or other materials provided        with the distribution.     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER "AS IS" AND ANY   EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR   PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY   OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.  \**************************************************************************/ #endregion using System;using System.ComponentModel;using System.Globalization;using System.Linq;using System.Runtime.CompilerServices;using GSF.Units; namespace GSF{    #region [ Enumerations ]     /// <summary>    /// Time intervals enumeration used by <see cref="Ticks.BaselinedTimestamp"/> method.    /// </summary>    public enum BaselineTimeInterval    {        /// <summary>        /// Baseline timestamp to the second (i.e., starting at zero milliseconds).        /// </summary>        Second,        /// <summary>        /// Baseline timestamp to the minute (i.e., starting at zero seconds and milliseconds).        /// </summary>        Minute,        /// <summary>        /// Baseline timestamp to the hour (i.e., starting at zero minutes, seconds and milliseconds).        /// </summary>        Hour,        /// <summary>        /// Baseline timestamp to the day (i.e., starting at zero hours, minutes, seconds and milliseconds).        /// </summary>        Day,        /// <summary>        /// Baseline timestamp to the month (i.e., starting at day one, zero hours, minutes, seconds and milliseconds).        /// </summary>        Month,        /// <summary>        /// Baseline timestamp to the year (i.e., starting at month one, day one, zero hours, minutes, seconds and milliseconds).        /// </summary>        Year    }     #endregion     /// <summary>    /// Represents an instant in time, or time period, as a 64-bit signed integer with a value that is expressed as the number    /// of 100-nanosecond intervals that have elapsed since 12:00:00 midnight, January 1, 0001.    /// </summary>    /// <remarks>    /// <para>    /// <see cref="Ticks"/> can represent an "instant in time" and therefore can be used exactly like a <see cref="DateTime"/>.    /// The difference between <see cref="Ticks"/> and <see cref="DateTime"/> is that <see cref="Ticks"/> is essentially a long    /// integer (i.e., an <see cref="Int64"/>) which represents the number of ticks that have elapsed since 12:00:00 midnight,    /// January 1, 0001 with each tick having a resolution of 100-nanoseconds. You would use <see cref="Ticks"/> in places where    /// you needed to directly represent time in high-resolution, i.e., time with sub-second accuracy, using an object that will    /// act like a long integer but handle time conversions. <see cref="Ticks"/> can also represent a "time period" (e.g., the    /// number of ticks elapsed since a process started) and thus can also be used like a <see cref="TimeSpan"/>; when used in    /// this manner the <see cref="Ticks.ToElapsedTimeString()"/> method can be used to convert the <see cref="Ticks"/> value    /// into a handy textual representation of elapsed years, days, hours, minutes and seconds or sub-seconds.    /// </para>    /// <para>    /// This class behaves just like an <see cref="Int64"/> representing a time in ticks; it is implicitly castable to and from    /// an <see cref="Int64"/> and therefore can be generally used "as" an Int64 directly. It is also implicitly castable to and    /// from a <see cref="DateTime"/>, a <see cref="TimeSpan"/>, an <see cref="NtpTimeTag"/> and a <see cref="UnixTimeTag"/>.    /// </para>    /// </remarks>    // ReSharper disable RedundantNameQualifier    [Serializable]    public struct Ticks : IComparable, IFormattable, IConvertible, IComparable<Ticks>, IComparable<Int64>, IComparable<DateTime>, IComparable<TimeSpan>, IEquatable<Ticks>, IEquatable<Int64>, IEquatable<DateTime>, IEquatable<TimeSpan>    {        #region [ Members ]         // Constants         /// <summary>        /// Number of 100-nanosecond ticks in one second.        /// </summary>        public const long PerSecond = 10000000L;         /// <summary>        /// Number of 100-nanosecond ticks in one millisecond.        /// </summary>        public const long PerMillisecond = (long)(Ticks.PerSecond * SI.Milli);         /// <summary>        /// Number of 100-nanosecond ticks in one microsecond.        /// </summary>        public const long PerMicrosecond = (long)(Ticks.PerSecond * SI.Micro);         /// <summary>        /// Number of 100-nanosecond ticks in one minute.        /// </summary>        public const long PerMinute = 60L * Ticks.PerSecond;         /// <summary>        /// Number of 100-nanosecond ticks in one hour.        /// </summary>        public const long PerHour = 60L * Ticks.PerMinute;         /// <summary>        /// Number of 100-nanosecond ticks in one day.        /// </summary>        public const long PerDay = 24L * Ticks.PerHour;         // Fields         /// <summary>        /// Time value stored in ticks.        /// </summary>        public readonly long Value;         #endregion         #region [ Constructors ]         /// <summary>        /// Creates a new <see cref="Ticks"/>.        /// </summary>        /// <param name="value">New time value in ticks.</param>        public Ticks(long value)        {            Value = value;        }         /// <summary>        /// Creates a new <see cref="Ticks"/>.        /// </summary>        /// <param name="value">New time value as a <see cref="DateTime"/>.</param>        public Ticks(DateTime value)        {            Value = value.Ticks;        }         /// <summary>        /// Creates a new <see cref="Ticks"/>.        /// </summary>        /// <param name="value">New time value as a <see cref="TimeSpan"/>.</param>        public Ticks(TimeSpan value)        {            Value = value.Ticks;        }         #endregion         #region [ Methods ]         /// <summary>        /// Gets the <see cref="Ticks"/> value in equivalent number of days.        /// </summary>        /// <returns>Value of <see cref="Ticks"/> in days.</returns>        /// <remarks>        /// If <see cref="Ticks"/> value represents an instant in time, returned value will represent the number of days        /// that have elapsed since 12:00:00 midnight, January 1, 0001.        /// </remarks>        public double ToDays()        {            return ToSeconds() / Time.SecondsPerDay;        }         /// <summary>        /// Gets the <see cref="Ticks"/> value in equivalent number of hours.        /// </summary>        /// <returns>Value of <see cref="Ticks"/> in hours.</returns>        /// <remarks>        /// If <see cref="Ticks"/> value represents an instant in time, returned value will represent the number of hours        /// that have elapsed since 12:00:00 midnight, January 1, 0001.        /// </remarks>        public double ToHours()        {            return ToSeconds() / Time.SecondsPerHour;        }         /// <summary>        /// Gets the <see cref="Ticks"/> value in equivalent number of minutes.        /// </summary>        /// <returns>Value of <see cref="Ticks"/> in minutes.</returns>        /// <remarks>        /// If <see cref="Ticks"/> value represents an instant in time, returned value will represent the number of minutes        /// that have elapsed since 12:00:00 midnight, January 1, 0001.        /// </remarks>        public double ToMinutes()        {            return ToSeconds() / Time.SecondsPerMinute;        }         /// <summary>        /// Gets the <see cref="Ticks"/> value in equivalent number of seconds.        /// </summary>        /// <returns>Value of <see cref="Ticks"/> in seconds.</returns>        /// <remarks>        /// If <see cref="Ticks"/> value represents an instant in time, returned value will represent the number of seconds        /// that have elapsed since 12:00:00 midnight, January 1, 0001.        /// </remarks>        public double ToSeconds()        {            return Value / (double)Ticks.PerSecond;        }         /// <summary>        /// Gets the <see cref="Ticks"/> value in equivalent number of milliseconds.        /// </summary>        /// <returns>Value of <see cref="Ticks"/> in milliseconds.</returns>        /// <remarks>        /// If <see cref="Ticks"/> value represents an instant in time, returned value will represent the number of milliseconds        /// that have elapsed since 12:00:00 midnight, January 1, 0001.        /// </remarks>        public double ToMilliseconds()        {            return Value / (double)Ticks.PerMillisecond;        }         /// <summary>        /// Gets the <see cref="Ticks"/> value in equivalent number of microseconds.        /// </summary>        /// <returns>Value of <see cref="Ticks"/> in microseconds.</returns>        /// <remarks>        /// If <see cref="Ticks"/> value represents an instant in time, returned value will represent the number of microseconds        /// that have elapsed since 12:00:00 midnight, January 1, 0001.        /// </remarks>        public double ToMicroseconds()        {            return Value / (double)Ticks.PerMicrosecond;        }         /// <summary>        /// Determines if time, represented by <see cref="Ticks"/> value in UTC time, is valid by comparing it to        /// the system clock.        /// </summary>        /// <param name="lagTime">The allowed lag time, in seconds, before assuming time is too old to be valid.</param>        /// <param name="leadTime">The allowed lead time, in seconds, before assuming time is too advanced to be valid.</param>        /// <returns>True, if UTC time represented by <see cref="Ticks"/> value, is within the specified range.</returns>        /// <remarks>        /// Time, represented by <see cref="Ticks"/> value, is considered valid if it exists within the specified        /// <paramref name="lagTime"/> and <paramref name="leadTime"/> range of system clock time in UTC. Note        /// that <paramref name="lagTime"/> and <paramref name="leadTime"/> must be greater than zero, but can be set        /// to sub-second intervals.        /// </remarks>        /// <exception cref="ArgumentOutOfRangeException">        /// <paramref name="lagTime"/> and <paramref name="leadTime"/> must be greater than zero, but can be less than one.        /// </exception>        public bool UtcTimeIsValid(double lagTime, double leadTime)        {            return TimeIsValid(DateTime.UtcNow.Ticks, lagTime, leadTime);        }         /// <summary>        /// Determines if time, represented by <see cref="Ticks"/> value in UTC time, is valid by comparing it to        /// the system clock.        /// </summary>        /// <param name="lagTime">The allowed lag time, in ticks, before assuming time is too old to be valid.</param>        /// <param name="leadTime">The allowed lead time, in ticks, before assuming time is too advanced to be valid.</param>        /// <returns>True, if UTC time represented by <see cref="Ticks"/> value, is within the specified range.</returns>        /// <remarks>        /// Time, represented by <see cref="Ticks"/> value, is considered valid if it exists within the specified        /// <paramref name="lagTime"/> and <paramref name="leadTime"/> range of system clock time in UTC. Note        /// that <paramref name="lagTime"/> and <paramref name="leadTime"/> must be greater than zero.        /// </remarks>        /// <exception cref="ArgumentOutOfRangeException">        /// <paramref name="lagTime"/> and <paramref name="leadTime"/> must be greater than zero.        /// </exception>        public bool UtcTimeIsValid(Ticks lagTime, Ticks leadTime)        {            return TimeIsValid(DateTime.UtcNow.Ticks, lagTime, leadTime);        }         /// <summary>        /// Determines if time, represented by <see cref="Ticks"/> value in local time, is valid by comparing it to        /// the system clock.        /// </summary>        /// <param name="lagTime">The allowed lag time, in seconds, before assuming time is too old to be valid.</param>        /// <param name="leadTime">The allowed lead time, in seconds, before assuming time is too advanced to be valid.</param>        /// <returns>True, if local time represented by <see cref="Ticks"/> value, is within the specified range.</returns>        /// <remarks>        /// Time, represented by <see cref="Ticks"/> value, is considered valid if it exists within the specified        /// <paramref name="lagTime"/> and <paramref name="leadTime"/> range of local system clock time. Note        /// that <paramref name="lagTime"/> and <paramref name="leadTime"/> must be greater than zero, but can be set        /// to sub-second intervals.        /// </remarks>        /// <exception cref="ArgumentOutOfRangeException">        /// <paramref name="lagTime"/> and <paramref name="leadTime"/> must be greater than zero, but can be less than one.        /// </exception>        public bool LocalTimeIsValid(double lagTime, double leadTime)        {            return TimeIsValid(DateTime.Now.Ticks, lagTime, leadTime);        }         /// <summary>        /// Determines if time, represented by <see cref="Ticks"/> value in local time, is valid by comparing it to        /// the system clock.        /// </summary>        /// <param name="lagTime">The allowed lag time, in ticks, before assuming time is too old to be valid.</param>        /// <param name="leadTime">The allowed lead time, in ticks, before assuming time is too advanced to be valid.</param>        /// <returns>True, if local time represented by <see cref="Ticks"/> value, is within the specified range.</returns>        /// <remarks>        /// Time, represented by <see cref="Ticks"/> value, is considered valid if it exists within the specified        /// <paramref name="lagTime"/> and <paramref name="leadTime"/> range of local system clock time. Note        /// that <paramref name="lagTime"/> and <paramref name="leadTime"/> must be greater than zero.        /// </remarks>        /// <exception cref="ArgumentOutOfRangeException">        /// <paramref name="lagTime"/> and <paramref name="leadTime"/> must be greater than zero.        /// </exception>        public bool LocalTimeIsValid(Ticks lagTime, Ticks leadTime)        {            return TimeIsValid(DateTime.Now.Ticks, lagTime, leadTime);        }         /// <summary>        /// Determines if time, represented by <see cref="Ticks"/> value, is valid by comparing it to the specified        /// current time.        /// </summary>        /// <param name="currentTime">Specified current time (e.g., could be DateTime.Now.Ticks).</param>        /// <param name="lagTime">The allowed lag time, in seconds, before assuming time is too old to be valid.</param>        /// <param name="leadTime">The allowed lead time, in seconds, before assuming time is too advanced to be valid.</param>        /// <returns>True, if time represented by <see cref="Ticks"/> value, is within the specified range.</returns>        /// <remarks>        /// Time, represented by <see cref="Ticks"/> value, is considered valid if it exists within the specified        /// <paramref name="lagTime"/> and <paramref name="leadTime"/> range of <paramref name="currentTime"/>. Note        /// that <paramref name="lagTime"/> and <paramref name="leadTime"/> must be greater than zero, but can be set        /// to sub-second intervals.        /// </remarks>        /// <exception cref="ArgumentOutOfRangeException">        /// <paramref name="lagTime"/> and <paramref name="leadTime"/> must be greater than zero, but can be less than one.        /// </exception>        public bool TimeIsValid(Ticks currentTime, double lagTime, double leadTime)        {            if (lagTime <= 0)                throw new ArgumentOutOfRangeException(nameof(lagTime), "lagTime must be greater than zero, but it can be less than one");             if (leadTime <= 0)                throw new ArgumentOutOfRangeException(nameof(leadTime), "leadTime must be greater than zero, but it can be less than one");             double distance = (currentTime.Value - Value) / (double)Ticks.PerSecond;             return (distance >= -leadTime && distance <= lagTime);        }         /// <summary>        /// Determines if time, represented by <see cref="Ticks"/> value, is valid by comparing it to the specified        /// current time.        /// </summary>        /// <param name="currentTime">Specified current time (e.g., could be DateTime.Now.Ticks).</param>        /// <param name="lagTime">The allowed lag time, in ticks, before assuming time is too old to be valid.</param>        /// <param name="leadTime">The allowed lead time, in ticks, before assuming time is too advanced to be valid.</param>        /// <returns>True, if time represented by <see cref="Ticks"/> value, is within the specified range.</returns>        /// <remarks>        /// Time, represented by <see cref="Ticks"/> value, is considered valid if it exists within the specified        /// <paramref name="lagTime"/> and <paramref name="leadTime"/> range of <paramref name="currentTime"/>. Note        /// that <paramref name="lagTime"/> and <paramref name="leadTime"/> must be greater than zero.        /// </remarks>        /// <exception cref="ArgumentOutOfRangeException">        /// <paramref name="lagTime"/> and <paramref name="leadTime"/> must be greater than zero.        /// </exception>        public bool TimeIsValid(Ticks currentTime, Ticks lagTime, Ticks leadTime)        {            if (lagTime.Value <= 0)                throw new ArgumentOutOfRangeException(nameof(lagTime), "lagTime must be greater than zero");             if (leadTime.Value <= 0)                throw new ArgumentOutOfRangeException(nameof(leadTime), "leadTime must be greater than zero");             long distance = (currentTime.Value - Value);             return (distance >= -leadTime.Value && distance <= lagTime.Value);        }         /// <summary>        /// Gets the distance, in 100-nanoseconds intervals, beyond the top of the second in the timestamp        /// represented by the <see cref="Ticks"/>.        /// </summary>        /// <returns>        /// Number of 100-nanoseconds intervals <see cref="Ticks"/> value is from the top of the second.        /// </returns>        public Ticks DistanceBeyondSecond()        {            // Calculate the number of ticks past the top of the second            return Value - (Value - Value % Ticks.PerSecond);        }         /// <summary>        /// Creates a new <see cref="Ticks"/> value that represents a base-lined timestamp, in 100-nanoseconds        /// intervals, that begins at the beginning of the specified time interval.        /// </summary>        /// <param name="interval">        /// <see cref="BaselineTimeInterval"/> to which <see cref="Ticks"/> timestamp should be base-lined.        /// </param>        /// <returns>        /// A new <see cref="Ticks"/> value that represents a base-lined timestamp, in 100-nanoseconds intervals,        /// that begins at the specified <see cref="BaselineTimeInterval"/>.        /// </returns>        /// <remarks>        /// Base-lining to the <see cref="BaselineTimeInterval.Second"/> would return the <see cref="Ticks"/>        /// value starting at zero milliseconds.<br/>        /// Base-lining to the <see cref="BaselineTimeInterval.Minute"/> would return the <see cref="Ticks"/>        /// value starting at zero seconds and milliseconds.<br/>        /// Base-lining to the <see cref="BaselineTimeInterval.Hour"/> would return the <see cref="Ticks"/>        /// value starting at zero minutes, seconds and milliseconds.<br/>        /// Base-lining to the <see cref="BaselineTimeInterval.Day"/> would return the <see cref="Ticks"/>        /// value starting at zero hours, minutes, seconds and milliseconds.<br/>        /// Base-lining to the <see cref="BaselineTimeInterval.Month"/> would return the <see cref="Ticks"/>        /// value starting at day one, zero hours, minutes, seconds and milliseconds.<br/>        /// Base-lining to the <see cref="BaselineTimeInterval.Year"/> would return the <see cref="Ticks"/>        /// value starting at month one, day one, zero hours, minutes, seconds and milliseconds.        /// </remarks>        public Ticks BaselinedTimestamp(BaselineTimeInterval interval)        {            switch (interval)            {                case BaselineTimeInterval.Second:                    return Value - Value % Ticks.PerSecond;                case BaselineTimeInterval.Minute:                    return Value - Value % Ticks.PerMinute;                case BaselineTimeInterval.Hour:                    return Value - Value % Ticks.PerHour;                case BaselineTimeInterval.Day:                    return Value - Value % Ticks.PerDay;                case BaselineTimeInterval.Month:                    DateTime toMonth = new DateTime(Value);                    return new DateTime(toMonth.Year, toMonth.Month, 1, 0, 0, 0, 0).Ticks;                case BaselineTimeInterval.Year:                    return new DateTime((new DateTime(Value)).Year, 1, 1, 0, 0, 0, 0).Ticks;                default:                    return this;            }        }         /// <summary>        /// Converts the value of the <see cref="Ticks"/> value to its equivalent <see cref="DateTime"/> string representation.        /// </summary>        /// <returns>A <see cref="DateTime"/> string representation of the <see cref="Ticks"/> value.</returns>        public override string ToString()        {            return ((DateTime)this).ToString();

Lines 1–500 of 1682.

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t