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
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
|
|
|
|
}
|
|
|
|
}
|
|
|