c# Math、DataTime对象梳理
C# Math类重要的属性和方法
C# 中的 Math 类位于 System 命名空间下,是一个静态密封类,提供了大量常用的数学常数和静态方法,无需实例化即可直接使用。下面按类别梳理最重要的属性和方法:
A.重要常量(属性)
|
常量 |
代码表示 |
近似值 |
说明 |
|
圆周率 π |
Math.PI |
3.14159265358979 |
圆的周长与直径之比 |
|
自然对数底 e |
Math.E |
2.71828182845905 |
自然对数的底数 |
|
τ(Tau) |
Math.Tau |
6.28318530717959 |
一周的弧度数(= 2π),.NET Core 3.0+ 引入 |
B.核心方法
1. 基础数学运算
|
方法 |
功能 |
示例 |
结果 |
|
Abs(x) |
返回绝对值 |
Math.Abs(-5) |
5 |
|
Sign(x) |
返回符号(-1 / 0 / 1) |
Math.Sign(-3) |
-1 |
|
Max(a, b) |
返回较大值 |
Math.Max(3, 7) |
7 |
|
Min(a, b) |
返回较小值 |
Math.Min(3, 7) |
3 |
|
Clamp(value, min, max) |
将值限制在指定范围内 |
Math.Clamp(15, 0, 10) |
10 |
2. 幂与根
|
方法 |
功能 |
示例 |
结果 |
|
Pow(x, y) |
返回 x 的 y 次幂 |
Math.Pow(2, 3) |
8 |
|
Sqrt(x) |
返回平方根 |
Math.Sqrt(16) |
4 |
|
Cbrt(x) |
返回立方根 |
Math.Cbrt(27) |
3 |
|
Exp(x) |
返回 e 的 x 次幂 |
Math.Exp(1) |
2.71828 |
3. 取整与舍入
|
方法 |
功能 |
示例 |
结果 |
|
Floor(x) |
向下取整(向负无穷) |
Math.Floor(2.9) → 2,Math.Floor(-2.9) → -3 |
|
|
Ceiling(x) |
向上取整(向正无穷) |
Math.Ceiling(2.1) → 3,Math.Ceiling(-2.1) → -2 |
|
|
Round(x) |
四舍六入五取偶(银行家舍入) |
Math.Round(2.5) → 2,Math.Round(3.5) → 4 |
|
|
Round(x, digits) |
保留指定位数小数 |
Math.Round(3.14159, 2) |
3.14 |
|
Truncate(x) |
截断取整(直接舍弃小数) |
Math.Truncate(2.9) → 2,Math.Truncate(-2.9) → -2 |
注意:Round 默认采用银行家舍入法(四舍六入五取偶),如需传统四舍五入,可使用 Math.Round(x, MidpointRounding.AwayFromZero)。
C# DateTime对象重要的属性和方法
C# 中的 DateTime 是 System 命名空间下的一个值类型结构体,用于表示日期和时间,精度可达 100 纳秒(1 tick)。下面按类别梳理最重要的属性和方法。
一、静态属性(获取当前时间)
表格
|
属性 |
返回值 |
说明 |
|
DateTime.Now |
当前本地时间 |
返回你所在时区的当前日期和时间,包含时区偏移 |
|
DateTime.UtcNow |
当前 UTC 时间 |
返回协调世界时,不受本地时区影响,适合跨时区存储 |
|
DateTime.Today |
当前日期 |
返回当前日期,时间部分为 00:00:00 |
示例(基于当前时间 2026-05-18 17:36:46):
DateTime now = DateTime.Now; // 2026-05-18 17:36:462DateTime utc = DateTime.UtcNow; // 2026-05-18 09:36:46(假设东八区)3DateTime today = DateTime.Today; // 2026-05-18 00:00:00
二、实例属性(获取日期时间的组成部分)
表格
|
属性 |
类型 |
说明 |
示例值 |
|
Year |
int |
年份 |
2026 |
|
Month |
int |
月份(1-12) |
5 |
|
Day |
int |
日(1-31) |
18 |
|
Hour |
int |
小时(0-23) |
17 |
|
Minute |
int |
分钟(0-59) |
36 |
|
Second |
int |
秒(0-59) |
46 |
|
Millisecond |
int |
毫秒(0-999) |
0 |
|
DayOfWeek |
DayOfWeek |
星期几(枚举) |
DayOfWeek.Monday |
|
DayOfYear |
int |
一年中的第几天(1-366) |
138 |
|
TimeOfDay |
TimeSpan |
当天已过的时间 |
17:36:46 |
|
Ticks |
long |
自 0001-01-01 以来的刻度数 |
637,xxx,xxx,xxx,xxx,xxx |
|
Kind |
DateTimeKind |
时间种类(Utc/Local/Unspecified) |
Local |
三、常用方法
1. 时间加减运算(返回新实例,原对象不变)
|
方法 |
说明 |
示例 |
|
AddDays(n) |
加/减 n 天 |
now.AddDays(1) → 明天同一时间 |
|
AddHours(n) |
加/减 n 小时 |
now.AddHours(-2) → 两小时前 |
|
AddMinutes(n) |
加/减 n 分钟 |
now.AddMinutes(30) → 半小时后 |
|
AddMonths(n) |
加/减 n 个月 |
now.AddMonths(1) → 下个月同一天 |
|
AddYears(n) |
加/减 n 年 |
now.AddYears(-1) → 去年今天 |
|
AddSeconds(n) |
加/减 n 秒 |
now.AddSeconds(10) → 10 秒后 |
|
AddMilliseconds(n) |
加/减 n 毫秒 |
now.AddMilliseconds(500) → 半秒后 |
|
AddTicks(n) |
加/减 n 个刻度 |
now.AddTicks(10000) → 1 毫秒后 |
重要提醒:DateTime 是不可变类型,所有 AddXxx() 方法都返回新实例,原对象不变。必须将返回值赋给变量:
// 错误写法:dt.AddDays(1); // 返回值被丢弃,dt 不变2
// 正确写法:dt = dt.AddDays(1);
2. 时间差计算
|
表格方法/运算符 |
说明 |
示例 |
|
Subtract(DateTime) |
返回 TimeSpan 时间差 |
dt2.Subtract(dt1) |
|
Subtract(TimeSpan) |
减去一个时间间隔 |
dt.Subtract(TimeSpan.FromDays(7)) |
|
- 运算符 |
两个 DateTime 相减 |
dt2 - dt1 |
示例:
DateTime start = new DateTime(2026, 5, 1);
DateTime end = new DateTime(2026, 5, 18);
TimeSpan diff = end - start;4Console.WriteLine(diff.Days); // 输出:17
3. 比较方法
|
方法 |
说明 |
|
Compare(dt1, dt2) |
静态方法,返回 -1(dt1 < dt2)、0(相等)、1(dt1 > dt2) |
|
CompareTo(dt) |
实例方法,与另一个 DateTime 比较 |
|
Equals(dt) |
判断两个 DateTime 是否相等 |
|
==、!=、<、>、<=、>= |
直接使用比较运算符 |
4. 格式化与转换
|
方法 |
说明 |
示例 |
|
ToString("格式") |
按自定义格式输出 |
now.ToString("yyyy-MM-dd HH:mm:ss") → 2026-05-18 17:36:46 |
|
ToShortDateString() |
短日期格式 |
2026/5/18 |
|
ToLongDateString() |
长日期格式 |
2026年5月18日 |
|
ToShortTimeString() |
短时间格式 |
17:36 |
|
ToLongTimeString() |
长时间格式 |
17:36:46 |
|
ToUniversalTime() |
转换为 UTC 时间 |
|
|
ToLocalTime() |
转换为本地时间 |
常用自定义格式符:
yyyy — 四位年份
MM — 两位月份(01-12)
dd — 两位日期(01-31)
HH — 24小时制小时(00-23)
mm — 分钟(00-59)
ss — 秒(00-59)
fff — 毫秒
dddd — 星期几(中文)
示例(中文格式):
var culture = new System.Globalization.CultureInfo("zh-CN");
string cnDate = now.ToString("yyyy年M月d日 dddd HH:mm:ss", culture);
// 输出:2026年5月18日 星期一 17:36:46
5. 字符串解析
|
方法 |
说明 |
推荐度 |
|
Parse(string) |
解析字符串,失败抛异常 |
⭐⭐ |
|
TryParse(string, out DateTime) |
安全解析,返回是否成功 |
⭐⭐⭐⭐⭐ |
|
ParseExact(string, format, provider) |
按指定格式解析,失败抛异常 |
⭐⭐⭐ |
|
TryParseExact(string, format, provider, out DateTime) |
按指定格式安全解析 |
⭐⭐⭐⭐⭐ |
推荐用法(生产环境):
string input = "2026-05-18 17:36:46";
if (DateTime.TryParse(input, out DateTime result))
{
Console.WriteLine(result); // 解析成功
}
else
{
Console.WriteLine("日期格式无效");
}
6. 其他实用方法
|
方法 |
说明 |
|
DateTime.IsLeapYear(year) |
判断指定年份是否为闰年 |
|
DateTime.DaysInMonth(year, month) |
返回指定月份的天数 |
|
DateTime.SpecifyKind(dt, kind) |
为 DateTime 指定 Kind 属性 |
四、常见陷阱与最佳实践
不可变性:所有 AddXxx() 方法都返回新实例,务必赋值。
Kind 属性:存储到数据库时建议统一使用 DateTime.UtcNow,展示时再转本地时间,避免时区混乱。
解析字符串:永远优先使用 TryParse 或 TryParseExact,避免 Parse 抛异常导致程序崩溃。
性能:高频循环中不要反复调用 DateTime.Now,应提前取一次复用。
精度:DateTime 精度为 100 纳秒,但 DateTime.Now 的实际精度通常受操作系统限制(约 1-15 毫秒)。
五、实际应用示例
计算两个日期之间相差的天数:
DateTime start = new DateTime(2026, 1, 1);
DateTime end = DateTime.Now;
int daysPassed = (end - start).Days;
Console.WriteLine($"2026年已过去 {daysPassed} 天");
判断某日是否为周末:
DateTime date = DateTime.Now;
bool isWeekend = date.DayOfWeek == DayOfWeek.Saturday || date.DayOfWeek == DayOfWeek.Sunday;
获取本月第一天和最后一天:
DateTime firstDay = new DateTime(DateTime.Now.Year, DateTime.Now.Month, 1);
DateTime lastDay = firstDay.AddMonths(1).AddDays(-1);
这些属性和方法覆盖了日常开发中 95% 以上的日期时间处理需求,熟练掌握它们能让你在处理时间相关逻辑时游刃有余。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace _1.Math和DataTime对象
{
internal class Program
{
static void Main(string[] args)
{
/*int[] ints = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
int max = 0;
for (int i = 0; i < ints.Length; i++)
{
var first = ints[i];
if (i == 0)
{
var second = ints[i + 1];
if (first > second)
{
max = first;
}
else
{
first = second;
}
}
else
{
if (first > max)
{
max = first;
}
}
}
Console.WriteLine(max);*/
Console.WriteLine(Math.Max(10, 20));
int[] ints = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
Console.WriteLine(ints.Max());
/* string str = "hello";
str.Dongshuhua(); // 在使用扩展方法时,第一个参数不需要传递,为啥,谁调用的扩展方法,谁就是第一个参数。
str.Dongshuhua2(10, "hello");*/
Console.WriteLine(Math.Round(20.1));
Console.WriteLine(Math.Round(20.51));
Console.WriteLine(Math.Round(20.55));
Console.WriteLine(Math.Round(20.56));
Console.WriteLine(Math.Round(20.6));
Console.WriteLine("----------------");
Console.WriteLine(Math.Round(21.5));
Random random = new Random();
int result = random.Next(100) + 1;// 0-99
int result2 = random.Next(1, 101);
DateTime dt = new DateTime();
Console.WriteLine(dt.ToString());
Console.WriteLine(DateTime.Now);
DateTime dt2 = new DateTime(2026, 5, 9, 10, 28, 30);
Console.WriteLine(dt2.ToString());
DateTime dt3 = DateTime.Parse("2026-5-19 10:29:34.999");
Console.WriteLine(dt3.ToString("yyyy年MM月dd日"));
Console.WriteLine(dt3.ToString("HH时mm:ss:fff"));
dt3.AddDays(-1);
DateTime now = DateTime.Now;
Console.WriteLine($"当前日期:{now}");
Console.WriteLine($"当前日期的年月日:{DateTime.Today.ToString("yyyy-MM-dd")}");
Console.WriteLine($"当前日期的年月日:{now.Year}-{now.Month.ToString().PadLeft(2, '0')}-{now.Day}");
Console.WriteLine($"当前日期的年月日:{now.DayOfWeek}");
Console.WriteLine($"当前日期的年月日:{now.ToString("dddd")}");
Console.WriteLine($"当前日期的年月日:{now.Ticks}");
Console.WriteLine($"当前日期的年月日:{DateTime.Now.Ticks}");
Thread.Sleep(1000); // 休眠1秒
Console.WriteLine($"当前日期的年月日:{DateTime.Now.Ticks}");
Console.WriteLine($"当前日期加1天:{now.AddDays(1)}");
Console.WriteLine($"当前日期减1天:{now.AddDays(-1)}");
DateTime firstDateTime = DateTime.Now;
DateTime secondDateTime = new DateTime(2026, 5, 23, 11, 15, 30);
if (secondDateTime > firstDateTime)
{
TimeSpan timeSpan = secondDateTime - firstDateTime;
Console.WriteLine($"secondDateTime大, {secondDateTime - firstDateTime}");
}
TimeSpan timeSpan2 = secondDateTime.Subtract(firstDateTime);
Console.WriteLine($"secondDateTime大, {timeSpan2}");
Console.WriteLine($"当前日期减去7天, {now.Subtract(TimeSpan.FromDays(3))}");
(年份 % 4 == 0 且 年份 % 100 != 0) 或 (年份 % 400 == 0)
int year = 2000;
if(year % 4 == 0 && year % 100 != 0 || year % 400 == 0)
{
Console.WriteLine("是闰年");
}
// 规律:Is,Can, Contains,Try开头一般返回布尔值
Console.WriteLine(DateTime.IsLeapYear(2000));
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace _1.Math和DataTime对象
{
// 给某个已存在的类添加扩展方法有几个要求:
// 1。创建类是静态类且不是泛型类,一般建议以Extension结尾
// 2。方法必须是静态的
// 3。第一个参数是方法扩展谁身上了。
public static class StringExtension
{
// this 表示Dongshuahua扩展到谁身上。
public static void Dongshuhua(this string str) {
Console.WriteLine("给字符串扩展一个Dongshuhua");
}
public static string Dongshuhua2(this string str, int count, string str2)
{
return count.ToString() + str2;
}
}
}
定时器
方法一
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace 定时器1
{
internal class Program
{
static void Main(string[] args)
{
// System.Threading.Timer 是 C# 中一个非常轻量且高效的定时器,它基于线程池工作,非常适合在后台执行周期性的任务,比如定时刷新数据、心跳检测或延迟操作。
// 参数1: 回调方法 (这里使用 Lambda 表达式),回调函数:回头调用。
// 参数2: 状态对象 (把当前时间当成参数传递给回调方法,s变量接收此参数)
// 参数3: dueTime - 0 毫秒 (首次触发间隔时间,单位毫秒) 延迟时间
// 参数4: period - 1000 毫秒 (首次之后每次触发间隔时间,单位毫秒)
Timer t = new Timer((s) =>
{
//Console.WriteLine($"定时器触发: {DateTime.Now:HH:mm:ss.fff}, 状态: {s}");
//Console.WriteLine($"定时器触发: {DateTime.Now:yyyy-MM-dd HH:mm:ss}");
Console.Clear();
Console.WriteLine($"定时器触发: {DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}");
}, DateTime.Now, 0, 1000);
// 定时器:每间隔一段时间(单位毫秒)执行一次指定的任务
/*System.Threading.Timer timer1 = null; // 线程安全
System.Timers.Timer timer2 = null;*/
Console.WriteLine("定时器已启动。按 'q' 键退出程序...");
// 2. 主线程等待用户输入,防止程序立即退出,按 Q 键退出循环
while (Console.ReadKey().Key != ConsoleKey.Q)
{
}
// 3. 释放 Timer 资源
// 使用 ManualResetEvent 确保所有回调执行完毕后再退出
using (var waitHandle = new ManualResetEvent(false))
{
// Dispose(waitHandle) 会等待所有正在执行的回调完成
t?.Dispose(waitHandle);
waitHandle.WaitOne();
}
Console.WriteLine("定时器已释放,程序退出。");
}
}
}
方法二
using System;
using System.Collections.Generic;
using System.Data.SqlTypes;
using System.Linq;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Threading.Tasks;
using System.Timers;
namespace 定时器2
{
internal class Program
{
public delegate string MyDelegate(string s);// 定义一个委托,和方法相似,比方法多了一个关键字delegate。
public event ElapsedEventHandler MyEvent; // 定义一个事件
static void Main(string[] args)
{
// 实例化一个定时器
Timer timer = new Timer();
// 重要属性
timer.Interval = 1000; // 定时器的间隔时间,单位毫秒
//timer.Enabled = true; // 启动定时器
//timer.Enabled = false; // 禁用定时器
// 事件:是委托实例。方法可以当成委托的参数。 方法参数:int,string,等,见过方法的参数中传递方法吗?
//timer.Elapsed += new ElapsedEventHandler(ElapsedHandler);
timer.Elapsed += ElapsedHandler;
// 重要的方法
timer.Start();
//timer.Stop();
// 主线程等待用户输入
while (true)
{ }
//public event ElapsedEventHandler Elapsed; // 定义事件 委托的签名
// int a ;
//Method2(Method1);
//Method2(Method3); // Method3不能添加小括号,加了小括号表示Method3()执行过了。
//MyDelegate myDelegate = new MyDelegate(Method1);
//MyDelegate myDelegate = Method1;
//Method2(myDelegate);
//MyDelegate myDelegate2 = new MyDelegate(Method3);
//Method2(myDelegate2);
}
private static void ElapsedHandler(object sender, EventArgs e)
{
Console.WriteLine(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
}
// 需求:把Method1当成Method2的参数传递到Method2中。
// 通过回调函数(方法),使用委托实现回调。
// Method1方法是否能满足委托MyDelegate? 能,方法的返回值和方法参数满足了委托的定义
// 委托的出现:主要为了让方法的参数,再传递一个方法。传递的方法称为回调函数。
// 事件本质是委托的实例。委托是方法的代理。 代理==包工头 代理记账公司(委托)==财务人员(方法)
static string Method1(string str)
{
return str;
}
static string Method3(string str)
{
return str;
}
static void Method2(MyDelegate myDelegate)
{
var result = myDelegate.Invoke("hello"); // 调用委托,侧面就相当执行了Method1()
Console.WriteLine(result);
}
}
}
更多推荐


所有评论(0)