文章目录
- 一、名词概念
- 二、DateTime
- 三、TimeSpan
一、名词概念
(一)格里高利历
格里高利历一般指公元,即公历纪年法。目前我们所说公历,就是格里高利历。
比如 2022 年就是从公元元年开始算起的两千二十二年。
(二)格林尼治时间 (GMT)
格林尼治标准时间是指位于英国伦敦郊区的皇家格林尼治天文台的标准时间,因为本初子午线被定义在通过那里的经线。
地球每天的自转是有些不规则的,而且正在缓慢减速,所以格林尼治时间已经不再被作为标准时间使用。现在的标准时间——协调世界时(UTC)。
(三)协调世界时 (UTC)
又称世界统一时间、世界标准时间、国际协调时间。
UTC 协调世界时即格林尼治平太阳时间,是指格林尼治所在地的标准时间,也是表示地球自转速率的一种形式。
UTC 基于国际原子时间,通过不规则的加入闰秒来抵消地球自转变慢的影响,是世界上调节时钟和时间的主要时间标准。
(四)时间戳
从 1970 年 1 月 1 日(UNIX 时间戳的起点时间)到现在的时间。
计算机时间和众多的编程语言的时间都是从 1970 年 1 月 1 日开始算起,是因为很多编程语言起源于 UNIX 系统,而 UNIX 系统认为 1970 年 1 月 1 日 0 点是时间纪元。
所以我们常说的 UNIX 时间戳是以 1970 年 1 月 1 日 0 点为计时起点时间的。
原因:
最初计算机操作系统是 32 位,而时间也是用 32 位表示。32 位能代表的最大十进制数是 2147483647。1 年总秒数是 3153 6000,那么 2147483647 / 3153 6000 = 68.1 年。
也就是说因为早期用 32 位来表示时间,最大的时间间隔是 68 年,而最早出现的 UNIX 操作系统考虑到计算机产生的年代和应用的时限,综合取了 1970 年 1 月 1 日作为 UNIX TIME 的纪元时间(开始时间)。
二、DateTime
命名空间:System
DateTime 是 C# 提供给我们处理日期和时间的结构体。
DateTime 对象的默认值和最小值是 0001 年 1 月 1 日 00:00:00(午夜),最大值可以是 9999 年 12 月 31 日晚上 11:59:59
(一)初始化
public DateTime(int year, int month, int day, int hour, int minute, int second, int millisecond);
次要参数:
-
DateTimeKind:日期时间种类
- Local:本地时间
- Utc:UTC 时间
- Unspecified:不指定
-
Calendar:日历
使用哪个国家的日历,一般在 Unity 开发中不使用。
DateTime dt = new DateTime(2022, 12, 1, 13, 30, 45, 500);
print(dt.Year + "-" + dt.Month + "-" + dt.Day + "-" + dt.Hour + "-" + dt.Minute + "-" + dt.Second + "-" + dt.Millisecond); // 年、月、日、时、分、秒、毫秒
print(dt.Ticks); // 以格里高利历 00:00:00.000 年 1 月 1 日以来的 100 纳秒间隔数表示,一般是一个很大的数字
print(dt.DayOfYear); // 一年的第多少天
print(dt.DayOfWeek); // 星期几
(二)获取时间
DateTime nowTime = DateTime.Now;
print(nowTime.Minute); // 返回今日日期
DateTime nowTime2 = DateTime.Today;
print(nowTime2.Year + "-" + nowTime2.Month + "-" + nowTime2.Day); // 返回当前 UTC 日期和时间
(三)计算时间
// 各种加时间
DateTime nowTime3 = nowTime.AddDays(-1);
print(nowTime3.Day);
(四)字符串输出
// 默认输出格式
print(nowTime.ToString()); // "2023/8/17 22:55:35"
print(nowTime.ToShortTimeString()); // "22:55"
print(nowTime.ToShortDateString()); // "2023/8/17"
print(nowTime.ToLongTimeString()); // "22:55:35"
print(nowTime.ToLongDateString()); // "2023年8月17日"
// 自定义输出格式
print(nowTime.ToString("D")); // "2023年8月17日"
print(nowTime.ToString("yyyy-MM-dd-ddd/HH-mm-ss")); // "2023-08-17-周四/22-55-35"
自定义输出格式参照表 1 与表 2 示例:
(五)字符串转 DateTime
字符串想要成功转回 DateTime,那么这个字符串的格式是有要求的。最基本的 ToString() 的转换出来的字符串才能转回去,格式必须如下:
年/月/日 时:分:秒
string str = "1988/5/4 18:00:08";
DateTime dt3;
if (DateTime.TryParse(str, out dt3)) { // 尝试转换
print(dt3); // 此处可以转换成功
}
else {
print("转换失败");
}
(六)存储时间
存储时间的方式很多:
- 直接存字符串
- 直接存 Ticks
- 直接存时间戳信息
建议:存储时间戳的形式,更加节约。
三、TimeSpan
命名空间:System
TimeSpan 是 C# 提供给我们的时间跨度结构体,用两个 DateTime 对象相减可以得到 TimeSpan 对象。
public TimeSpan(int days, int hours, int minutes, int seconds, int milliseconds);
TimeSpan ts = DateTime.Now - new DateTime(1970, 1, 1);
print(ts.TotalMinutes); // 总分钟
print(ts.TotalSeconds); // 总秒数
print(ts.TotalDays); // 总天数
print(ts.TotalHours); // 总小时数
print(ts.Ticks); // 总 Ticks,即多少个 100 ns
print(ts.Days + "-" + ts.Hours + "-" + ts.Minutes + "-" + ts.Seconds + "-" + ts.Milliseconds); // "19586-22-55-35-19"
(一)时间计算
TimeSpan ts2 = new TimeSpan(1, 0, 0, 0);
DateTime timeNow = DateTime.Now + ts2;
TimeSpan ts3 = new TimeSpan(0, 1, 1, 1);
TimeSpan ts4 = ts2 + ts3;
print(ts4.Days + "-" + ts4.Hours); // "1-1"
(二)Ticks 转 Seconds
long seconds = ts4.Ticks / TimeSpan.TicksPerSecond; // 自带常量方便用于和 ticks 进行计算
(三)存储时间
// 用当前时间加上 2 天,再减去 1970 年 1 月 1 日的时间。得到时间差
TimeSpan time = DateTime.Now.AddDays(2) - new DateTime(1970, 1, 1);
// 再将该时间差转换为秒,便得到最终的时间戳,只需要存储该 long 变量即可
long timeStamp = (long)(time.Ticks / TimeSpan.TicksPerSecond);
// 由于时间戳的单位为秒,将其乘以转换常量,转为为 ticks 的单位
TimeSpan time2 = new TimeSpan(timeStamp * TimeSpan.TicksPerSecond);
// 再用 1970 年 1 月 1 日 + 该时间跨度,即可
DateTime date = new DateTime(1970, 1, 1) + time2;
每次打开面板时计算目标时间和当前时间的秒数差,在面板中对显示内容进行更新。
注意:不要在更新函数中不停用 DateTime.Now 来计算,浪费性能。只需要在面板打开时计算一次时间差,之后 用该时间差进行计算即可:
long seconds = (long)(date - DateTime.Now).TotalSeconds;