You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

481 lines
17 KiB

using Apewer.Internals;
using System;
using System.Collections.Generic;
using System.Text;
namespace Apewer.Internals
{
/// <summary>时钟。</summary>
internal struct ClockValue
{
#region 值。
//private int _hashcode = 0;
private int _year, _month, _day, _hour, _minute, _second, _milli;
/// <summary>年:1 ~ 9999,若超出范围,则设置为最大值。</summary>
public int Year
{
get { return _year; }
set { _year = NumberHelper.RestrictValue(value, 1, 9999); }
}
/// <summary>月:1 ~ 12,若超出范围,则设置为最大值。</summary>
public int Month
{
get { return _month; }
set { _month = NumberHelper.RestrictValue(value, 1, 12); }
}
/// <summary>日:1 ~ 31,若超出范围,则设置为最大值。</summary>
public int Day
{
get { return _day; }
set { _day = NumberHelper.RestrictValue(value, 1, ClockHelper.MonthDays(Year, Month)); }
}
/// <summary>时:0 ~ 23,若超出范围,则设置为最大值。</summary>
public int Hour
{
get { return _hour; }
set { _hour = NumberHelper.RestrictValue(value, 0, 59); }
}
/// <summary>分:0 ~ 59,若超出范围,则设置为最大值。</summary>
public int Minute
{
get { return _minute; }
set { _minute = NumberHelper.RestrictValue(value, 0, 59); }
}
/// <summary>秒:0 ~ 59,若超出范围,则设置为最大值。</summary>
public int Second
{
get { return _second; }
set { _second = NumberHelper.RestrictValue(value, 0, 59); }
}
/// <summary>毫秒:0 ~ 999,若超出范围,则设置为最大值。</summary>
public int Millisecond
{
get { return _milli; }
set { _milli = NumberHelper.RestrictValue(value, 0, 999); }
}
#endregion
#region 运算。
/// <summary>获取哈希代码。</summary>
public override int GetHashCode()
{
return Compact.GetHashCode();
}
/// <summary>判断值相等。</summary>
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;
}
/// <summary>获取时间戳,默认基于零值。</summary>
public TimeSpan Subtract()
{
return Subtract(true);
}
/// <summary>获取时间戳,若不为零值,则使用 1970-01-01 00:00:00.000 作为减数。</summary>
public TimeSpan Subtract(bool argZero)
{
return ToDateTime().Subtract(argZero ? Zero.ToDateTime() : Create(1970, 1, 1, 0, 0, 0, 0).ToDateTime());
}
/// <summary>减少时间。</summary>
public TimeSpan Subtract(ClockValue argClock)
{
var span = ToDateTime().Subtract(argClock.ToDateTime());
return span;
}
/// <summary>减少时间。</summary>
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;
}
/// <summary>比较 Clock 对象值。</summary>
public static bool operator >(ClockValue argLeft, ClockValue argRight)
{
return Compare(argLeft, argRight) == 1;
}
/// <summary>比较 Clock 对象值。</summary>
public static bool operator <(ClockValue argLeft, ClockValue argRight)
{
return Compare(argLeft, argRight) == -1;
}
#endregion
#region 输入。
/// <summary>使用零值创建对象。</summary>
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;
}
}
/// <summary>使用当前本地时间创建对象。</summary>
public static ClockValue Current
{
get { return Create(DateTime.Now); }
}
/// <summary>使用当前本地时间创建对象。</summary>
public static ClockValue LocalNow
{
get { return Create(DateTime.Now); }
}
/// <summary>使用当前 UTC 时间创建对象。</summary>
public static ClockValue UtcNow
{
get { return Create(DateTime.UtcNow); }
}
/// <summary>由指定时间创建对象。</summary>
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;
}
/// <summary>由指定时间创建对象。</summary>
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);
}
/// <summary>由指定时间创建对象。</summary>
public static ClockValue Create(int argYear, int argMonth, int argDay)
{
return Create(argYear, argMonth, argDay, 0, 0, 0, 0);
}
/// <summary>由指定时间创建对象。</summary>
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;
}
/// <summary>由指定 DateTime 创建对象。</summary>
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);
}
/// <summary>由毫秒时间戳创建对象。</summary>
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 输出。
/// <summary>表示当前时钟的文本,显示为易于阅读的格式。</summary>
public string Lucid
{
get { return ToString(true); }
}
/// <summary>表示当前时钟的文本,显示为易于阅读的格式。</summary>
public string LucidDate
{
get { return ToString(true).Substring(0, 10); }
}
/// <summary>表示当前时钟的文本,显示为易于阅读的格式。</summary>
public string LucidTime
{
get { return ToString(true).Substring(11); }
}
/// <summary>表示当前时钟的文本,显示为连续的数字。</summary>
public string Compact
{
get { return ToString(false); }
}
/// <summary>获取以毫秒为单位的时间戳,以 1970-01-01 00:00:00.000 为原点。</summary>
public long Stamp
{
get
{
return ClockHelper.Stamp(ToDateTime(), true);
}
}
/// <summary>生成 DateTime 对象。</summary>
public static DateTime ToDateTime(object argDateTime)
{
try { var dt = (DateTime)argDateTime; return dt; }
catch { return Zero.ToDateTime(); }
}
/// <summary>生成 DateTime 对象。</summary>
public static DateTime ToDateTime(string argDateTime)
{
if (string.IsNullOrEmpty(argDateTime))
{
try { var dt = DateTime.Parse(argDateTime); return dt; }
catch { }
}
return Zero.ToDateTime();
}
/// <summary>生成 DateTime 对象。</summary>
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;
}
/// <summary>生成文本。</summary>
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;
}
}
/// <summary>生成 Lucid 风格的文本。</summary>
public override string ToString()
{
return ToString(true);
}
#endregion
#region 封装。
/// <summary>表示当前时钟的字节数组。</summary>
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;
}
/// <summary>由指定字节数组创建对象。</summary>
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
}
}