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.

286 lines
10 KiB

using System;
using System.Collections.Generic;
using System.Text;
namespace Apewer
{
/// <summary>System.DateTime 实用工具。</summary>
public class DateTimeUtility
{
#region Private Methods
private static DateTime GetOrigin()
{
return new DateTime(1970, 1, 1, 0, 0, 0, 0);
}
private static string FormatDate(DateTime datetime, bool lucid)
{
var sb = new StringBuilder();
var y = NumberUtility.RestrictValue(datetime.Year, 0, 9999);
var m = NumberUtility.RestrictValue(datetime.Month, 1, 12);
var d = NumberUtility.RestrictValue(datetime.Day, 1, GetDays(y, m));
if (y < 10) sb.Append("000");
else if (y < 100) sb.Append("00");
else if (y < 1000) sb.Append("0");
sb.Append(y.ToString());
if (lucid) sb.Append("-");
if (m < 10) sb.Append("0");
sb.Append(m.ToString());
if (lucid) sb.Append("-");
if (d < 10) sb.Append("0");
sb.Append(d.ToString());
var date = sb.ToString();
return date;
}
private static string FormatTime(DateTime datetime, bool lucid, bool seconds, bool milliseconds)
{
var sb = new StringBuilder();
var h = NumberUtility.RestrictValue(datetime.Hour, 0, 23);
var m = NumberUtility.RestrictValue(datetime.Minute, 0, 59);
var s = NumberUtility.RestrictValue(datetime.Second, 0, 59);
var ms = NumberUtility.RestrictValue(datetime.Millisecond, 0, 999);
if (h < 10) sb.Append("0");
sb.Append(h.ToString());
if (lucid) sb.Append(":");
if (m < 10) sb.Append("0");
sb.Append(m.ToString());
if (seconds)
{
if (lucid) sb.Append(":");
if (s < 10) sb.Append("0");
sb.Append(s.ToString());
if (milliseconds)
{
if (lucid) sb.Append(".");
if (ms < 10) sb.Append("00");
else if (ms < 100) sb.Append("0");
sb.Append(ms.ToString());
}
}
var time = sb.ToString();
return time;
}
#endregion
#region Public Properties
/// <summary>获取当前本地时间的易读格式文本。</summary>
public static string NowLucid { get { return ToLucid(DateTime.Now); } }
/// <summary>获取当前 UTC 的易读格式文本。</summary>
public static string NowUtcLucid { get { return ToLucid(DateTime.UtcNow); } }
/// <summary>获取当前本地时间的毫秒时间戳。</summary>
public static long NowStamp { get { return GetStamp(DateTime.Now); } }
/// <summary>获取当前 UTC 的毫秒时间戳。</summary>
public static long NowUtcStamp { get { return GetStamp(DateTime.UtcNow); } }
/// <summary>获取 1970-01-01 00:00:00.000 的时间对象。</summary>
public static DateTime Origin { get { return GetOrigin(); } }
#endregion
#region Public Methods
/// <summary>获取安全的 DateTime 对象。</summary>
public static DateTime GetDateTime(DateTime datetime)
{
var origin = GetOrigin();
var span = datetime - origin;
var stemp = span.TotalMilliseconds;
var safely = origin.AddMilliseconds(stemp);
return safely;
}
/// <summary>获取安全的 DateTime 对象。</summary>
public static DateTime ToDateTime(DateTime datetime)
{
return GetDateTime(datetime);
}
/// <summary>从毫秒时间戳获取 DateTime 对象。发生异常且不允许异常时将返回 1970-01-01 00:00:00.000。</summary>
/// <exception cref="System.ArgumentOutOfRangeException"></exception>
public static DateTime GetDateTime(long stamp, bool exceptable = true)
{
var origin = GetOrigin();
try
{
var datetime = origin.AddMilliseconds(Convert.ToDouble(stamp));
return datetime;
}
catch
{
if (exceptable) throw new ArgumentOutOfRangeException();
return origin;
}
}
/// <summary>从毫秒时间戳获取 DateTime 对象。发生异常且不允许异常时将返回 1970-01-01 00:00:00.000。</summary>
/// <exception cref="System.ArgumentOutOfRangeException"></exception>
public static DateTime ToDateTime(long stamp, bool exceptable = true)
{
var origin = GetOrigin();
try
{
var datetime = origin.AddMilliseconds(Convert.ToDouble(stamp));
return datetime;
}
catch
{
if (exceptable) throw new ArgumentOutOfRangeException();
return origin;
}
}
/// <summary>获取毫秒时间戳。</summary>
public static long GetStamp(DateTime datetime)
{
var origin = GetOrigin();
var span = datetime - origin;
var milliseconds = span.TotalMilliseconds;
var result = Convert.ToInt64(milliseconds);
return result;
}
/// <summary>获取毫秒时间戳。</summary>
public static long ToStamp(DateTime datetime)
{
return GetStamp(datetime);
}
/// <summary>判断是否为闰年。</summary>
public static bool IsLeapYear(int year)
{
if (year % 400 == 0) return true;
if (year % 100 == 0) return false;
if (year % 4 == 0) return true;
return false;
}
/// <summary>获取指定月份中的天数。</summary>
public static int GetDays(int year, int month)
{
switch (month)
{
case 1: case 3: case 5: case 7: case 8: case 10: case 12: return 31;
case 4: case 6: case 9: case 11: return 30;
case 2: return IsLeapYear(year) ? 29 : 28;
default: return 0;
}
}
/// <summary>转换 DateTime 对象到易于阅读的文本。</summary>
public static string ToLucid(DateTime datetime, bool date = true, bool time = true, bool seconds = true, bool milliseconds = true)
{
var safely = GetDateTime(datetime);
var sb = new StringBuilder();
if (date) sb.Append(FormatDate(safely, true));
if (time)
{
if (date) sb.Append(" ");
sb.Append(FormatTime(safely, true, seconds, milliseconds));
}
var lucid = sb.ToString();
return lucid;
}
/// <summary>转换 DateTime 对象到易于阅读的文本。</summary>
public static string GetLucid(DateTime datetime, bool date = true, bool time = true, bool seconds = true, bool milliseconds = true)
{
return GetLucid(datetime, date, time, seconds, milliseconds);
}
/// <summary>转换 DateTime 对象到紧凑的文本。</summary>
public static string ToCompact(DateTime datetime, bool date = true, bool time = true, bool seconds = true, bool milliseconds = true)
{
var safely = GetDateTime(datetime);
var sb = new StringBuilder();
if (date) sb.Append(FormatDate(safely, false));
if (time)
{
// if (date) sb.Append(" ");
sb.Append(FormatTime(safely, false, seconds, milliseconds));
}
var lucid = sb.ToString();
return lucid;
}
/// <summary>转换 DateTime 对象到紧凑的文本。</summary>
public static string GetCompact(DateTime datetime, bool date = true, bool time = true, bool seconds = true, bool milliseconds = true)
{
return ToCompact(datetime, date, time, seconds, milliseconds);
}
/// <summary>解析 Lucid 文本。</summary>
public static Nullable<DateTime> ParseLucid(string lucid)
{
var failed = new Nullable<DateTime>();
if (lucid.IsEmpty()) return failed;
int year = 0, month = 0, day = 0, hour = 0, minute = 0, second = 0, milli = 0;
if (lucid.Length < 10) return failed;
if (lucid[4] != '-' || lucid[7] != '-') return failed;
year = TextUtility.GetInt32(lucid.Substring(0, 4));
month = TextUtility.GetInt32(lucid.Substring(5, 2));
day = TextUtility.GetInt32(lucid.Substring(8, 2));
if (year < 1) return failed;
if (month < 1 || month > 12) return failed;
if (day < 1 || day > DateTime.DaysInMonth(year, month)) return failed;
if (lucid.Length >= 16)
{
if (lucid[10] != ' ' || lucid[13] != ':') return failed;
hour = TextUtility.GetInt32(lucid.Substring(11, 2));
minute = TextUtility.GetInt32(lucid.Substring(14, 2));
if (hour < 0 || hour > 23) return failed;
if (minute < 0 || minute > 59) return failed;
if (lucid.Length >= 19)
{
if (lucid[16] != ':') return failed;
second = TextUtility.GetInt32(lucid.Substring(17, 2));
if (second < 0 || second > 59) return failed;
if (lucid.Length >= 23)
{
if (lucid[19] != '.') return failed;
milli = TextUtility.GetInt32(lucid.Substring(20, 3));
if (milli < 0 || milli > 999) return failed;
}
}
}
var entity = new DateTime(year, month, day, hour, minute, second, milli);
return new Nullable<DateTime>(entity);
}
/// <summary>创建新的零值 DateTime 对象。</summary>
public static DateTime Zero() => new DateTime(0L, DateTimeKind.Utc);
#endregion
}
}