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 }