using System;
using System.Data;

namespace ZXDT.Common
{
    [Serializable]
    public enum DateInterval
    {
        Second, Minute, Hour, Day, Week, Month, Quarter, Year
    }
    /// <summary>
    /// 日期处理工具类
    /// </summary>
    [Serializable]
    public class DateUtil
    {
        private DateUtil() { }
        private static readonly string ISO8601Short = "yyyy-MM-dd";
        private static readonly string ISO8601Long = "yyyy-MM-dd HH:mm:ss";


        /// <summary>
        /// 根据日期获取一个周期(7天)的开始日期
        /// </summary>
        /// <param name="cd"></param>
        /// <returns></returns>
        public static DateTime getStartDate(DateTime cd)
        {

            string[] Day = new string[] { "星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六" };
            switch (Day[Convert.ToInt16(DateTime.Now.DayOfWeek)])
            {
                case "星期日": return cd.AddDays(-9);
                case "星期一": return cd.AddDays(-10);
                case "星期二": return cd.AddDays(-11);
                case "星期三": return cd.AddDays(-12);
                case "星期四": return cd.AddDays(-13);
                case "星期五": return cd.AddDays(-7);
                case "星期六": return cd.AddDays(-8);
            }
            return cd;
        }
        /// <summary>
        /// 根据日期获取一个周期(7天)的结束日期
        /// </summary>
        /// <param name="cd"></param>
        /// <returns></returns>
        public static DateTime getEndDate(DateTime cd)
        {
            int t = Convert.ToInt16(cd.DayOfWeek);
            switch (t)
            {
                case 0: return cd.AddDays(-3);
                case 1: return cd.AddDays(-4);
                case 2: return cd.AddDays(-5);
                case 3: return cd.AddDays(-6);
                case 4: return cd.AddDays(-7);
                case 5: return cd.AddDays(-1);
                case 6: return cd.AddDays(-2);

            }
            return cd;
        }
        /// <summary>
        /// 判断 字符对象 是否是日期字符
        /// </summary>
        /// <param name="obj">字符对象</param>
        /// <returns></returns>
        public static bool isDate(object obj)
        {
            bool tag = false;
            try
            {
                if (obj != null)
                {
                    Convert.ToDateTime(obj.ToString());
                    tag = true;
                }
            }
            catch (Exception)
            {
            }
            return tag;
        }
        public static string toStr(object obj)
        {
            try
            {
                if (obj == null || obj == DBNull.Value)
                {
                    return string.Empty;
                }
                else
                {
                    return Convert.ToDateTime(obj.ToString()).ToString(DateUtil.ISO8601Short);
                }
            }
            catch (Exception)
            {
                return string.Empty;
            }
        }
        public static string toLongStr(object obj)
        {
            try
            {
                if (obj == null || obj == DBNull.Value)
                {
                    return string.Empty;
                }
                else
                {
                    return Convert.ToDateTime(obj.ToString()).ToString(DateUtil.ISO8601Long);
                }
            }
            catch (Exception)
            {
                return string.Empty;
            }
        }
        /// <summary>
        /// 将日期对象转换成日期
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public static DateTime toDate(object obj)
        {
            try
            {
                if (obj != null)
                {
                    return Convert.ToDateTime(obj.ToString().Trim());
                }
                else
                {
                    return DateTime.MinValue;
                }
            }
            catch (Exception)
            {
                return DateTime.MinValue;
            }

        }
        /// <summary>
        /// 实现类似数据库 DateDiff 功能
        /// </summary>
        /// <param name="Interval">间隔类型</param>
        /// <param name="StartDate">开始日期</param>
        /// <param name="EndDate">结束日期</param>
        /// <returns></returns>
        public static long DateDiff(DateInterval Interval, System.DateTime StartDate, System.DateTime EndDate)
        {
            long lngDateDiffValue = 0;
            System.TimeSpan TS = new System.TimeSpan(EndDate.Ticks - StartDate.Ticks);
            switch (Interval)
            {
                case DateInterval.Second:
                    lngDateDiffValue = (long)TS.TotalSeconds;
                    break;
                case DateInterval.Minute:
                    lngDateDiffValue = (long)TS.TotalMinutes;
                    break;
                case DateInterval.Hour:
                    lngDateDiffValue = (long)TS.TotalHours;
                    break;
                case DateInterval.Day:
                    lngDateDiffValue = (long)TS.Days;
                    break;
                case DateInterval.Week:
                    lngDateDiffValue = (long)(TS.Days / 7);
                    break;
                case DateInterval.Month:
                    lngDateDiffValue = (long)(TS.Days / 30);
                    break;
                case DateInterval.Quarter:
                    lngDateDiffValue = (long)((TS.Days / 30) / 3);
                    break;
                case DateInterval.Year:
                    lngDateDiffValue = (long)(TS.Days / 365);
                    break;
            }
            return (lngDateDiffValue);
        }
        public static string toColorStr(object obj)
        {
            string temp = "";
            try
            {
                if (obj != null)
                {
                    DateTime dt = Convert.ToDateTime(obj.ToString());
                    if (dt.Year == 2011)
                    {
                        temp = "<span class='x-grid-back-red1'>" + dt.ToString(DateUtil.ISO8601Short) + "</span>";
                    }
                    if (dt.Year == 2012)
                    {
                        temp = "<span class='x-grid-back-red2'>" + dt.ToString(DateUtil.ISO8601Short) + "</span>";
                    }
                    if (dt.Year == 2013)
                    {
                        temp = "<span class='x-grid-back-red3'>" + dt.ToString(DateUtil.ISO8601Short) + "</span>";
                    }
                    if (dt.Year == 2014)
                    {
                        temp = "<span class='x-grid-back-red4'>" + dt.ToString(DateUtil.ISO8601Short) + "</span>";
                    }

                }
            }
            catch (Exception)
            {
            }
            return temp;
        }
        /// <summary>
        /// 获取该年中是第几周
        /// </summary>
        /// <param name="day">日期</param>
        /// <returns></returns>
        public static int WeekOfYear(System.DateTime day)
        {
            int weeknum;
            System.DateTime fDt = DateTime.Parse(day.Year.ToString() + "-01-01");
            int k = Convert.ToInt32(fDt.DayOfWeek);//得到该年的第一天是周几 
            if (k == 0)
            {
                k = 7;
            }
            int l = Convert.ToInt32(day.DayOfYear);//得到当天是该年的第几天 
            l = l - (7 - k + 1);
            if (l <= 0)
            {
                weeknum = 1;
            }
            else
            {
                if (l % 7 == 0)
                {
                    weeknum = l / 7 + 1;
                }
                else
                {
                    weeknum = l / 7 + 2;//不能整除的时候要加上前面的一周和后面的一周 
                }
            }
            return weeknum;
        }


        /// <summary>
        /// 获取该年中是第几季度
        /// </summary>
        /// <param name="day">日期</param>
        /// <returns></returns>
        public static int QuarterOfYear(System.DateTime day)
        {
            if (day.Month < 4)
            {
                return 1;
            }
            else if (day.Month > 9)
            {
                return 4;
            }
            else if (day.Month > 3 && day.Month < 7)
            {
                return 2;
            }
            else
            {
                return 3;
            }
        }
        /// <summary>
        /// 计算日期间隔
        /// </summary>
        /// <param name="d1">要参与计算的其中一个日期字符串</param>
        /// <param name="d2">要参与计算的另一个日期字符串</param>
        /// <returns>一个表示日期间隔的TimeSpan类型</returns>
        public static TimeSpan toResult(string d1, string d2)
        {
            try
            {
                DateTime date1 = DateTime.Parse(d1);
                DateTime date2 = DateTime.Parse(d2);
                return toResult(date1, date2);
            }
            catch
            {
                throw new Exception("字符串参数不正确!");
            }
        }
        /// <summary>
        /// 计算日期间隔
        /// </summary>
        /// <param name="d1">要参与计算的其中一个日期</param>
        /// <param name="d2">要参与计算的另一个日期</param>
        /// <returns>一个表示日期间隔的TimeSpan类型</returns>
        public static TimeSpan toResult(DateTime d1, DateTime d2)
        {
            TimeSpan ts;
            if (d1 > d2)
            {
                ts = d1 - d2;
            }
            else
            {
                ts = d2 - d1;
            }
            return ts;
        }

        /// <summary>
        /// 计算日期间隔
        /// </summary>
        /// <param name="d1">要参与计算的其中一个日期字符串</param>
        /// <param name="d2">要参与计算的另一个日期字符串</param>
        /// <param name="drf">决定返回值形式的枚举</param>
        /// <returns>一个代表年月日的int数组，具体数组长度与枚举参数drf有关</returns>
        public static int[] toResult(string d1, string d2, diffResultFormat drf)
        {
            try
            {
                DateTime date1 = DateTime.Parse(d1);
                DateTime date2 = DateTime.Parse(d2);
                return toResult(date1, date2, drf);
            }
            catch
            {
                throw new Exception("字符串参数不正确!");
            }
        }
        /// <summary>
        /// 计算日期间隔
        /// </summary>
        /// <param name="d1">要参与计算的其中一个日期</param>
        /// <param name="d2">要参与计算的另一个日期</param>
        /// <param name="drf">决定返回值形式的枚举</param>
        /// <returns>一个代表年月日的int数组，具体数组长度与枚举参数drf有关</returns>
        public static int[] toResult(DateTime d1, DateTime d2, diffResultFormat drf)
        {
            #region 数据初始化
            DateTime max;
            DateTime min;
            int year;
            int month;
            int tempYear, tempMonth;
            if (d1 > d2)
            {
                max = d1;
                min = d2;
            }
            else
            {
                max = d2;
                min = d1;
            }
            tempYear = max.Year;
            tempMonth = max.Month;
            if (max.Month < min.Month)
            {
                tempYear--;
                tempMonth = tempMonth + 12;
            }
            year = tempYear - min.Year;
            month = tempMonth - min.Month;
            #endregion
            #region 按条件计算
            if (drf == diffResultFormat.dd)
            {
                TimeSpan ts = max - min;
                return new int[] { ts.Days };
            }
            if (drf == diffResultFormat.mm)
            {
                return new int[] { month + year * 12 };
            }
            if (drf == diffResultFormat.yy)
            {
                return new int[] { year };
            }
            return new int[] { year, month };
            #endregion
        }

        /// <summary>
        /// 获取指定年月的最后一天
        /// </summary>
        /// <param name="year">年份</param>
        /// <param name="month">月份</param>
        /// <returns></returns>
        public static int GetLastDayofMonth(int year, int month)
        {
            int days = DateTime.DaysInMonth(year, month);
            DateTime datetime = new DateTime(year, month, 1);
            return datetime.AddDays(days - 1).Day;
        }

        /// <summary>  
        /// 获取指定日期所在周的第一天，星期天为第一天  
        /// </summary>  
        /// <param name="dateTime"></param>  
        /// <returns></returns>  
        public static DateTime GetDateTimeWeekFirstDaySun(DateTime dateTime)
        {
            DateTime firstWeekDay = DateTime.Now;

            try
            {
                //得到是星期几，然后从当前日期减去相应天数   
                int weeknow = Convert.ToInt32(dateTime.DayOfWeek);

                int daydiff = (-1) * weeknow;

                firstWeekDay = dateTime.AddDays(daydiff);
            }
            catch { }

            return firstWeekDay;
        }

        /// <summary>  
        /// 获取指定日期所在周的第一天，星期一为第一天  
        /// </summary>  
        /// <param name="dateTime"></param>  
        /// <returns></returns>  
        public static DateTime GetDateTimeWeekFirstDayMon(DateTime dateTime)
        {
            DateTime firstWeekDay = DateTime.Now;

            try
            {
                int weeknow = Convert.ToInt32(dateTime.DayOfWeek);

                //星期一为第一天，weeknow等于0时，要向前推6天。     
                weeknow = (weeknow == 0 ? (7 - 1) : (weeknow - 1));

                int daydiff = (-1) * weeknow;

                firstWeekDay = dateTime.AddDays(daydiff);
            }
            catch { }

            return firstWeekDay;
        }

        /// <summary>  
        /// 获取指定日期所在周的最后一天，星期六为最后一天  
        /// </summary>  
        /// <param name="dateTime"></param>  
        /// <returns></returns>  
        public static DateTime GetDateTimeWeekLastDaySat(DateTime dateTime)
        {
            DateTime lastWeekDay = DateTime.Now;

            try
            {
                int weeknow = Convert.ToInt32(dateTime.DayOfWeek);

                int daydiff = (7 - weeknow) - 1;

                lastWeekDay = dateTime.AddDays(daydiff);

            }
            catch { }

            return lastWeekDay;
        }

        /// <summary>  
        /// 获取指定日期所在周的最后一天，星期天为最后一天  
        /// </summary>  
        /// <param name="dateTime"></param>  
        /// <returns></returns>  

        public static DateTime GetDateTimeWeekLastDaySun(DateTime dateTime)
        {
            DateTime lastWeekDay = DateTime.Now;

            try
            {
                int weeknow = Convert.ToInt32(dateTime.DayOfWeek);

                weeknow = (weeknow == 0 ? 7 : weeknow);

                int daydiff = (7 - weeknow);

                lastWeekDay = dateTime.AddDays(daydiff);
            }
            catch { }

            return lastWeekDay;
        }

        /// <summary>  
        /// 获取指定日期的月份第一天  
        /// </summary>  
        /// <param name="dateTime"></param>  
        /// <returns></returns>  
        public static DateTime GetDateTimeMonthFirstDay(DateTime dateTime)
        {
            if (dateTime == null)
            {
                dateTime = DateTime.Now;
            }

            return new DateTime(dateTime.Year, dateTime.Month, 1);
        }

        /// <summary>  
        /// 获取指定月份最后一天  
        /// </summary>  
        /// <param name="dateTime"></param>  
        /// <returns></returns>  
        public static DateTime GetDateTimeMonthLastDay(DateTime dateTime)
        {
            int day = DateTime.DaysInMonth(dateTime.Year, dateTime.Month);

            return new DateTime(dateTime.Year, dateTime.Month, day);
        }
    }
}

/// <summary>
/// 关于返回值形式的枚举
/// </summary>
public enum diffResultFormat
{
    /// <summary>
    /// 年数和月数
    /// </summary>
    yymm,
    /// <summary>
    /// 年数
    /// </summary>
    yy,
    /// <summary>
    /// 月数
    /// </summary>
    mm,
    /// <summary>
    /// 天数
    /// </summary>
    dd,
}