C# 基础知识系列- 13 常见类库介绍(二)日期时间类
liebian365 2024-11-04 14:28 19 浏览 0 评论
0. 前言
上一篇内容介绍了Console类和Math类,这篇内容着重介绍一下C#中时间日期的处理方式。
上一篇勘误: 上一篇中关于静态类没有构造函数,这一表述有误。正确的说法是C#中静态类不包含常规构造函数,但可以添加一个静态构造函数。 静态构造函数与普通普通构造函数的区别是,静态构造函数没有访问修饰符,即访问修饰符是默认的,且静态构造函数只能是无参的,并添加 static 修饰符;静态构造函数不能手动调用,会在类加载的时候由系统自己加载。
1 DateTime 和 TimeSpan
DateTime表示时间点,TimeSpan表示 时间段。在C#中,这两个都是结构体,结构体与类都能继承并实现接口,但是与类不同的是结构体在内存中存放在栈里。这部分在微软官方文档中关于CLR有过介绍。后续也会针对CLR写一个系列。这里就不做过多的介绍了。
DateTime延伸开来也有很多内容要讲,这里只做一个大体的介绍:
1. 创建一个DateTime
DateTime time = new DateTime(2018,1,20);// 2018年1月20日 0时0分0秒
DateTime time = new DateTime(2019,11,30, 12, 01, 59);// 2019年11月30日,12:01:59
DateTime time = DateTime.Now;// 表示代码运行到这里的系统时间,一般意义上的当前时间
DateTime time = new DateTime(long ticks);// 以时间刻度计算日期,以公历 0001 年 1 月 1 日 00:00:00.000 以来所经历的以 100 纳秒为间隔的间隔数来表示
这些是我们常用的创建日期的方法,还有一些通过日历对象结合日历来创建日期时间,不过这块在不涉及到程序国际化之前不需要做过多的深入。
需要注意的是,DateTime.Now在每次运行结果都不一样,这个属性返回的是系统运行时当前时间,而不是程序编写时的时间。与之对应的还有一个DaTime.Year,这个属性返回结果是当天,也就是Now去掉时分秒的时间。
2. 日期变更
DateTime提供了很多可以变更日期的方法,这些方法可以获取一个计算之后的时间值:
public DateTime AddDays (double value);// 计算天数,正数代表 天数增加,负数代表天数减少
public DateTime AddHours (double value);// 返回一个新的 DateTime,它将指定的小时数加到此实例的值上。
public DateTime AddMilliseconds (double value);//返回一个新的 DateTime,它将指定的毫秒数加到此实例的值上。
public DateTime AddMonths (int months);//返回一个新的 DateTime,它将指定的月数加到此实例的值上
public DateTime AddMonths (int months);// 返回一个新的 DateTime,它将指定的月数加到此实例的值上
public DateTime AddSeconds (double value);/// 返回一个新的 DateTime,它将指定的秒数加到此实例的值上。
public DateTime AddTicks (long value);// 返回一个新的 DateTime,它将指定的刻度数加到此实例的值上,也就是构造函数里的ticks
public DateTime AddYears (int value);//返回一个新的 DateTime,它将指定的年份数加到此实例的值上。
以上是DateTime类对日期计算的支持,其中参数如果是正的表示时间后移,如果是负的则表示时间向前移。
需要注意的一点就是,日期的变更不会在原有的DateTime元素上变更,会返回一个计算之后的日期类型。
3. 日期算术运算
说了这么多DateTime,没有介绍TimeSpan,那么这里就会介绍一下TimeSpan是什么了。TimeSpan表示一个时间间隔,也就是两个DateTime之间的差值。说到这里,大家也应该明白日期的算术运算应该是指什么了。以下来看一组示例:
class Program
{
static void Main(string[] args)
{
DateTime lastYear = new DateTime(2019, 03, 08, 20,49, 36);
DateTime now = DateTime.Now;
TimeSpan span = now - lastYear;
DateTime newTime = lastYear + span;
}
}
这就是C#中关于日期运算的基本内容。那我们来看看 TimeSpan里封装了哪些内容吧。
TimeSpan的属性:
public int Days { get; }//获取当前 TimeSpan 结构所表示的时间间隔的天数部分。
public int Hours { get; }// 获取当前 TimeSpan 结构所表示的时间间隔的小时数部分。
public int Milliseconds { get; }//获取当前 TimeSpan 结构所表示的时间间隔的毫秒数部分。
public int Minutes { get; }//获取当前 TimeSpan 结构所表示的时间间隔的分钟数部分。
public int Seconds { get; }//获取当前 TimeSpan 结构所表示的时间间隔的秒数部分。
以上属性表示一个TimeSpan的代表的时间间隔中的天数、小时、分钟等。
public double TotalDays { get; }//获取以整天数和天的小数部分表示的当前 TimeSpan 结构的值。
public double TotalHours { get; }//获取以整小时数和小时的小数部分表示的当前 TimeSpan 结构的值。
public double TotalMinutes { get; }//获取以整分钟数和分钟的小数部分表示的当前 TimeSpan 结构的值。
public double TotalSeconds { get; }//获取以整秒数和秒的小数部分表示的当前 TimeSpan 结构的值。
public double TotalMilliseconds { get; }//获取以整毫秒数和毫秒的小数部分表示的当前 TimeSpan 结构的值。
上述几组属性表示以XXX为单位,返回的TimeSpan的值,与之相对应的TimeSpan提供了一组FormXXX的方法,可以将double类型的值还原成TimeSpan。
因为TimeSpan表示时间间隔,所以TimeSpan也允许两个TimeSpan进行加法运算,并提供了一个Add(TimeSpan ts)的方法。
这些是TimeSpan最常用的一些属性和方法。不过在使用TimeSpan中需要注意的地方是,TimeSpan计算返回的值可正可负,正值表示时间间隔的头在前尾在后,负值表示头在后尾在前;TimeSpan中没有提供TotalMonths这个方法,这是因为每个月具体有多少天不是固定值,如果想计算两个日期直接相差几个月,则需要自定义对应的计算方法了。
4. DateTime与字符串之间的恩怨情仇
在程序中,用户或者三方输入的日期大多都是字符串格式的,而且系统获取到的时间也大多会转成字符串给其他人展示,所以这里就会涉及到DateTime与字符串之间的相互转换。
我们先试试日期的各种ToString会产生什么样的结果:
class Program
{
static void Main(string[] args)
{
DateTime now = DateTime.Now;
Console.WriteLine("ToString :{0}", now.ToString());
Console.WriteLine("ToLongDateString :{0}", now.ToLongDateString());
Console.WriteLine("ToLongTimeString :{0}", now.ToLongTimeString());
Console.WriteLine("ToShortDateString :{0}",now.ToShortDateString());
Console.WriteLine("ToShortTimeString :{0}",now.ToShortTimeString());
}
}
结果:
这是DateTime的默认输出结果,当然会根据系统的语言和地区等设置变化而产生不同的变化。为了避免这种变化,C#提供了一种日期类型的格式化模板,这里介绍几个常用的格式代表:
格式符 含义 yy 年份。00~99,如果年份大于99,则只保留后两位。如2020年则显示20,2019年则显示19 yyyy 年份,显示四位。0000~9999 M 月份,显示1~12 MM 月份,显示01~12 d 天,1~31(具体看月份允许的最大天数) dd 与d一致,显示为01~31 h 小时,12小时制显示1~12 hh 与h一致,显示为01~12 H 小时,24小时制,显示0~23 HH 小时,24小时制,显示00~23 m 分钟,显示0~59 mm 分钟,显示00~59 s 秒,显示0~59 ss 秒,显示00~59 f 表示日期和时间值的十分之几秒,显示0~9 ff 表示百分之几秒,显示00~99
最后的f,f的次数越多精度越细,但需要考虑系统的时钟精度。
在实际开发中,最常用的格式是:yyyy-MM-dd HH:mm:ss,显示效果就是:2020-04-25 12:00:00。其中连接符可以根据开发需求更换。
上述是时间转字符串,反过来也有字符串转时间。
使用DateTime.Parse或者Convert.ToDateTime就可以将字符串转换为时间类型。C#并不需要在字符串转日期的时候指定字符串的显示格式,这是因为一个约定优于配置的设计理念。C#通过分析字符串,然后将字符串转换成对应的时间类型。当然,在正确解析到时间的时候,C#会抛出异常。为此,C#提供了DateTime.TryParse方法,该方法不会抛出异常,会返回一个是否正确转换的bool值。
它的声明如下:
public static bool TryParse (string s, out DateTime result);// 使用了result作为实际转换结果
虽然C# 不用提供转换格式就可以读取,但是如果时间字符串的格式比较少见呢,或者说就想指定一个格式字符串,怎么办?别急,C#还提供了一个方法:
public static DateTime ParseExact (string s, string format, IFormatProvider provider);
不过,这个方法需要指定一个区域性的格式信息:provider。这个信息可以通过CultureInfo.CurrentCulture来获取,这个属性表示系统的当前区域信息。
以上是DateTime的基本内容,有兴趣的小伙伴可以查阅一下微软的官方文档继续深入研究一下。
更多内容烦请关注我的博客《高先生小屋》
相关推荐
- [西门子PLC] S7-1200PLC中所支持的数据类型详解
-
数据类型呢,就是讲数据的长度和属性的,也就是指定数据元素的大小,还有怎么去解释数据。每个指令起码得支持一种数据类型,有的指令还能支持好多种数据类型。所以呀,指令上用的操作数的数据类型一定得跟指令支持的...
- C语言wctomb函数详解:宽字符到多字节字符的「翻译官」
-
核心定位wctomb是C语言中用于将宽字符转换为多字节字符的「翻译官」,它能将单个宽字符(wchar_t)转换为多字节字符(如UTF-8编码的中文)。就像一位翻译官,它能将一种语言(宽字符)翻译成...
- Python 中数组和列表之间的区别(python列表和c语言数组区别)
-
在这篇文章中,您将了解Python中数组和列表之间的区别。Python列表Python列表是一种内置数据结构,是包含在方括号[]的元素集合。它们具有许多独特的属性,使它们与其他数据结构不同。有...
- Linux内核设计与实现—进程管理(linux内核原理与实现)
-
进程进程就是处于执行期的程序(目标码存放在某种存储介质上)。进并不仅仅局限于一段可执行程序代码(Unix称其为代码段,textsection)。通常进程还要包含其他资源,像打开的文件,挂起的信号,...
- 实际工程项目中西门子S7-1500如何批量读取和写入机器人信号
-
方法一:DPRD_DAT:读取DP标准从站的一致性数据该指令适用于中央模块以及DP标准从站和PROFINETIO设备。可以使用以下数据类型:BOOL,BYTE,CHAR,WCHAR,WO...
- C语言mbstowcs函数详解:多字节字符串到宽字符的「翻译官」
-
核心定位mbstowcs是C语言中用于将多字节字符串转换为宽字符字符串的「翻译官」,它能将多字节字符(如UTF-8编码的中文)转换为宽字符(wchar_t)。就像一位翻译官,它能将一种语言(多字节...
- C语言mbtowc函数详解:多字节字符到宽字符的「翻译官」
-
核心定位mbtowc是C语言中用于将多字节字符转换为宽字符的「翻译官」,它能将单个多字节字符(如UTF-8编码的中文)转换为宽字符(wchar_t)。就像一位翻译官,它能将一种语言(多字节字符)翻...
- 西门子PLC系列连载|No.5 初识西门子1200PLC数据类型
-
导语:在之前的文章中我们介绍了PLC的相关基础知识和一些小的程序段,也讲解过博途软件使用的一些基本方法。那么我们在本章内容将为大家讲解关于西门子1200系列PLC的常用数据类型,以及这些数据类型的区别...
- 计算机中常见的字符编码及存储方式
-
常见的字符编码ASCII、GBK、GB2312、Unicode等等常识用多个字节来代表的字符称之为宽字符,而Unicode码只是宽字符编码的一种实现,宽字符并不一定是Unicodechar窄字...
- 西门子SCL高级语言之数据转换介绍
-
(整数转浮点数INT_TO_REAL)我们在做项目中经常用到各种类型的数据,这就需要转换(CONVERT)指令来转换,由于博途数据转换指令只有它一个,那我们就只记住它就可以了,注意设置需要转换...
- SCL编程语言学习(2)-启保停电路(起保停电路plc程序)
-
“启保停”电路是学习过程中最常见的一个案例,也是最简单易懂的控制程序。如果采用梯形图编程,如图1所示。在实际工程的电路中,很少有这么简单的起保停电路,一般都需要考虑急停、限位、过载保护等多项因素,启停...
- GCC的常用编译选项(gcc编译工具)
-
GCC(GNUCompilerCollection,GNU编译器套件)是由GNU开发的编程语言译器。对于C语言源代码文件,使用GCC生成可执行文件的过程不仅仅是编译的过程,而是要经历四个相...
- 「C语言」初始化数组,C语言中初始化特定列表和元素
-
如果没有显式地初始化数组变量,那么就会采用一般规则:如果数组具有动态存储周期,那么数组元素的值就是没有定义的。否则,所有的元素都会被默认地初始化为0(如果数组元素是指针,则会被初始化为NULL)。编...
- C++11新特性(c++11新特性 lambda)
-
1、智能指针2、Lambda表达式3、线程库4、原子操作5、统一的列表初始化{}6、右值引用和移动构造7、引入nullptr指针8、类型推导auto和decltype智能指针:智能指针是一个...
- 西门子 S7-1200 PLC 数据类型详解
-
关注“PLC发烧友”,一起涨知识!回复:西门子全套,领西门子系列PLC电子资料包!数据类型用来描述数据的长度和属性,即用于指定数据元素的大小及如何解释数据,每个指令至少支持一个数据类型,而部分指令支持...
你 发表评论:
欢迎- 一周热门
- 最近发表
- 标签列表
-
- wireshark怎么抓包 (75)
- qt sleep (64)
- cs1.6指令代码大全 (55)
- factory-method (60)
- sqlite3_bind_blob (52)
- hibernate update (63)
- c++ base64 (70)
- nc 命令 (52)
- wm_close (51)
- epollin (51)
- sqlca.sqlcode (57)
- lua ipairs (60)
- tv_usec (64)
- 命令行进入文件夹 (53)
- postgresql array (57)
- statfs函数 (57)
- .project文件 (54)
- lua require (56)
- for_each (67)
- c#工厂模式 (57)
- wxsqlite3 (66)
- dmesg -c (58)
- fopen参数 (53)
- tar -zxvf -c (55)
- 速递查询 (52)