//****************************************************************************************************** // TimeOffset.cs - Gbtc // // Copyright © 2017, 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://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: // ---------------------------------------------------------------------------------------------------- // 09/29/2017 - J. Ritchie Carroll // Generated original version of source code. // //****************************************************************************************************** using System; using Newtonsoft.Json; namespace GSF.COMTRADE { /// /// Represents a UTC time offset for COMTRADE - format HhMM. /// public class TimeOffset { #region [ Members ] // Fields private int m_hours; private int m_minutes; #endregion #region [ Constructors ] /// /// Creates a new instance of the /// public TimeOffset() { } /// /// Creates a new instance of the /// /// Line image to parse. public TimeOffset(string lineImage) { bool validFormat; int hours = 0, minutes = 0; if (string.Compare(lineImage, "x", StringComparison.OrdinalIgnoreCase) == 0) { // An "x" value means not applicable NotApplicable = true; validFormat = true; } else { // Image example: -5h30 string[] parts = lineImage.Split('h'); switch (parts.Length) { case 1: validFormat = int.TryParse(lineImage, out hours); break; case 2: { validFormat = int.TryParse(parts[0], out hours); if (validFormat) validFormat = int.TryParse(parts[1], out minutes); break; } default: validFormat = false; break; } } if (validFormat) { Hours = hours; Minutes = minutes; } else { throw new FormatException($"Invalid line image format for time offset: expected \"[+/-]HhMM\"{Environment.NewLine}Image = {lineImage}"); } } #endregion #region [ Properties ] /// /// Gets or sets UTC time offset hours. /// public int Hours { get => m_hours; set { if (Math.Abs(value) > 23) throw new ArgumentOutOfRangeException(nameof(value), "Maximum value for hours is 23."); m_hours = value; } } /// /// Gets or sets UTC time offset minutes. /// public int Minutes { get => m_minutes; set { if (value < 0) throw new ArgumentOutOfRangeException(nameof(value), "Minutes cannot be negative."); if (value > 59) throw new ArgumentOutOfRangeException(nameof(value), "Maximum value for minutes is 59."); m_minutes = value; } } /// /// Gets or sets value that determines if offset is not applicable. /// public bool NotApplicable { get; set; } /// /// Gets the total value in ticks. /// [JsonIgnore] public long TickOffset { get { long hourOffset = m_hours * Ticks.PerHour; long minuteOffset = m_minutes * Ticks.PerMinute; return hourOffset < 0 ? hourOffset - minuteOffset : hourOffset + minuteOffset; } } #endregion #region [ Methods ] /// /// Converts to its string format. /// public override string ToString() => NotApplicable ? "x" : $"{Hours}h{Minutes:00}"; #endregion } }