目录
一、基础Demo
可直接拷贝到控制台程序运行
class Test
{
public static bool IsWeekend(DateTime date)//判断是否周末
{
return date.DayOfWeek == DayOfWeek.Saturday || date.DayOfWeek == DayOfWeek.Sunday;
}
static void Main(string[] args)
{
//1.格式化
//(1)字符串转日期
//1.转化成功返回True 并且把变量输出到Changetime
bool isFormatTime = DateTime.TryParse("2024-11-30",out DateTime Changetime);
//2.转化成功则输出,否则返回今日
DateTime Changetime2 = DateTime.TryParse("2024-11-30", out DateTime temp) ? temp : DateTime.Today;
//(2)日期转字符串
string dateTimenow = DateTime.Now.ToString("yyyy/MM-dd");//2023/11-17
string dateTimenow2 = DateTime.Now.ToString("HH:mm");//15:00
//2.年月日时分秒
int d1 = dateTime.Year;
int d2 = dateTime.Month;
int d3 = dateTime.Day;
int d4 = dateTime.Hour;
int d5 = dateTime.Minute;
int d6 = dateTime.Second;
DateTime resulttime = dateTime.Date;//打印完整日期:2023/11/11 0:00:00
string resulttime2 = dateTime.ToShortDateString();//打印短日期:2023/11/11
string resulttime3 = dateTime.ToShortTimeString();//打印短时间:0:00
string resulttime4 = dateTime.ToLongTimeString();//打印长时间:0:00:00
string resulttime5 = dateTime.ToLongDateString();//打印长时间:2023年11月11日
//3.修改时间
//修改前
DateTime d7 = DateTime.Parse("2024-01-01 12:00:00");//2024/1/1 12:00:00
// 修改年、月、日
DateTime d7_1 = new DateTime(2025, 02, 03, d7.Hour, d7.Minute, d7.Second, DateTimeKind.Local);//2025/2/3 12:00:00
// 修改时、分、秒
DateTime d7_2 = new DateTime(d7.Year, d7.Month, d7.Day, 15, 30, 45, DateTimeKind.Local);//2025/2/3 15:30:45
//【更好的方法】修改时、分、秒,先清空后加上:
DateTime d7_2_1 = d7.Date.Add(new TimeSpan(15, 30, 45));//2024/1/1 15:30:45
//4.日期计算
DateTime d8 = DateTime.Now;//获取今天日期
DateTime d9 = dateTime.AddDays(1);//增加一天
DateTime d10 = dateTime.AddDays(-1);//减少一天
//5.判断是否为周末
bool isWeekend = IsWeekend(dateTime.Date);//True
//6.比较时间早晚(越晚越大)
Console.WriteLine(DateTime.Parse("2023-12-01") > DateTime.Parse("2024-12-01"));//输出false
//7.判断时间是否是默认值"0001-01-01 00:00:00"
//若b=true则该时间是默认值
DateTime d11 = DateTime.Parse("0001-01-01 00:00:00");
DateTime d12 = new DateTime();//初始化也有默认值,就是上面这个
bool b = d11 == DateTime.MinValue;
bool b2 = d12 == DateTime.MinValue;
Console.WriteLine(b);//返回True
Console.WriteLine(b2);//返回True
//8.输出指定日期是星期几
var re1 = DateTime.Now.DayOfWeek;//输出字符串,例如Sunday
var re2 = (int)DateTime.Now.DayOfWeek;//输出整形,星期日=0 星期一=1,以此类推
}
}
【日期中等大小写规则】
【注意】HH和hh的区别,MM和mm的区别
在日期格式中,大写和小写字母代表不同的意义:
yyyy:四位数年份(例如,2024)。
MM:两位数月份(01-12)。
dd:两位数日期(01-31)。
HH(大写):24小时制的小时(00-23)。
hh(小写):12小时制的小时(01-12)。
mm:两位数分钟(00-59)。
ss:两位数秒(00-59)。
二、进阶使用
【清空时分秒】
传入2024-06-13 17:03:20,如何传出2024-06-13 00:00:00
DateTime dateTime = new DateTime(2024, 06, 13, 17, 03, 20); // 给定的日期时间
DateTime dateOnly = dateTime.Date; // 这将得到 2024-06-13 00:00:00,会清空时分秒
【时间差计算】
须知:TimeSpan 是时间间隔的意思
1.计算时间差
DateTime dateTime = new DateTime(2024,01,01,10,30,10);
DateTime dateTime2 = new DateTime(2024,01,02,11,20,00);
TimeSpan difference = dateTime2 - dateTime;//差1天 49分 50秒
Console.WriteLine("时间差是" + difference);
Console.WriteLine(difference.Days);//时间差转换为x天(省略后面的时分秒),输出为1
Console.WriteLine(difference.TotalDays);//时间差合计天数
更多的属性:
2.处理时间差
DateTime time = DateTime.Now;
TimeSpan span = time - time;//相同的日期做差
bool b = span == TimeSpan.Zero;
Console.WriteLine(b);//输出True 表示没有时间差
TimeSpan span1 = new TimeSpan();
TimeSpan span2 = new TimeSpan();
var result = span1+span2;
bool bb = result == TimeSpan.Zero;
Console.WriteLine(bb);//输出True 表示没有时间差
【判断是否同年月/同年月日/完全相同】
封装:
// 判断两个日期是否同年同月
public static bool IsSameYearAndMonth(DateTime date1, DateTime date2)
{
return date1.Year == date2.Year && date1.Month == date2.Month;
}
// 判断两个日期是否同年同月同日
public static bool IsSameYearMonthAndDay(DateTime date1, DateTime date2)
{
return date1.Year == date2.Year && date1.Month == date2.Month && date1.Day == date2.Day;
}
// 判断两个日期是否完全相同(包括时间)
public static bool IsSameDate(DateTime date1, DateTime date2)
{
return date1 == date2;
}
调用示例:
static void Main()
{
DateTime date1 = new DateTime(2024, 8, 11, 14, 30, 0);
DateTime date2 = new DateTime(2024, 8, 11, 15, 45, 0);
DateTime date3 = new DateTime(2023, 8, 11, 14, 30, 0);
DateTime date4 = new DateTime(2024, 9, 11, 14, 30, 0);
Console.WriteLine(IsSameYearAndMonth(date1,date4));//false
Console.WriteLine(IsSameYearAndMonth(date1, date2));//true
Console.WriteLine(IsSameYearMonthAndDay(date1,date4));//false
Console.WriteLine(IsSameYearMonthAndDay(date1, date2));//true
Console.WriteLine(IsSameDate(date1,date3));//false
Console.WriteLine(IsSameDate(date3,date3));//true
}
【比早晚+区间判断】(扩展方法)
public static class DateTimeExtensions
{
// 比较两个 DateTime 对象,第一个时间比第二个时间更早吗
public static bool IsEarlier(this DateTime first, DateTime? second)
{
if (second == null)
{
throw new Exception("不能和空时间比较");
}
return first < second ;
}
// 判断一个 DateTime 是否在指定的时间范围(比较年月日时分秒)内
public static bool IsInRange(this DateTime dateTime, DateTime? start, DateTime? end)
{
if (start == null || end == null)
{
return false;
}
else if (start>end)
{
throw new Exception("开始时间不能晚于结束时间!");
}
return dateTime >= start && dateTime <= end;
}
// 判断一个 DateTime 是否在指定的时间范围(只比较时分秒)内
public static bool IsInHourMiniRange(this DateTime dateTime, DateTime? start, DateTime? end)
{
if (start == null || end == null)
{
return false;
}
// 提取时分秒
var timeToCheck = dateTime.TimeOfDay;
var startTime = start.Value.TimeOfDay;
var endTime = end.Value.TimeOfDay;
return timeToCheck >= startTime && timeToCheck <= endTime;
}
// 判断一个 DateTime 是否在指定的时间范围(只比较时分秒)内
public static bool IsInHourMiniRange(this DateTime dateTime, TimeSpan? startTime, TimeSpan? endTime)
{
if (startTime == null || endTime == null)
{
return false;
}
// 提取时分秒
var timeToCheck = dateTime.TimeOfDay;
return timeToCheck >= startTime && timeToCheck <= endTime;
}
}
调用示例:
DateTime dt1 = new DateTime(2023, 5, 1);
DateTime dt2 = new DateTime(2024, 1, 1);
// 比较两个 DateTime 对象
bool b = dt1.IsEarlier(dt2);
Console.WriteLine(b);//true
// 判断一个 DateTime 是否在指定范围内
DateTime rangeStart = new DateTime(2023, 1, 1);
DateTime rangeEnd = new DateTime(2023, 12, 31);
bool isInRange = dt1.IsInRange(rangeStart, rangeEnd);
Console.WriteLine(isInRange);//true
//判断一个 DateTime 是否在指定范围(时分秒)内
DateTime dt11 = new DateTime(2023, 5, 1,10,10,00);
DateTime dt22 = new DateTime(2023, 6, 1,13,00,00);
DateTime dt33 = new DateTime(2024, 1, 1,12,00,00);
Console.WriteLine(dt33.IsInHourMiniRange(dt11,dt22));//true
【输出年月第一天和最后一天】
public class Program
{
/// <summary>
/// 传入一个日期,根据其年月,输出该年月第一天
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
private static DateTime GeFirstDate(DateTime input)
{
int year = input.Year;
int month = input.Month;
DateTime firstDayOfMonth = new DateTime(year, month,1,0,0,0);
return firstDayOfMonth;
}
/// <summary>
/// 传入一个日期,根据其年月,输出该年月最后一天
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
private static DateTime GetLastDate(DateTime input)
{
int year = input.Year;
int month = input.Month;
DateTime lastDayOfMonth = new DateTime(year, month, DateTime.DaysInMonth(year, month),23,59,59);
return lastDayOfMonth;
}
public static void Main()
{
var a = GeFirstDate(DateTime.Now);
var b = GetLastDate(DateTime.Now);
}
}
【输出日期跨度】(跨度:小时、日、月、年)
封装:
/// <summary>
/// 返回两个日期之间的时间值(跨度单位:小时,含开始时间和结束时间)
/// </summary>
/// <param name="start"></param>
/// <param name="end"></param>
/// <returns></returns>
/// <exception cref="Exception"></exception>
public static List<DateTime> GetHourSpanList(DateTime start, DateTime end)
{
List<DateTime> results = new List<DateTime>();
start = new DateTime(start.Year, start.Month, start.Day, start.Hour, 0, 0);
end = new DateTime(end.Year, end.Month, end.Day, end.Hour, 0, 0);
if (start > end)
{
throw new Exception("开启时间不应该晚于结束时间!");
}
else
{
// 迭代日期
var currentDate = start;
while (currentDate <= end)
{
results.Add(currentDate);
currentDate = currentDate.AddHours(1);
}
}
return results;
}
/// <summary>
/// 返回两个日期之间的时间值(跨度单位:日,含开始时间和结束时间)
/// </summary>
/// <param name="start"></param>
/// <param name="end"></param>
/// <returns></returns>
/// <exception cref="Exception"></exception>
public static List<DateTime> GetDailySpanList(DateTime start, DateTime end)
{
List<DateTime> results = new List<DateTime>();
start = new DateTime(start.Year, start.Month, start.Day, 0, 0, 0);
end = new DateTime(end.Year, end.Month, end.Day, 0, 0, 0);
if (start > end)
{
throw new Exception("开启时间不应该晚于结束时间!");
}
else
{
// 迭代日期
var currentDate = start;
while (currentDate <= end)
{
results.Add(currentDate);
currentDate = currentDate.AddDays(1);
}
}
return results;
}
/// <summary>
/// 返回两个日期之间的时间值(跨度单位:月,含开始时间和结束时间)
/// </summary>
/// <param name="start"></param>
/// <param name="end"></param>
/// <returns></returns>
/// <exception cref="Exception"></exception>
public static List<DateTime> GetMonthSpanList(DateTime start, DateTime end)
{
List<DateTime> results = new List<DateTime>();
start = new DateTime(start.Year, start.Month, 1, 0, 0, 0);
end = new DateTime(end.Year, end.Month, 1, 0, 0, 0);
if (start > end)
{
throw new Exception("开启时间不应该晚于结束时间!");
}
else
{
// 迭代日期
var currentDate = start;
while (currentDate <= end)
{
results.Add(currentDate);
currentDate = currentDate.AddMonths(1);
}
}
return results;
}
/// <summary>
/// 返回两个日期之间的时间值(跨度单位:年,含开始时间和结束时间)
/// </summary>
/// <param name="start"></param>
/// <param name="end"></param>
/// <returns></returns>
/// <exception cref="Exception"></exception>
public static List<DateTime> GetYearSpanList(DateTime start, DateTime end)
{
List<DateTime> results = new List<DateTime>();
start = new DateTime(start.Year, 1, 1, 0, 0, 0);
end = new DateTime(end.Year, 1, 1, 0, 0, 0);
if (start > end)
{
throw new Exception("开启时间不应该晚于结束时间!");
}
else
{
// 迭代日期
var currentDate = start;
while (currentDate <= end)
{
results.Add(currentDate);
currentDate = currentDate.AddYears(1);
}
}
return results;
}
调用示例:
public static void Main()
{
DateTime start = new DateTime(2024, 8, 1);
DateTime end = DateTime.Now;
var testlist1 = GetDailySpanList(start, end);
var testlist2 = GetHourSpanList(start, end);
;
}
【日期格式化封装方法】
调用:
var now = DateTime.Now;
var resultlist = GetDaTimeFormat(now);
Console.WriteLine(resultlist.YM);
封装:
/// <summary>
/// 日期格式化(DateTime=>string)
/// </summary>
/// <param name="now"></param>
/// <returns></returns>
public static (string YM, string YMD, string YMDH0, string YMDHM, string YMDHM0, string YMDHMS, string YMDHMSF, string CYM, string CYMD, string CYMDH0, string CYMDHM, string CYMDHM0, string CYMDHMS) GetDaTimeFormat(DateTime now)
{
var tuple =
(
YM: now.ToString("yyyy-MM"),
YMD: now.ToString("yyyy-MM-dd"),
YMDH0: now.ToString("yyyy-MM-dd HH:00"),
YMDHM: now.ToString("yyyy-MM-dd HH:mm"),
YMDHM0: now.ToString("yyyy-MM-dd HH:mm:00"),
YMDHMS: now.ToString("yyyy-MM-dd HH:mm:ss"),
YMDHMSF: now.ToString("yyyy-MM-dd HH:mm:ss:ffff"),
CYM: now.ToString("yyyy年MM月"),
CYMD: now.ToString("yyyy年MM月dd日"),
CYMDH0: now.ToString("yyyy年MM月dd日 HH时00分"),
CYMDHM: now.ToString("yyyy年MM月dd日 HH时mm分"),
CYMDHM0: now.ToString("yyyy年MM月dd日 HH时mm分00秒"),
CYMDHMS: now.ToString("yyyy年MM月dd日 HH时mm分ss秒")
);
return tuple;
}
全打印效果:
2024-09-20 21:51
2024-09
2024-09-20
2024-09-20 21:00
2024-09-20 21:51
2024-09-20 21:51:00
2024-09-20 21:51:17
2024年09月
2024年09月20日
2024年09月20日 21时00分
2024年09月20日 21时51分
2024年09月20日 21时51分00秒
2024年09月20日 21时51分17秒
【输出这周一和周日】
调用:
static void Main(string[] args) // 主方法
{
DateTime specifiedDate = new DateTime(2024,9,22); // 替换为你的指定日期
var result = GetWeekTime(specifiedDate);
Console.WriteLine($"这周的周一是:{result.ThisMonday}");
Console.WriteLine($"这周的周日是:{result.ThisSunday}");
}
封装方法:
/// <summary>
/// 输入一个日期,输出这个日期所在周的周一和周日
/// </summary>
/// <param name="specifiedDate"></param>
/// <returns></returns>
public static (DateTime ThisMonday, DateTime ThisSunday) GetWeekTime(DateTime specifiedDate)
{
// 获取当前日期是星期几
int daysOffset = (int)specifiedDate.DayOfWeek;
// 如果是星期日,则偏移量需要减一
if (daysOffset == 0)
{
daysOffset = 6; // 星期日
}
else
{
daysOffset -= 1; // 其他日期
}
// 计算周一时间
DateTime monday = specifiedDate.AddDays(-daysOffset);
// 计算周日时间
DateTime sunday = monday.AddDays(6);
var tuple = (ThisMonday:monday,ThisSunday:sunday);
return tuple;
}
【输出两日期天数差】
封装方法:
/// <summary>
/// 计算两个日期之间的天数差(入参:开始时间 结束时间,结束时间不传默认是今天)
/// </summary>
/// <param name="time"></param>
/// <param name="end"></param>
/// <returns></returns>
public static string GetTimeGap(DateTime time, DateTime? end = null)
{
if (end == null)
{
end = DateTime.Now;
}
var gaptime = end - time;
return Convert.ToInt32(gaptime.Value.TotalDays - 1).ToString();
}
【输出中文周几】
public static string GetCNWeek(DateTime time)
{
string[] daysInChinese = { "周日", "周一", "周二", "周三", "周四", "周五", "周六" };
string dayOfWeekInChinese = daysInChinese[(int)time.DayOfWeek];
return dayOfWeekInChinese;
}
三、问题记录
1.建议使用DateTime ?,而不是DateTime
- 使用可空类型:前端入参的时间格式化错误,就会转化为null,而不是转化为0001/1/1 0:00:00(DateTime会转化为这种格式)
- 两种类型:均支持多种格式传入:年月、年月日、年月日时分、年月日时分秒(分隔符支持 - / )
2.日期默认值赋null的问题
【要求】时间为默认值“0001/1/1 0:00:00”时赋为null
【易错点】三元运算符不能直接赋null,要写成(DateTime?)null
var result = datetime == DateTime.MinValue? null : datetime;//报错,三元运算符前后类型要匹配
var result = datetime == DateTime.MinValue? (DateTime?)null : datetime;//正确
3.GetValueOrDefault
BeginTime.GetValueOrDefault(DateTime.Now); //BeginTime类型是DateTime? 这句代码意思是非空返回对应值,空返回默认值(DateTime 默认值是0001/01/01 00:00:00)