1 //====================================================================
2 //** Copyright © classbao.com 2016 -- QQ:1165458780 -- 请保留此注释 **
3 //====================================================================
4 // 文件名称:DateHelper.cs
5 // 项目名称:常用方法实用工具集
6 // 创建时间:2016年7月25日10时59分
7 // 创建人员:熊学浩
8 // 负 责 人:熊学浩
9 // 参与人员:熊学浩
10 // ===================================================================
11 using System;
12 using System.Collections.Generic;
13 using System.Text.RegularExpressions;
14
15 namespace DawnXZ.DawnUtility {
16 /// <summary>
17 /// 日期操作辅助类
18 /// </summary>
19 public static class DateHelper {
20
21 #region 当前时间
22
23 /// <summary>
24 /// 返回当前时间的标准日期格式
25 /// </summary>
26 /// <returns>yyyy-MM-dd</returns>
27 public static string GetDate() {
28 return DateTime.Now.ToString("yyyy-MM-dd");
29 }
30 /// <summary>
31 /// 返回当前时间的标准时间格式string
32 /// </summary>
33 /// <returns>HH:mm:ss</returns>
34 public static string GetTime() {
35 return DateTime.Now.ToString("HH:mm:ss");
36 }
37 /// <summary>
38 /// 返回当前时间的标准时间格式string
39 /// </summary>
40 /// <returns>yyyy-MM-dd HH:mm:ss</returns>
41 public static string GetDateTime() {
42 return DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
43 }
44 /// <summary>
45 /// 返回相对于当前时间的相对天数
46 /// </summary>
47 /// <param name="relativeday">增加的天数</param>
48 /// <returns>相对天数</returns>
49 public static string GetDateTimeOfDay(int relativeday) {
50 return DateTime.Now.AddDays(relativeday).ToString("yyyy-MM-dd HH:mm:ss");
51 }
52 /// <summary>
53 /// 返回相对于当前时间的相对分钟数
54 /// </summary>
55 /// <param name="relativeday">增加的分钟数</param>
56 /// <returns>相对分钟数</returns>
57 public static string GetDateTimeOfMinutes(int relativeday) {
58 return DateTime.Now.AddMinutes(relativeday).ToString("yyyy-MM-dd HH:mm:ss");
59 }
60 /// <summary>
61 /// 返回当前时间的标准时间格式
62 /// </summary>
63 /// <returns>yyyy-MM-dd HH:mm:ss:fffffff</returns>
64 public static string GetDateTimeF() {
65 return DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss:fffffff");
66 }
67
68 #endregion
69
70 #region 时间转换
71
72 /// <summary>
73 /// 返回指定日期格式
74 /// </summary>
75 /// <param name="datetimestr">需要转换的时间</param>
76 /// <param name="replacestr">指定格式</param>
77 /// <returns>转换后的时间</returns>
78 public static string GetDate(string datetimestr, string replacestr) {
79 if (datetimestr == null) return replacestr;
80 if (datetimestr.Equals("")) return replacestr;
81 try {
82 datetimestr = Convert.ToDateTime(datetimestr).ToString("yyyy-MM-dd").Replace("1900-01-01", replacestr);
83 }
84 catch {
85 return replacestr;
86 }
87 return datetimestr;
88 }
89 /// <summary>
90 /// 转换时间为unix时间戳
91 /// </summary>
92 /// <param name="date">需要传递UTC时间,避免时区误差,例:DataTime.UTCNow</param>
93 /// <returns></returns>
94 public static double ConvertToUnixTimestamp(DateTime date) {
95 DateTime origin = new DateTime(1970, 1, 1, 0, 0, 0, 0);
96 TimeSpan diff = date - origin;
97 return Math.Floor(diff.TotalSeconds);
98 }
99 /// <summary>
100 /// 将8位日期型整型数据转换为日期字符串数据
101 /// 默认为英文格式
102 /// </summary>
103 /// <param name="date">整型日期</param>
104 /// <returns></returns>
105 public static string FormatDate(int date) {
106 return FormatDate(date, false);
107 }
108 /// <summary>
109 /// 将8位日期型整型数据转换为日期字符串数据
110 /// </summary>
111 /// <param name="date">整型日期</param>
112 /// <param name="chnType">是否以中文年月日输出</param>
113 /// <returns></returns>
114 public static string FormatDate(int date, bool chnType) {
115 string dateStr = date.ToString();
116 if (date <= 0 || dateStr.Length != 8) return dateStr;
117 if (chnType) return dateStr.Substring(0, 4) + "年" + dateStr.Substring(4, 2) + "月" + dateStr.Substring(6) + "日";
118 return dateStr.Substring(0, 4) + "-" + dateStr.Substring(4, 2) + "-" + dateStr.Substring(6);
119 }
120
121 #endregion
122
123 #region 标准时间
124
125 /// <summary>
126 /// 返回标准时间
127 /// </summary>
128 /// <param name="fDateTime">转换时间</param>
129 /// <param name="formatStr">转换格式</param>
130 /// <returns>转换后的时间</returns>
131 public static string GetStandardDateTime(string fDateTime, string formatStr) {
132 if (fDateTime == "0000-0-0 0:00:00") return fDateTime;
133 DateTime time = new DateTime(1900, 1, 1, 0, 0, 0, 0);
134 if (DateTime.TryParse(fDateTime, out time)) {
135 return time.ToString(formatStr);
136 }
137 else {
138 return "N/A";
139 }
140 }
141 /// <summary>
142 /// 返回标准时间 yyyy-MM-dd HH:mm:ss
143 /// </summary>
144 /// <param name="fDateTime">转换时间</param>
145 /// <returns>yyyy-MM-dd HH:mm:ss</returns>
146 public static string GetStandardDateTime(string fDateTime) {
147 return GetStandardDateTime(fDateTime, "yyyy-MM-dd HH:mm:ss");
148 }
149 /// <summary>
150 /// 返回标准时间 yyyy-MM-dd
151 /// </summary>
152 /// <param name="fDate">转换时间</param>
153 /// <returns>yyyy-MM-dd</returns>
154 public static string GetStandardDate(string fDate) {
155 return GetStandardDateTime(fDate, "yyyy-MM-dd");
156 }
157
158 #endregion
159
160 #region 返回相差 秒数、分钟数、小时数
161
162 /// <summary>
163 /// 返回相差的秒数
164 /// </summary>
165 /// <param name="time">时间字符串</param>
166 /// <param name="Sec">秒数</param>
167 /// <returns>相差的秒数</returns>
168 public static int DateOfDiffSeconds(string time, int Sec) {
169 if (string.IsNullOrEmpty(time)) return 1;
170 DateTime dateTime = TypeHelper.StrToDateTime(time, DateTime.Parse("1900-01-01"));
171 if (dateTime.ToString("yyyy-MM-dd") == "1900-01-01") return 1;
172 TimeSpan ts = DateTime.Now - dateTime.AddSeconds(Sec);
173 if (ts.TotalSeconds > int.MaxValue) {
174 return int.MaxValue;
175 }
176 else if (ts.TotalSeconds < int.MinValue) {
177 return int.MinValue;
178 }
179 return (int)ts.TotalSeconds;
180 }
181 /// <summary>
182 /// 返回相差的分钟数
183 /// </summary>
184 /// <param name="time">时间字符串</param>
185 /// <param name="minutes">分钟数</param>
186 /// <returns>相差的分钟数</returns>
187 public static int DateOfDiffMinutes(string time, int minutes) {
188 if (string.IsNullOrEmpty(time)) return 1;
189 DateTime dateTime = TypeHelper.StrToDateTime(time, DateTime.Parse("1900-01-01"));
190 if (dateTime.ToString("yyyy-MM-dd") == "1900-01-01") return 1;
191 TimeSpan ts = DateTime.Now - dateTime.AddMinutes(minutes);
192 if (ts.TotalMinutes > int.MaxValue) {
193 return int.MaxValue;
194 }
195 else if (ts.TotalMinutes < int.MinValue) {
196 return int.MinValue;
197 }
198 return (int)ts.TotalMinutes;
199 }
200 /// <summary>
201 /// 返回相差的小时数
202 /// </summary>
203 /// <param name="time">时间字符串</param>
204 /// <param name="hours">小时数</param>
205 /// <returns>相差的小时数</returns>
206 public static int DateOfDiffHours(string time, int hours) {
207 if (string.IsNullOrEmpty(time)) return 1;
208 DateTime dateTime = TypeHelper.StrToDateTime(time, DateTime.Parse("1900-01-01"));
209 if (dateTime.ToString("yyyy-MM-dd") == "1900-01-01") return 1;
210 TimeSpan ts = DateTime.Now - dateTime.AddHours(hours);
211 if (ts.TotalHours > int.MaxValue) {
212 return int.MaxValue;
213 }
214 else if (ts.TotalHours < int.MinValue) {
215 return int.MinValue;
216 }
217 return (int)ts.TotalHours;
218 }
219
220 #endregion
221
222 #region 时间格式检测
223
224 /// <summary>
225 /// 是否常规时间
226 /// </summary>
227 public static bool IsTime(string timeval) {
228 return Regex.IsMatch(timeval, @"^((([0-1]?[0-9])|(2[0-3])):([0-5]?[0-9])(:[0-5]?[0-9])?)$");
229 }
230 /// <summary>
231 /// 判断字符串是否是yy-mm-dd字符串
232 /// </summary>
233 /// <param name="str">待判断字符串</param>
234 /// <returns>判断结果</returns>
235 public static bool IsDateString(string str) {
236 return Regex.IsMatch(str, @"(\d{4})-(\d{1,2})-(\d{1,2})");
237 }
238
239 #endregion
240
241 #region 年
242
243 /// <summary>
244 /// 判断某年是否为闰年
245 /// </summary>
246 /// <param name="year">需要计算的年份</param>
247 /// <returns>是否为闰年</returns>
248 public static bool YearIsLeap(int year) {
249 if (year <= 0001 || year >= 9999) return false;
250 return DateTime.IsLeapYear(year);
251 }
252 /// <summary>
253 /// 计算某年共有多少天
254 /// </summary>
255 /// <param name="year">需要计算的年份</param>
256 /// <returns>共有多少天</returns>
257 public static int YearOfTotalDay(int year) {
258 if (year <= 0001 || year >= 9999) return -1;
259 return YearOfLastDay(year).DayOfYear;
260 }
261 /// <summary>
262 /// 获得某年第一天的日期
263 /// </summary>
264 /// <param name="year">需要计算的年份</param>
265 /// <returns>第一天日期</returns>
266 public static DateTime YearOfFirstDay(int year) {
267 if (year <= 0001 || year >= 9999) return DateTime.MaxValue;
268 DateTime result = DateTime.MinValue;
269 DateTime.TryParse(string.Format("{0}-01-01", year), out result);
270 return result;
271 }
272 /// <summary>
273 /// 获得某年最后一天的日期
274 /// </summary>
275 /// <param name="year">需要计算的年份</param>
276 /// <returns>最后一天日期</returns>
277 public static DateTime YearOfLastDay(int year) {
278 if (year <= 0001 || year >= 9999) return DateTime.MaxValue;
279 DateTime result = DateTime.MaxValue;
280 DateTime.TryParse(string.Format("{0}-12-31", year), out result);
281 return result;
282 }
283
284 #endregion
285
286 #region 月
287
288 /// <summary>
289 /// 获得当前年当前月的总天数
290 /// </summary>
291 /// <returns>共有多少天</returns>
292 public static int MonthOfTotalDay() {
293 DateTime _now = DateTime.Now;
294 return DateTime.DaysInMonth(_now.Year, _now.Month);
295 }
296 /// <summary>
297 /// 获得某年某月的总天数
298 /// </summary>
299 /// <param name="year">需要计算的年份</param>
300 /// <param name="month">需要计算的月份</param>
301 /// <returns>共有多少天</returns>
302 public static int MonthOfTotalDay(int year, int month) {
303 if (year <= 0001 || year >= 9999) return -1;
304 if (month < 1 || month > 12) return -1;
305 return DateTime.DaysInMonth(year, month);
306 }
307 /// <summary>
308 /// 获得当前年当前月第一天的日期
309 /// </summary>
310 /// <returns>第一天日期</returns>
311 public static DateTime MonthOfFirstDay() {
312 DateTime _now = DateTime.Now;
313 return MonthOfFirstDay(_now.Year, _now.Month);
314 }
315 /// <summary>
316 /// 获得某年某月第一天的日期
317 /// </summary>
318 /// <param name="year">需要计算的年份</param>
319 /// <param name="month">需要计算的月份</param>
320 /// <returns>第一天日期</returns>
321 public static DateTime MonthOfFirstDay(int year, int month) {
322 if (year <= 0001 || year >= 9999) return DateTime.MaxValue;
323 if (month < 1 || month > 12) return DateTime.MaxValue;
324 DateTime result = DateTime.MinValue;
325 DateTime.TryParse(string.Format("{0}-{1}-01", year, month), out result);
326 return result;
327 }
328 /// <summary>
329 /// 获得当前年当前月最后一天的日期
330 /// </summary>
331 /// <returns>最后一天日期</returns>
332 public static DateTime MonthOfLastDay() {
333 DateTime _now = DateTime.Now;
334 return MonthOfLastDay(_now.Year, _now.Month);
335 }
336 /// <summary>
337 /// 获得某年某月最后一天的日期
338 /// </summary>
339 /// <param name="year">需要计算的年份</param>
340 /// <param name="month">需要计算的月份</param>
341 /// <returns>最后一天日期</returns>
342 public static DateTime MonthOfLastDay(int year, int month) {
343 if (year <= 0001 || year >= 9999) return DateTime.MaxValue;
344 if (month < 1 || month > 12) return DateTime.MaxValue;
345 DateTime result = DateTime.MaxValue;
346 string tmpString = string.Format("{0}-{1}-{2}", year, month, DateTime.DaysInMonth(year, month));
347 DateTime.TryParse(tmpString, out result);
348 return result;
349 }
350
351 #endregion
352
353 #region 周
354
355 /// <summary>
356 /// 周(星期)信息实体类
357 /// </summary>
358 [Serializable]
359 public class WeekInfo {
360 /// <summary>
361 /// 周(星期)信息实体类
362 /// </summary>
363 public WeekInfo() {
364 Number = 0;
365 BeginDate = DateTime.MinValue;
366 EndDate = DateTime.MaxValue;
367 }
368 /// <summary>
369 /// 周数
370 /// </summary>
371 public int Number { get; set; }
372 /// <summary>
373 /// 开始时间
374 /// </summary>
375 public DateTime BeginDate { get; set; }
376 /// <summary>
377 /// 结束时间
378 /// </summary>
379 public DateTime EndDate { get; set; }
380 /// <summary>
381 /// 输出第几周和日期间隔
382 /// <para>默认格式:</para>
383 /// <para>第几周,从2012年12月21日至2112年12月21日。</para>
384 /// </summary>
385 /// <returns>第几周和日期间隔</returns>
386 public override string ToString() {
387 return string.Format("第{0}周,从{1}至{2}。", Number, BeginDate.ToString("yyyy年MM月dd日"), EndDate.ToString("yyyy年MM月dd日"));
388 }
389 /// <summary>
390 /// 输出第几周
391 /// </summary>
392 /// <param name="isFill">少于2位时是否补零</param>
393 /// <returns>第几周</returns>
394 public string GetWeekString(bool isFill) {
395 string _format = "第{0}周";
396 if (isFill && Number < 10) _format = "第0{0}周";
397 return string.Format(_format, Number);
398 }
399 /// <summary>
400 /// 输出日期间隔
401 /// </summary>
402 /// <param name="inputString">输出格式化字符串</param>
403 /// <param name="dateString">日期格式化字符串</param>
404 /// <returns>日期间隔</returns>
405 public string GetDateString(string inputString, string dateString) {
406 if (string.IsNullOrWhiteSpace(inputString) || string.IsNullOrWhiteSpace(dateString)) return null;
407 try {
408 return string.Format(inputString, BeginDate.ToString(dateString), EndDate.ToString(dateString));
409 }
410 catch (Exception ex) {
411 return ex.Message;
412 }
413 }
414 }
415 /// <summary>
416 /// 获得年度第一个周一的日期
417 /// </summary>
418 /// <param name="year">需要计算的年份</param>
419 /// <param name="jumpYear">年度第一周是否跳过跨年的周数</param>
420 /// <param name="offset">年度第一个周一偏移量</param>
421 /// <returns>年度第一个周一的日期</returns>
422 public static DateTime WeekOfFirstDay(int year, bool jumpYear, out int offset) {
423 DateTime firstDate = YearOfFirstDay(year); //该年的第一天
424 int firstWeek = (int)firstDate.DayOfWeek; //该年的第一天是周几
425 offset = 0; //周一偏移量
426 switch (firstWeek) {
427 case 1: //星期一
428 offset = jumpYear ? 0 : 0;
429 break;
430 case 2: //星期二
431 offset = jumpYear ? 6 : -1;
432 break;
433 case 3: //星期三
434 offset = jumpYear ? 5 : -2;
435 break;
436 case 4: //星期四
437 offset = jumpYear ? 4 : -3;
438 break;
439 case 5: //星期五
440 offset = jumpYear ? 3 : -4;
441 break;
442 case 6: //星期六
443 offset = jumpYear ? 2 : -5;
444 break;
445 case 0: //星期日
446 offset = jumpYear ? 1 : -6;
447 break;
448 }
449 firstDate = firstDate.AddDays(offset);
450 return firstDate;
451 }
452 /// <summary>
453 /// 获得年度周(星期)信息实体集合列表
454 /// </summary>
455 /// <param name="year">需要计算的年份</param>
456 /// <param name="jumpYear">年度第一周是否跳过跨年的周数</param>
457 /// <returns>周(星期)信息实体集合列表对象</returns>
458 public static IList<WeekInfo> WeekOfList(int year, bool jumpYear) {
459 IList<WeekInfo> weekList = new List<WeekInfo>();
460 if (year <= 0001 || year >= 9999) return weekList;
461 int offset = 0;
462 DateTime firstDate = WeekOfFirstDay(year, jumpYear, out offset); //年度周一的日期
463 int index = 1;
464 WeekInfo weekInfo;
465 while (true) {
466 if (index > 54) break;
467 weekInfo = new WeekInfo();
468 weekInfo.Number = index;
469 weekInfo.BeginDate = firstDate; //周一
470 weekInfo.EndDate = firstDate.AddDays(6); //周日
471 weekList.Add(weekInfo);
472 firstDate = firstDate.AddDays(7); //下周
473 if (jumpYear) {
474 if (firstDate.Year != year) break;
475 }
476 else {
477 if (firstDate.AddDays(6).Year != year) break;
478 }
479 index++;
480 }
481 return weekList;
482 }
483 /// <summary>
484 /// 获得某年第某周的开始日期和结束日期
485 /// </summary>
486 /// <param name="year">需要计算的年份</param>
487 /// <param name="weekNumber">需要计算的周数</param>
488 /// <param name="jumpYear">年度第一周是否跳过跨年的周数</param>
489 /// <param name="weekBeginDate">开始日期</param>
490 /// <param name="weekEndDate">结束日期</param>
491 public static void WeekOfDate(int year, int weekNumber, bool jumpYear, out DateTime weekBeginDate, out DateTime weekEndDate) {
492 weekBeginDate = DateTime.MinValue;
493 weekEndDate = DateTime.MaxValue;
494 if (year <= 0001 || year >= 9999 || weekNumber < 1 || weekNumber > 54) return;
495 int offset = 0;
496 DateTime firstDate = WeekOfFirstDay(year, jumpYear, out offset); //年度周一的日期
497 firstDate = firstDate.AddDays((weekNumber - 1) * 7);
498 weekBeginDate = firstDate;
499 weekEndDate = firstDate.AddDays(6);
500 }
501 /// <summary>
502 /// 获得某个日期属于某年的第几周
503 /// </summary>
504 /// <param name="currentDate">需要计算的日期</param>
505 /// <param name="jumpYear">年度第一周是否跳过跨年的周数</param>
506 /// <returns>某年的第几周</returns>
507 public static int WeekOfCurrent(DateTime currentDate, bool jumpYear) {
508 if (DateTime.MinValue == currentDate || DateTime.MaxValue == currentDate) return 0;
509 int result = 0, offset = 0;
510 DateTime firstDate = WeekOfFirstDay(currentDate.Year, jumpYear, out offset); //年度周一的日期
511 int firstWeek = (int)firstDate.DayOfWeek; //该年的第一天是周几
512 int currentDay = currentDate.DayOfYear;
513 if (offset > 0) {
514 currentDay += offset;
515 }
516 else {
517 currentDay -= offset;
518 }
519 int remainderDay = currentDay - (7 - firstWeek);
520 if (remainderDay < 1) {
521 result = 1;
522 }
523 else {
524 result = remainderDay / 7;
525 if (remainderDay % 7 != 0) result++;
526 result++;
527 }
528 return result;
529 }
530 /// <summary>
531 /// 统计一段时间内有多少个星期几
532 /// </summary>
533 /// <param name="beginDate">开始日期</param>
534 /// <param name="endDate">结束日期</param>
535 /// <param name="weekNumber">星期几</param>
536 /// <returns>多少个星期几</returns>
537 public static int WeekOfTotalWeeks(DateTime beginDate, DateTime endDate, DayOfWeek weekNumber) {
538 TimeSpan _dayTotal = new TimeSpan(endDate.Ticks - beginDate.Ticks);
539 int result = (int)_dayTotal.TotalDays / 7;
540 double iLen = _dayTotal.TotalDays % 7;
541 for (int i = 0; i <= iLen; i++) {
542 if (beginDate.AddDays(i).DayOfWeek == weekNumber) {
543 result++;
544 break;
545 }
546 }
547 return result;
548 }
549
550 #endregion
551
552 #region 季度
553
554 /// <summary>
555 /// 计算当前月属于第几季度
556 /// </summary>
557 /// <returns>当前年第几季度</returns>
558 public static int QuarterOfCurrent() {
559 return QuarterOfCurrent(DateTime.Now.Month);
560 }
561 /// <summary>
562 /// 计算某个月属于第几季度
563 /// </summary>
564 /// <param name="month">需要计算的月份</param>
565 /// <returns>某年第几季度</returns>
566 public static int QuarterOfCurrent(int month) {
567 if (month < 1 || month > 12) return -1;
568 return (month - 1) / 3 + 1;
569 }
570 /// <summary>
571 /// 获得当前年当前季度的开始日期和结束日期
572 /// </summary>
573 /// <param name="quarterBeginDate">开始日期</param>
574 /// <param name="quarterEndDate">结束日期</param>
575 public static void QuarterOfDate(out DateTime quarterBeginDate, out DateTime quarterEndDate) {
576 int quarter = QuarterOfCurrent(DateTime.Now.Month);
577 QuarterOfDate(DateTime.Now.Year, quarter, out quarterBeginDate, out quarterEndDate);
578 }
579 /// <summary>
580 /// 获得指定日期所在季度的开始日期和结束日期
581 /// </summary>
582 /// <param name="fromDate">需要计算的日期</param>
583 /// <param name="quarterBeginDate">开始日期</param>
584 /// <param name="quarterEndDate">结束日期</param>
585 public static void QuarterOfDate(DateTime fromDate, out DateTime quarterBeginDate, out DateTime quarterEndDate) {
586 int quarter = QuarterOfCurrent(fromDate.Month);
587 QuarterOfDate(fromDate.Year, quarter, out quarterBeginDate, out quarterEndDate);
588 }
589 /// <summary>
590 /// 获得某年第某季度的开始日期和结束日期
591 /// </summary>
592 /// <param name="year">需要计算的年份</param>
593 /// <param name="quarter">需要计算的季度</param>
594 /// <param name="quarterBeginDate">开始日期</param>
595 /// <param name="quarterEndDate">结束日期</param>
596 public static void QuarterOfDate(int year, int quarter, out DateTime quarterBeginDate, out DateTime quarterEndDate) {
597 quarterBeginDate = DateTime.MinValue;
598 quarterEndDate = DateTime.MaxValue;
599 if (year <= 0001 || year >= 9999 || quarter < 1 || quarter > 4) return;
600 int month = (quarter - 1) * 3 + 1;
601 quarterBeginDate = new DateTime(year, month, 1);
602 quarterEndDate = quarterBeginDate.AddMonths(3).AddMilliseconds(-1);
603 }
604
605 #endregion
606
607 }
608 }