DateTime 相关的操作汇总【C# 基础】

datetime,相关,操作,汇总,c#,基础 · 浏览次数 : 634

小编点评

## 生成内容时需要带简单的排版 以下内容生成时需要带简单的排版: * **时间戳时间戳 (TimeStamp)**:通常是一个字符序列,唯一地标识某一刻的时间。 * **日期时间戳 (Date)**:表示某个日期的秒数或毫秒数。 * **时间 (Time)**:表示某个时间的秒数或毫秒数。 * **日期时间 (Date)**:表示某个日期的秒数或毫秒数。 * **时间戳 (Ticks)**:时间从 Unix 纪元开始,至开始时间的最小粒度总数。 **排版建议:** * 在生成时间戳时,可以使用格式化函数格式化时间字符串,以便易于阅读。例如,`"{DateTime.Now:HH:mm:ss}"`。 * 在生成日期时间戳时,可以使用 `"{DateTime.Now:yyyy-MM-dd}"` 或 `"{DateTime.Now:yyyy-MM-dd HH:mm:ss}"` 格式化日期字符串。 * 在生成时间戳时,可以使用 `"{DateTime.Now:yyyy-MM-dd HH:mm:ss}"` 格式化时间字符串。 **示例代码:** ```csharp // 时间戳 Console.WriteLine($"{DateTime.Now:HH:mm:ss}"); // 日期时间 Console.WriteLine($"{DateTime.Now:yyyy-MM-dd}"); // 时间 Console.WriteLine($"{DateTime.Now:HH:mm:ss}"); // 日期时间 Console.WriteLine($"{DateTime.Now:yyyy-MM-dd}"); // 时间戳 Console.WriteLine($"{DateTime.Now:yyyy-MM-dd HH:mm:ss}"); // 日期时间戳 Console.WriteLine($"{DateTime.Now:yyyy-MM-dd HH:mm:ss}"); // 时间戳 Console.WriteLine($"{DateTime.Now:yyyy-MM-dd HH:mm:ss}"); ``` **运行结果:** ``` 00:00:00 2023-04-01 16:00:00 2023-04-01 16:00:00 16:00:00 2023-04-01 16:00:00 00:00:00 ```

正文

〇、前言

在日常开发中,日期值当然是不可或缺的,能够清晰的在脑海中梳理出最快捷的实现也非常重要,那么今天就来梳理一下。

一、C# 中的本机时间以及格式化

如何取当前(本机)时间?很简单,一句话解决:

DateTime dt_now = DateTime.Now;

1.1 单字母格式化日期时间值

如下示例,将 ToString() 支持的单字母全部列出,并对比格式差异:

Console.WriteLine("“日本投降矣!”78 年前的今天,1945 年 8 月 15 日,铭记历史,吾辈自强!");
Console.WriteLine("付出了巨大牺牲的中国人民将坚定不移,捍卫用鲜血和生命写下的历史,捍卫来之不易的和平!");
Console.WriteLine($"_:{DateTime.Now} 默认格式"); // 默认格式就是 G 的格式
Console.WriteLine($"D:{DateTime.Now.ToString("D")}");
Console.WriteLine($"d:{DateTime.Now.ToString("d")}");
Console.WriteLine($"F:{DateTime.Now.ToString("F")}");
Console.WriteLine($"f:{DateTime.Now.ToString("f")}");
Console.WriteLine($"G:{DateTime.Now.ToString("G")}");
Console.WriteLine($"g:{DateTime.Now.ToString("g")}");
Console.WriteLine($"T:{DateTime.Now.ToString("T")}");
Console.WriteLine($"t:{DateTime.Now.ToString("t")}");
Console.WriteLine($"U:{DateTime.Now.ToString("U")}");
Console.WriteLine($"u:{DateTime.Now.ToString("u")}");
Console.WriteLine($"M:{DateTime.Now.ToString("M")}"); // M、m 格式相同
Console.WriteLine($"m:{DateTime.Now.ToString("m")}");
Console.WriteLine($"R:{DateTime.Now.ToString("R")}"); // R、r 格式相同
Console.WriteLine($"r:{DateTime.Now.ToString("r")}");
Console.WriteLine($"Y:{DateTime.Now.ToString("Y")}"); // Y、y 格式相同
Console.WriteLine($"y:{DateTime.Now.ToString("y")}");
Console.WriteLine($"O:{DateTime.Now.ToString("O")}"); // O、o格式相同
Console.WriteLine($"o:{DateTime.Now.ToString("o")}");
Console.WriteLine($"s:{DateTime.Now.ToString("s")}"); // 没有 S 格式

关于时间的几个概念了解:

名词 举例 备注
长时间(T) 16:30:28 显示至 秒级
短时间(t) 16:30 显示至 分钟级
长日期(D) 2023年8月15日 汉字显示年月日
短日期(d) 2023/8/15 反斜线代替汉字年月,没有小日
页面显示常用 = 长日期+长时间(F)  2023年8月15日  16:30:28  
数据显示常用 = 短日期+长时间(G) 2023/8/15 16:30:28  
Console.WriteLine($"默认格式          {DateTime.Now}");
Console.WriteLine($"ToShortTimeString {DateTime.Now.ToShortTimeString()}");
Console.WriteLine($"ToLongTimeString  {DateTime.Now.ToLongTimeString()}");
Console.WriteLine($"ToShortDateString {DateTime.Now.ToShortDateString()}");
Console.WriteLine($"ToLongDateString  {DateTime.Now.ToLongDateString()}");
Console.WriteLine($"ToLocalTime       {DateTime.Now.ToLocalTime()}");

1.2 日期时间精准格式化

如下示例,通过固定的日期格式指示字符,精准到日期时间的每一位显示:

Console.WriteLine("“日本投降矣!”78 年前的今天,1945 年 8 月 15 日,铭记历史,吾辈自强!");
Console.WriteLine("付出了巨大牺牲的中国人民将坚定不移,捍卫用鲜血和生命写下的历史,捍卫来之不易的和平!");
Console.WriteLine($"默认格式:                  :{DateTime.Now}");
Console.WriteLine($"yyyy-MM-dd HH:mm:ss.fffffff:{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fffffff")}"); // 秒的小数位,最高精确到 7 位
Console.WriteLine($"yyyy-MM-dd HH:mm:ss.ffff   :{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.ffff")}"); // 秒的小数位小于 7 时,其他位数将自动截断
Console.WriteLine($"yyyy-MM-dd HH:mm:ss.f      :{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.f")}");
Console.WriteLine($"yyyy-MM-dd HH:mm:ss        :{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}"); // HH:二十四小时制
Console.WriteLine($"yyyy-MM-dd hh:mm:ss        :{DateTime.Now.ToString("yyyy-MM-dd hh:mm:ss")}"); // hh:十二小时制
Console.WriteLine($"yyyyy-MMMM-dddd HH:mm:ss   :{DateTime.Now.ToString("yyyyy-MMMM-dddd HH:mm:ss")}");
Console.WriteLine($"yyyy-MMM-ddd H:m:s         :{DateTime.Now.ToString("yyyy-MMM-ddd H:m:s")}");
Console.WriteLine($"y-M-d H:m:s                :{DateTime.Now.ToString("y-M-d H:m:s")}");

年份 y(1~5 位)
y:年份的后两位,十位上若是 0 则省略
yy:年份的后两位,十位上不存在省略
yyy:年份的前四位,千位上若是 0 则省略
yyyy:年份的前四位,千位上不存在省略
yyyyy:年份的前五位
月份 M(1~4 位)
M:两位的月份,十位上若是 0 则省略
MM:两位的月份,十位上不存在省略
MMM:显示“8月”
MMMM:显示“八月”
d(1~4 位)
d:两位的天数,十位上若是 0 则省略
dd:两位的天数,十位上不存在省略
ddd:显示“周二”
dddd:显示“星期二”

h(1~2 位)

H(1~2 位)

h:十二小时制,十位上若为 0 则省略
hh:十二小时制,十位上不存在省略
H:二十四小时制,十位上若为 0 则省略
HH:二十四小时制,十位上不存在省略
m(1~2 位)
m:两位分钟数,十位上若是 0 则省略
mm:两位分钟数,十位上不存在省略
s(1~2 位)
m:两位秒数,十位上若是 0 则省略
mm:两位秒数,十位上不存在省略
秒的小数位 f(1~7 位)
// 其他位数类同
fff:秒的小数位精确到 3 位,后边四位自动截断

参考:https://www.cnblogs.com/yohen/articles/1565833.html

1.3 日期时间的加、减操作

DateTime dt_example = Convert.ToDateTime("2023-08-15 10:10:10.1000000");
// DateTime dt_example = DateTime.Parse("2023-08-15 10:10:10.1000000");
Console.WriteLine($"默认格式          {dt_example.ToString("yyyy-MM-dd HH:mm:ss.fffffff")}");
Console.WriteLine($"AddYears1         {dt_example.AddYears(1).ToString("yyyy-MM-dd HH:mm:ss.fffffff")}");
Console.WriteLine($"AddYears-1        {dt_example.AddYears(-1).ToString("yyyy-MM-dd HH:mm:ss.fffffff")}");
Console.WriteLine($"AddMonths         {dt_example.AddMonths(1).ToString("yyyy-MM-dd HH:mm:ss.fffffff")}");
Console.WriteLine($"AddDays           {dt_example.AddDays(1).ToString("yyyy-MM-dd HH:mm:ss.fffffff")}");
Console.WriteLine($"AddHours          {dt_example.AddHours(1).ToString("yyyy-MM-dd HH:mm:ss.fffffff")}");
Console.WriteLine($"AddMinutes        {dt_example.AddMinutes(1).ToString("yyyy-MM-dd HH:mm:ss.fffffff")}");
Console.WriteLine($"AddSeconds        {dt_example.AddSeconds(1).ToString("yyyy-MM-dd HH:mm:ss.fffffff")}");
Console.WriteLine($"AddMilliseconds   {dt_example.AddMilliseconds(1).ToString("yyyy-MM-dd HH:mm:ss.fffffff")}");
Console.WriteLine($"AddMicroseconds1  {dt_example.AddMicroseconds(1).ToString("yyyy-MM-dd HH:mm:ss.fffffff")}");
Console.WriteLine($"AddMicroseconds-1 {dt_example.AddMicroseconds(-1).ToString("yyyy-MM-dd HH:mm:ss.fffffff")}");

 

1.4 取日期时间的单个值

取值的结果均为 int 类型。

DateTime dt_example = DateTime.Parse("2023-08-15 10:10:10.1234567");
Console.WriteLine($"Year        {dt_example.Year}");
Console.WriteLine($"Month       {dt_example.Month}");
Console.WriteLine($"Day         {dt_example.Day}");
Console.WriteLine($"Hour        {dt_example.Hour}");
Console.WriteLine($"Minute      {dt_example.Minute}");
Console.WriteLine($"Second      {dt_example.Second}");
Console.WriteLine($"Millisecond {dt_example.Millisecond}");
Console.WriteLine($"Microsecond {dt_example.Microsecond}");

参考: https://www.cnblogs.com/lida/archive/2011/01/02/1924197.html

二、北京时间与协调世界时

2.1 时间概念的分类

当前时间大概可以分为三类:

  • 协调世界时:就是世界标准时间,这个时间在任何人看来都是相同的。
  • 北京时间:中国标准时间,是根据时区划分,北京为东八区而得来。
  • 本机时间:这个一般参考北京时间,不确定性比较大了,可以自行设置和校准,存在误差的可能性较大。

下面来看下详解:

2.1.1 协调世界时(UTC)

协调世界时又称世界统一时间、世界标准时间、国际协调时间。由于英文(CUT)和法文(TUC)的缩写不同,作为妥协,简称 UTC。

协调世界时是以原子时秒长为基础,在时刻上尽量接近于世界时的一种时间计量系统。

国际原子时的准确度为每日数纳秒,而世界时的准确度为每日数毫秒。许多应用部门要求时间系统接近世界时 UT,对于这种情况,一种称为协调世界时的折中时标于 1972 年面世。为确保协调世界时与世界时相差不会超过0.9秒,在有需要的情况下会在协调世界时内加上正或负闰秒。因此协调世界时与国际原子时之间会出现若干整数秒的差别,两者之差逐年积累,便采用跳秒(闰秒)的方法使协调时与世界时的时刻相接近,其差不超过1s。它既保持时间尺度的均匀性,又能近似地反映地球自转的变化。按国际无线电咨询委员会(CCIR)通过的关于 UTC 的修正案,从 1972 年 1 月 1 日起 UTC 与 UT1(在UT中加入极移改正得到)之间的差值最大可以达到 ±0.9s。位于巴黎的国际地球自转事务中央局负责决定何时加入闰秒。一般会在每年的 6 月 30 日、12 月 31 日的最后一秒进行调整。

这套时间系统被应用于许多互联网和万维网的标准中,例如,网络时间协议就是协调世界时在互联网中使用的一种方式。

在 C# 中,有一个专门的类 DateTimeOffset,用来标识 UTC 时间。

static void Main(string[] args)
{
    Console.WriteLine($"DateTime.Now:                                         {DateTime.Now}");
    Console.WriteLine($"DateTime.Now.ToUniversalTime():                       {DateTime.Now.ToUniversalTime()}");
    Console.WriteLine($"DateTime.UtcNow:                                      {DateTime.UtcNow}");
    Console.WriteLine($"new DateTimeOffset(DateTime.UtcNow):                  {new DateTimeOffset(DateTime.UtcNow)}");
    Console.WriteLine($"new DateTimeOffset(DateTime.UtcNow).ToUniversalTime():{new DateTimeOffset(DateTime.UtcNow).ToUniversalTime()}");
    Console.WriteLine($"new DateTimeOffset(DateTime.Now):                     {new DateTimeOffset(DateTime.Now)}");
    Console.WriteLine($"new DateTimeOffset(DateTime.Now).ToUniversalTime():   {new DateTimeOffset(DateTime.Now).ToUniversalTime()}");
    Console.ReadLine();
}

2.1.2 本机时间

本机时间就是最常用的时间了,代码中通过DateTime.Now获取。

本机时间容易存在不准时的情况,因为本机时间不一定和标准时间同步。

2.1.3 北京时间

我国的标准时区:UTC/GMT +8.00 (东八区)。

因为北京处于国际时区划分中的东八区,同格林尼治时间(世界时)整整相差8小时(即北京时间 = 协调世界时+8 小时),故命名为“北京时间”。

授时台必须建在地理中心地带,中国东西相跨 5 个时区(即东五区、东六区、东七区、东八区、东九区5个时区),从而也就产生了长短波授。“北京时间”与“北京当地时间”是两个概念,“北京时间”的发播不在北京,而是由陕西省渭南市蒲城县(处于东七区)的中国科学院国家授时中心发播。

中国科学院国家授时中心台本部位于陕西省西安市临潼区。中国科学院国家授时中心授时部(二部)位于陕西省渭南市蒲城县,两地虽处于东七区,但全国统一使用北京时间,负责发布北京时间,而非当地的地方时。

2.2 通过取网络时间来测试一下

下面来测试下看看(测试机时区选择的是:尤克拉 UTC+08:45)

注意:DateTime.Parse()Convert.ToDateTime()都是将时间字符串,按照本机配置的时区,转换为 DateTime 类型。

static void Main(string[] args)
{
    // 通过 HTTP 响应取标准时间
    HttpClient client = new HttpClient();
    using HttpResponseMessage response = client.GetAsync("https://cn.bing.com/").Result; // 此处网站地址可随意调换
    var ddd= response.Headers.Date;
    string dstr00 = ddd.ToString(); // 2023/8/17 6:10:35 +00:00
    Console.WriteLine($"dstr00:                    {dstr00}");
    Console.WriteLine($"DateTime.Parse(dstr00):    {DateTime.Parse(dstr00)}");
    Console.WriteLine($"Convert.ToDateTime(dstr00):{Convert.ToDateTime(dstr00)}");
    Console.WriteLine();
    string dstr08 = ddd.ToString().Replace(" +00:00", " +08:00"); // 2023/8/17 6:10:35 +08:00
    Console.WriteLine($"dstr08:                    {dstr08}");
    Console.WriteLine($"DateTime.Parse(dstr08):    {DateTime.Parse(dstr08)}");
    Console.WriteLine($"Convert.ToDateTime(dstr08):{Convert.ToDateTime(dstr08)}");
    Console.WriteLine();
    string dstr = ddd.ToString().Replace(" +00:00", ""); // 2023/8/17 6:10:35
    Console.WriteLine($"dstr  :                    {dstr}");
    Console.WriteLine($"DateTime.Parse(dstr):      {DateTime.Parse(dstr)}");
    Console.WriteLine($"Convert.ToDateTime(dstr):  {Convert.ToDateTime(dstr)}");
    Console.WriteLine();
    Console.WriteLine($"DateTime.Now:              {DateTime.Now}");
    Console.ReadLine();
}

当时间字符串的时区标识为“+00:00”,说明时间是协调世界时,转换成本地当前时间时,自动按照当前时区“+08:45”,则结果就是::UTC+08:45:00。

当时间字符串的时区标识为“+08:00”,说明时间是协调世界时加 8 小时,转换成本地当前时间时,自动按照当前时区“+08:45”,则结果就是:UTC+00:45:00。

另外,还可以通过下面代码来取 UTC:

DateTime timeUtc = DateTime.UtcNow;
// 或者
DateTime timeUtc = DateTime.Now.ToUniversalTime();

这两种方法的优点就是方便快捷,但是时间是以本机时间为准的,会有不准确的风险。

通过网络方式取时间,虽然准确度较高,但是由于需要发送网络请求,因此也会受网络情况的影响,因此在使用时要按需选择。

三、时间戳

时间戳(TimeStamp),通常是一个字符序列,唯一地标识某一刻的时间。数字时间戳技术是数字签名技术一种变种的应用。

在计算机中,时间戳一般是指 Unix 时间戳,即自从 Unix 纪元(格林威治时间 1970 年 1 月 1 日 00:00:00.000)到当前时间的秒/毫秒/微秒数。

下面简单列举几种时间戳和时间互相转换的方法:

3.1 通过类 DateTimeOffset 互相转换

时间转时间戳:

static void Main(string[] args)
{
    Console.WriteLine($"DateTime.Now:                                                {DateTime.Now}");
    Console.WriteLine($"DateTime.UtcNow:                                             {DateTime.UtcNow}");
    Console.WriteLine($"new DateTimeOffset(DateTime.Now).ToUnixTimeSeconds():        {new DateTimeOffset(DateTime.Now).ToUnixTimeSeconds()}"); // 秒
    Console.WriteLine($"new DateTimeOffset(DateTime.UtcNow).ToUnixTimeSeconds():     {new DateTimeOffset(DateTime.UtcNow).ToUnixTimeSeconds()}"); // 秒
    Console.WriteLine($"new DateTimeOffset(DateTime.UtcNow).ToUnixTimeMilliseconds():{new DateTimeOffset(DateTime.UtcNow).ToUnixTimeMilliseconds()}"); // 毫秒
    Console.ReadLine();
}

时间戳转时间:

public static DateTime GetTimeByTimeStamp(long timestamp)
{
    DateTime dt_back = DateTimeOffset.FromUnixTimeSeconds(timestamp).LocalDateTime; // 秒
    //DateTime dt_back = DateTimeOffset.FromUnixTimeMilliseconds(timestamp).LocalDateTime; // 毫秒
    return dt_back;
}

3.2 通过时间差互相转换

时间转时间戳:

public static long GetTimeStamp(DateTime starttime)
{
    TimeSpan ts = starttime.ToUniversalTime() - new DateTime(1970, 1, 1); // ToUniversalTime():将时间转换为 UTC
    long timestamp = (long)ts.TotalSeconds; // 秒  10 位
    //long time = (long)ts.TotalMilliseconds; // 毫秒  13 位
    //long time = (long)ts.TotalMicroseconds; // 微秒  16 位
    return timestamp;
}

时间戳转时间:

public static DateTime GetTimeByTimeStamp(long timestamp)
{
    DateTime startTime = TimeZoneInfo.ConvertTimeFromUtc(new DateTime(1970, 1, 1), TimeZoneInfo.Local); // TimeZoneInfo.Local:本机时区
    DateTime dt_back = startTime.AddSeconds(timestamp); // 秒
    //DateTime dt_back = startTime.AddMilliseconds(timestamp); // 毫秒
    //DateTime dt_back = startTime.AddMicroseconds(timestamp); // 微秒
    return dt_back;
}

3.3 通过 Ticks 取时间戳

Ticks 是时间从 Unix 纪元开始,至开始时间的最小粒度总数,由于秒可以分为 1000,0000 份,因此总粒度除于 1000,0000,得到总的秒数。

public static long GetTimeStamp(DateTime starttime)
{
    long timestamp = (starttime.ToUniversalTime().Ticks - 621355968000000000) / 10000000; // 秒  10 位
    //long timestamp = (starttime.ToUniversalTime().Ticks - 621355968000000000) / 10000; // 毫秒  13 位
    return timestamp;
}

注:本文示例都是通过验证的,有觉不准确或有疑问欢迎留言,有更好的方法实践请不吝赐教。

与DateTime 相关的操作汇总【C# 基础】相似的内容:

DateTime 相关的操作汇总【C# 基础】

关于协调世界时UTC、北京时间、本机时间,如何转成想要的格式,以及时间与时间戳互相转换,这里都有。

【pandas小技巧】--日期相关处理

日期处理相关内容之前`pandas基础`系列中有一篇专门介绍过,本篇补充两个常用的技巧。 # 1. 多列合并为日期 当收集来的数据中,年月日等信息分散在多个列时,往往需要先合并成日期类型,然后才能做分析处理。合并多列转换为日期类型,可以直接用 `to_datetime`函数来处理: ```pytho

[apue] 一图读懂 Unix 时间日期例程相互关系

GMT 和 UTC 时间有何区别?Unix 时间例程为何不处理闰秒?系统时区是如何设置的?哪些时间例程受夏时制影响?localtime 和 gmtime 是否共享内部存储区?strftime 获取第几周使用的 %U/%V/%W 有何区别?linux date 和 mac date 语法有何区别?本文一一为你解答

超越datetime:Arrow,Python中的日期时间管理大师

介绍 Arrow是一个Python库,它提供了一种合理且对人类友好的方法来创建、操作、格式化和转换日期、时间和时间戳。它实现了对datetime类型的更新,填补了功能上的空白,提供了一个智能的模块API,支持许多常见的创建场景。简单来说,它可以帮助您使用更少的导入和更少的代码来处理日期和时间。 Ar

java datetime数据类型去掉时分秒

本文详细介绍了Java DateTime数据类型去掉时分秒的方法示例,为了便于读者理解,给出了两个示例,同时本文也介绍了如何在Java中创建日期和时间对象。

python+requests爬取B站视频保存到本地

import os import datetime from django.test import TestCase # Create your tests here. import requests import re import json import subprocess from conc

Python 函数

函数返回多个返回值 ```python def multiple_return_value(): import datetime d = datetime.date.today() val_1 = '年份为:{}'.format(d.year) val_2 = '月份为:{}'.format(d.m

开源高性能结构化日志模块NanoLog

最近在写数据库程序,需要一个高性能的结构化日志记录组件,简单研究了一下Microsoft.Extensions.Logging和Serilog,还是决定重造一个轮子。 一、使用方法 直接参考以下示例代码: NanoLogger.Start(); DateTime? nullable = null;

[转帖]Mysql Timestamp只能活到2038年?

https://www.jianshu.com/p/3963c9cfafdc MySQL的TIMESTAMP使用 4 个字节存储,保存从1970年1月1日午夜(格林威治时间)以来的秒数,只能表示从 1970 年到 2038 年。 如何替换成DateTime? 1. 修改原来字段的名字; ALTERT

Redis数据存储和读写

今天工作群里,有小伙伴问了一个问题,从Redis获取的数据,一会是0,一会是OK。 这引起了我们对Redis数据存储和读写的疑问。 以下是整理的一些技术研究内容。 在 Redis 中,所有的数据存储都是基于字符串的。无论你插入的是 String、int 还是 DateTime 类型的数据,最终都会以