using Apewer.Internals; using System; using System.Collections.Generic; using System.Text; namespace Apewer.Internals { /// 时钟。 internal struct ClockValue { #region 值。 //private int _hashcode = 0; private int _year, _month, _day, _hour, _minute, _second, _milli; /// 年:1 ~ 9999,若超出范围,则设置为最大值。 public int Year { get { return _year; } set { _year = NumberHelper.RestrictValue(value, 1, 9999); } } /// 月:1 ~ 12,若超出范围,则设置为最大值。 public int Month { get { return _month; } set { _month = NumberHelper.RestrictValue(value, 1, 12); } } /// 日:1 ~ 31,若超出范围,则设置为最大值。 public int Day { get { return _day; } set { _day = NumberHelper.RestrictValue(value, 1, ClockHelper.MonthDays(Year, Month)); } } /// 时:0 ~ 23,若超出范围,则设置为最大值。 public int Hour { get { return _hour; } set { _hour = NumberHelper.RestrictValue(value, 0, 59); } } /// 分:0 ~ 59,若超出范围,则设置为最大值。 public int Minute { get { return _minute; } set { _minute = NumberHelper.RestrictValue(value, 0, 59); } } /// 秒:0 ~ 59,若超出范围,则设置为最大值。 public int Second { get { return _second; } set { _second = NumberHelper.RestrictValue(value, 0, 59); } } /// 毫秒:0 ~ 999,若超出范围,则设置为最大值。 public int Millisecond { get { return _milli; } set { _milli = NumberHelper.RestrictValue(value, 0, 999); } } #endregion #region 运算。 /// 获取哈希代码。 public override int GetHashCode() { return Compact.GetHashCode(); } /// 判断值相等。 public override bool Equals(object obj) { if (obj == null) return Equals(Create(0, 0, 0, 0, 0, 0, 0)); try { if (obj.GetType().Equals(typeof(ClockValue))) { return Compare(this, (ClockValue)obj) == 0; } } catch { } return false; } public static bool operator ==(ClockValue argLeft, ClockValue argRight) { if (argLeft.Year != argRight.Year) return false; if (argLeft.Month != argRight.Month) return false; if (argLeft.Day != argRight.Day) return false; if (argLeft.Hour != argRight.Hour) return false; if (argLeft.Minute != argRight.Minute) return false; if (argLeft.Second != argRight.Second) return false; if (argLeft.Millisecond != argRight.Millisecond) return false; return true; } public static bool operator !=(ClockValue argLeft, ClockValue argRight) { if (argLeft.Year != argRight.Year) return true; if (argLeft.Month != argRight.Month) return true; if (argLeft.Day != argRight.Day) return true; if (argLeft.Hour != argRight.Hour) return true; if (argLeft.Minute != argRight.Minute) return true; if (argLeft.Second != argRight.Second) return true; if (argLeft.Millisecond != argRight.Millisecond) return true; return false; } /// 获取时间戳,默认基于零值。 public TimeSpan Subtract() { return Subtract(true); } /// 获取时间戳,若不为零值,则使用 1970-01-01 00:00:00.000 作为减数。 public TimeSpan Subtract(bool argZero) { return ToDateTime().Subtract(argZero ? Zero.ToDateTime() : Create(1970, 1, 1, 0, 0, 0, 0).ToDateTime()); } /// 减少时间。 public TimeSpan Subtract(ClockValue argClock) { var span = ToDateTime().Subtract(argClock.ToDateTime()); return span; } /// 减少时间。 public ClockValue Subtract(TimeSpan argSpan) { var span = (argSpan == null) ? new TimeSpan(0) : argSpan; var dt = ToDateTime().Add(span); return Create(dt); } private static int Compare(ClockValue argLeft, ClockValue argRight) { if ((argLeft == null) && (argRight == null)) return 0; if ((argLeft == null) && (argRight != null)) return -1; if ((argLeft != null) && (argRight == null)) return 1; if (argLeft.Year < argRight.Year) return -1; if (argLeft.Month < argRight.Month) return -1; if (argLeft.Day < argRight.Day) return -1; if (argLeft.Hour < argRight.Hour) return -1; if (argLeft.Minute < argRight.Minute) return -1; if (argLeft.Second < argRight.Second) return -1; if (argLeft.Millisecond < argRight.Millisecond) return -1; if (argLeft.Millisecond == argRight.Millisecond) return 0; return 1; } /// 比较 Clock 对象值。 public static bool operator >(ClockValue argLeft, ClockValue argRight) { return Compare(argLeft, argRight) == 1; } /// 比较 Clock 对象值。 public static bool operator <(ClockValue argLeft, ClockValue argRight) { return Compare(argLeft, argRight) == -1; } #endregion #region 输入。 /// 使用零值创建对象。 public static ClockValue Zero { get { var clock = new ClockValue(); clock._year = 0; clock._month = 0; clock._day = 0; clock._hour = 0; clock._minute = 0; clock._second = 0; clock._milli = 0; return clock; } } /// 使用当前本地时间创建对象。 public static ClockValue Current { get { return Create(DateTime.Now); } } /// 使用当前本地时间创建对象。 public static ClockValue LocalNow { get { return Create(DateTime.Now); } } /// 使用当前 UTC 时间创建对象。 public static ClockValue UtcNow { get { return Create(DateTime.UtcNow); } } /// 由指定时间创建对象。 public static ClockValue Create(int argYear, int argMonth, int argDay, int argHour, int argMinute, int argSecond, int argMillisecond) { var clock = new ClockValue(); clock.Year = argYear; clock.Month = argMonth; clock.Day = argDay; clock.Hour = argHour; clock.Minute = argMinute; clock.Second = argSecond; clock.Millisecond = argMillisecond; return clock; } /// 由指定时间创建对象。 public static ClockValue Create(int argYear, int argMonth, int argDay, int argHour, int argMinute, int argSecond) { return Create(argYear, argMonth, argDay, argHour, argMinute, argSecond, 0); } /// 由指定时间创建对象。 public static ClockValue Create(int argYear, int argMonth, int argDay) { return Create(argYear, argMonth, argDay, 0, 0, 0, 0); } /// 由指定时间创建对象。 public static ClockValue Create(string argText, bool argLucid) { var clock = new ClockValue(); if (string.IsNullOrEmpty(argText)) return clock; if (argLucid) { if (argText.Length >= 10) { clock.Year = TextConverter.GetInt32(argText.Substring(0, 2)); clock.Month = TextConverter.GetInt32(argText.Substring(5, 2)); clock.Day = TextConverter.GetInt32(argText.Substring(8, 2)); } if (argText.Length >= 19) { clock.Hour = TextConverter.GetInt32(argText.Substring(11, 2)); clock.Minute = TextConverter.GetInt32(argText.Substring(14, 2)); clock.Second = TextConverter.GetInt32(argText.Substring(17, 2)); } if (argText.Length >= 23) { clock.Millisecond = TextConverter.GetInt32(argText.Substring(20, 3)); } } else { if (argText.Length >= 8) { clock.Year = TextConverter.GetInt32(argText.Substring(0, 2)); clock.Month = TextConverter.GetInt32(argText.Substring(4, 2)); clock.Day = TextConverter.GetInt32(argText.Substring(6, 2)); } if (argText.Length >= 14) { clock.Hour = TextConverter.GetInt32(argText.Substring(8, 2)); clock.Minute = TextConverter.GetInt32(argText.Substring(10, 2)); clock.Second = TextConverter.GetInt32(argText.Substring(12, 2)); } if (argText.Length >= 17) { clock.Millisecond = TextConverter.GetInt32(argText.Substring(14, 3)); } } return clock; } /// 由指定 DateTime 创建对象。 public static ClockValue Create(DateTime argDateTime) { var dt = argDateTime; if (dt == null) dt = new DateTime(0, 0, 0, 0, 0, 0, 0); return Create(dt.Year, dt.Month, dt.Day, dt.Hour, dt.Minute, dt.Second, dt.Millisecond); } /// 由毫秒时间戳创建对象。 public static ClockValue Create(long argMillisecondStamp) { var origin = new DateTime(1970, 1, 1, 0, 0, 0, 0); var datetime = origin.AddMilliseconds(Convert.ToDouble(argMillisecondStamp)); return Create(datetime); } #endregion #region 输出。 /// 表示当前时钟的文本,显示为易于阅读的格式。 public string Lucid { get { return ToString(true); } } /// 表示当前时钟的文本,显示为易于阅读的格式。 public string LucidDate { get { return ToString(true).Substring(0, 10); } } /// 表示当前时钟的文本,显示为易于阅读的格式。 public string LucidTime { get { return ToString(true).Substring(11); } } /// 表示当前时钟的文本,显示为连续的数字。 public string Compact { get { return ToString(false); } } /// 获取以毫秒为单位的时间戳,以 1970-01-01 00:00:00.000 为原点。 public long Stamp { get { return ClockHelper.Stamp(ToDateTime(), true); } } /// 生成 DateTime 对象。 public static DateTime ToDateTime(object argDateTime) { try { var dt = (DateTime)argDateTime; return dt; } catch { return Zero.ToDateTime(); } } /// 生成 DateTime 对象。 public static DateTime ToDateTime(string argDateTime) { if (string.IsNullOrEmpty(argDateTime)) { try { var dt = DateTime.Parse(argDateTime); return dt; } catch { } } return Zero.ToDateTime(); } /// 生成 DateTime 对象。 public DateTime ToDateTime() { try { var year = NumberHelper.RestrictValue(Year, 1, 9999); var month = NumberHelper.RestrictValue(Month, 1, 12); var days = ClockHelper.MonthDays(year, month); var day = NumberHelper.RestrictValue(Day, 1, days); var hour = NumberHelper.RestrictValue(Hour, 0, 23); var minute = NumberHelper.RestrictValue(Minute, 0, 59); var second = NumberHelper.RestrictValue(Second, 0, 59); var milli = NumberHelper.RestrictValue(Millisecond, 0, 999); var dt = new DateTime(year, month, day, hour, minute, second, milli); return dt; } catch { return new DateTime(); } } public byte[] ToBinary() { var bs = new byte[9]; bs[0] = (byte)(Year / 256); bs[1] = (byte)(Year % 256); bs[2] = (byte)(Day / 256); bs[3] = (byte)(Month / 256); bs[4] = (byte)(Hour / 256); bs[5] = (byte)(Minute / 256); bs[6] = (byte)(Second / 256); bs[7] = (byte)(Millisecond / 256); bs[8] = (byte)(Millisecond % 256); return bs; } /// 生成文本。 public string ToString(bool argLucid) { if (argLucid) { var result = new TextBuilder(); result.Append(TextModifier.PreZero(Year.ToString(), 4)); result.Append("-"); result.Append(TextModifier.PreZero(Month.ToString(), 2)); result.Append("-"); result.Append(TextModifier.PreZero(Day.ToString(), 2)); result.Append(" "); result.Append(TextModifier.PreZero(Hour.ToString(), 2)); result.Append(":"); result.Append(TextModifier.PreZero(Minute.ToString(), 2)); result.Append(":"); result.Append(TextModifier.PreZero(Second.ToString(), 2)); result.Append("."); result.Append(TextModifier.PreZero(Millisecond.ToString(), 3)); return result.Value; } else { string result = ""; result += TextModifier.PreZero(Year.ToString(), 4); result += TextModifier.PreZero(Month.ToString(), 2); result += TextModifier.PreZero(Day.ToString(), 2); result += TextModifier.PreZero(Hour.ToString(), 2); result += TextModifier.PreZero(Minute.ToString(), 2); result += TextModifier.PreZero(Second.ToString(), 2); result += TextModifier.PreZero(Millisecond.ToString(), 3); return result; } } /// 生成 Lucid 风格的文本。 public override string ToString() { return ToString(true); } #endregion #region 封装。 /// 表示当前时钟的字节数组。 public static byte[] ToBinary(ClockValue argClock) { var bs = new byte[9]; bs[0] = (byte)(argClock.Year / 256); bs[1] = (byte)(argClock.Year % 256); bs[2] = (byte)(argClock.Day / 256); bs[3] = (byte)(argClock.Month / 256); bs[4] = (byte)(argClock.Hour / 256); bs[5] = (byte)(argClock.Minute / 256); bs[6] = (byte)(argClock.Second / 256); bs[7] = (byte)(argClock.Millisecond / 256); bs[8] = (byte)(argClock.Millisecond % 256); return bs; } /// 由指定字节数组创建对象。 public static ClockValue FromBinary(byte[] argBytes) { var bs = argBytes; if (bs != null) { var clock = new ClockValue(); if (argBytes.Length >= 4) { clock.Year = bs[0] * 256 + bs[1]; clock.Month = bs[2]; clock.Day = bs[3]; } if (argBytes.Length >= 7) { clock.Hour = bs[4]; clock.Minute = bs[5]; clock.Millisecond = bs[6] * 256 + bs[7]; } return clock; } else { return Create(0, 0, 0, 0, 0, 0, 0); } } #endregion } }