using System;
using System.Data;
using System.Configuration;
 
using System.Runtime.InteropServices;

/// <summary>
/// DateTimeEx类：扩展了一些日期时间方法
/// </summary>
public class DateTimeEx
{
	public DateTimeEx()
	{
		//
		// TODO: 在此处添加构造函数逻辑
		//
	}

	/// <summary>
	/// 得到中文形式的日期
	/// </summary>
	/// <param name="dt"></param>
	/// <returns></returns>
	public static string GetChineseDate(DateTime dt)
	{
		return dt.Year.ToString() + "年" + dt.Month.ToString() + "月" + dt.Day.ToString() + "日";
	}

	/// <summary>
	/// 得到中文形式的时间
	/// </summary>
	/// <param name="dt"></param>
	/// <returns></returns>
	public static string GetChineseTime(DateTime dt)
	{
		return dt.Hour.ToString() + "点" + dt.Minute.ToString() + "分" + dt.Second.ToString() + "秒";
	}

	/// <summary>
	/// 得到中文形式的日期时间
	/// </summary>
	/// <param name="dt"></param>
	/// <returns></returns>
	public static string GetChineseDateTime(DateTime dt)
	{
		return GetChineseDate(dt) + GetChineseTime(dt);
	}

	/// <summary>
	/// 得到某月的最后一天
	/// </summary>
	/// <param name="dt">日期</param>
	/// <returns>返回最后一天的日期</returns>
	public static DateTime GetLastDateOfMonth(DateTime dt)
	{
		return GetLastDateOfMonth(dt.Year, dt.Month);
	}

	/// <summary>
	/// 得到某月的最后一天
	/// </summary>
	/// <param name="year">年</param>
	/// <param name="month">月</param>
	/// <returns>返回最后一天的日期</returns>
	public static DateTime GetLastDateOfMonth(int year, int month)
	{
		if (month < 1) month = 1;
		if (month > 12) month = 12;
		return (new DateTime(year, month, 1)).AddMonths(1).AddDays(-1);
	}

	/// <summary>
	/// 得到某月的最后一豪秒
	/// </summary>
	/// <param name="dt">日期</param>
	/// <returns>返回最后一豪秒的日期</returns>
	public static DateTime GetLastDateTimeOfMonth(DateTime dt)
	{
		return GetLastDateTimeOfMonth(dt.Year, dt.Month);
	}

	/// <summary>
	/// 得到某月的最后一豪秒
	/// </summary>
	/// <param name="year">年</param>
	/// <param name="month">月</param>
	/// <returns>返回最后一豪秒的日期</returns>
	public static DateTime GetLastDateTimeOfMonth(int year, int month)
	{
		if (month < 1) month = 1;
		if (month > 12) month = 12;
		return (new DateTime(year, month, 1)).AddMonths(1).AddSeconds(-1);
	}

	/// <summary>
	/// 得到某月的第一天
	/// </summary>
	/// <param name="dt">日期</param>
	/// <returns>返回第一天的日期</returns>
	public static DateTime GetFirstDateOfMonth(DateTime dt)
	{
		return GetFirstDateOfMonth(dt.Year, dt.Month);
	}

	/// <summary>
	/// 得到某月的第一天
	/// </summary>
	/// <param name="year">年</param>
	/// <param name="month">月</param>
	/// <returns>返回第一天的日期</returns>
	public static DateTime GetFirstDateOfMonth(int year, int month)
	{
		if (month < 1) month = 1;
		if (month > 12) month = 12;
		return new DateTime(year, month, 1);
	}

	/// <summary>
	/// 得到某年的第一天
	/// </summary>
	/// <param name="year">年</param>
	/// <returns>返回第一天的日期</returns>
	public static DateTime GetFirstDateOfYear(int year)
	{
		return new DateTime(year, 1, 1);
	}

	/// <summary>
	/// 得到某年的第一天
	/// </summary>
	/// <param name="dt">日期</param>
	/// <returns>返回第一天的日期</returns>
	public static DateTime GetFirstDateOfYear(DateTime dt)
	{
		return GetFirstDateOfYear(dt.Year);
	}

	/// <summary>
	/// 得到某年的最后一天
	/// </summary>
	/// <param name="year">年</param>
	/// <returns>返回最后一天的日期</returns>
	public static DateTime GetLastDateOfYear(int year)
	{
		return new DateTime(year, 12, 31);
	}

	/// <summary>
	/// 得到某年的最后一天
	/// </summary>
	/// <param name="dt">日期</param>
	/// <returns>返回最后一天的日期</returns>
	public static DateTime GetLastDateOfYear(DateTime dt)
	{
		return GetLastDateOfYear(dt.Year);
	}

	/// <summary>
	/// 得到某年的最后一毫秒
	/// </summary>
	/// <param name="year">年</param>
	/// <returns>返回最后一毫秒的日期时间对象</returns>
	public static DateTime GetLastDateTimeOfYear(int year)
	{
		return new DateTime(year + 1, 1, 1).AddSeconds(-1);
	}

	/// <summary>
	/// 得到某年的最后一毫秒
	/// </summary>
	/// <param name="dt">日期</param>
	/// <returns>返回最后一毫秒的日期时间对象</returns>
	public static DateTime GetLastDateTimeOfYear(DateTime dt)
	{
		return GetLastDateTimeOfYear(dt.Year);
	}

	/// <summary>
	/// 计算某段时间内，每月的天数
	/// </summary>
	/// <param name="beginTime">开始时间</param>
	/// <param name="endTime">结束时间</param>
	/// <returns>返回天数</returns>
	public static float GetDaysOfMonth(DateTime beginTime, DateTime endTime)
	{
		float days;
		if (beginTime.Year == endTime.Year && beginTime.Month == endTime.Month)
		{
			//如果是同一个月，返回这个月的天数
			DateTime t1 = new DateTime(beginTime.Year, beginTime.Month, 1);
			DateTime t2 = t1.AddMonths(1);
			TimeSpan interval = t2.Subtract(t1);
			days = interval.Days;
		}
		else if (beginTime.Year == endTime.Year)
		{
			//如果是同一年，返回这一年的平均月天数
			DateTime t1 = new DateTime(beginTime.Year, 1, 1);
			DateTime t2 = new DateTime(beginTime.Year + 1, 1, 1);
			TimeSpan interval = t2.Subtract(t1);
			days = (float)(1.0 * interval.Days / 12);
		}
		else
		{
			//否则返回每4年的平均月天数
			days = (float)((365.0 * 3 + 366) / 48);
		}
		return days;
	}

	/// <summary>
	/// 得到某日所在周的第一天
	/// </summary>
	/// <param name="dt">日期</param>
	/// <returns>返回某日所在周的第一天</returns>
	public static DateTime GetFirstDateOfWeek(DateTime dt)
	{
		int days = (int)dt.DayOfWeek;
		TimeSpan ts = new TimeSpan(days, 0, 0, 0);
		return dt.Date - ts;
	}

	/// <summary>
	/// 得到某日所在周的最后一天
	/// </summary>
	/// <param name="dt">日期</param>
	/// <returns>返回某日所在周的最后一天</returns>
	public static DateTime GetLastDateOfWeek(DateTime dt)
	{
		int days = 6 - (int)dt.DayOfWeek;
		TimeSpan ts = new TimeSpan(days, 0, 0, 0);
		return dt.Date + ts;
	}

	/// <summary>
	/// 得到某日所在周的最后一豪秒
	/// </summary>
	/// <param name="dt">日期</param>
	/// <returns>返回某日所在周的最后一毫秒</returns>
	public static DateTime GetLastDateTimeOfWeek(DateTime dt)
	{
		int days = 6 - (int)dt.DayOfWeek;
		TimeSpan ts = new TimeSpan(days, 0, 0, 0);
		DateTime lastDate = dt.Date + ts;
		return new DateTime(lastDate.Year, lastDate.Month, lastDate.Day, 23, 59, 59, 59);
	}

	/// <summary>
	/// 得到本月已经过去的天数
	/// </summary>
	/// <returns>返回本月已经过去的天数</returns>
	public static int GetThisMonthPastDays()
	{
		int days;
		DateTime today = DateTime.Today;
		DateTime firstDayOfCurMonth = DateTimeEx.GetFirstDateOfMonth(today);
		TimeSpan ts = today - firstDayOfCurMonth;
		days = (int)ts.TotalDays;
		if (days < 1)
			days = 1;
		return days;
	}

	/// <summary>
	/// 得到本年已经过去的天数
	/// </summary>
	/// <returns>返回本年已经过去的天数</returns>
	public static int GetThisYearPastDays()
	{
		int days;
		DateTime today = DateTime.Today;
		DateTime firstDayOfCurYear = DateTimeEx.GetFirstDateOfYear(today);
		TimeSpan ts = today - firstDayOfCurYear;
		days = (int)ts.TotalDays;
		if (days < 1) days = 1;
		return days;
	}

	/// <summary>
	/// 得到本周已经过去的天数
	/// </summary>
	/// <returns>返回本周已经过去的天数</returns>
	public static int GetThisWeekPastDays()
	{
		int days;
		DateTime today = DateTime.Today;
		DateTime firstDayOfCurWeek = DateTimeEx.GetFirstDateOfWeek(today);
		TimeSpan ts = today - firstDayOfCurWeek;
		days = (int)ts.TotalDays;
		if (days < 1) days = 1;
		return days;
	}

	/// <summary>
	/// 得到某日所在季度的第一天
	/// </summary>
	/// <param name="dt"></param>
	/// <returns></returns>
	public static DateTime GetFirstDateOfQuarter(DateTime dt)
	{
		int year = dt.Year;
		int month;
		int dtMonth = dt.Month;
		if (dtMonth == 1 || dtMonth == 2 || dtMonth == 3)
			month = 1;
		else if (dtMonth == 4 || dtMonth == 5 || dtMonth == 6)
			month = 4;
		else if (dtMonth == 7 || dtMonth == 8 || dtMonth == 9)
			month = 7;
		else
			month = 10;
		return new DateTime(year, month, 1);
	}

	/// <summary>
	/// 得到某日所在季度的最后一天
	/// </summary>
	/// <param name="dt"></param>
	/// <returns></returns>
	public static DateTime GetLastDateOfQuarter(DateTime dt)
	{
		return GetFirstDateOfQuarter(dt).AddMonths(3).AddDays(-1);	//即下一季度第1天减1天
	}

	/// <summary>
	/// 得到某日所在季度的最后一天的最后一秒
	/// </summary>
	/// <param name="dt"></param>
	/// <returns></returns>
	public static DateTime GetLastDateTimeOfQuarter(DateTime dt)
	{
		return GetFirstDateOfQuarter(dt).AddMonths(3).AddSeconds(-1);	//即下一季度第1天减1秒
	}

	/// <summary>
	/// 得到系统时钟周期的当前值
	/// </summary>
	/// <param name="lpPerformanceCount">输出参数，得到系统时钟周期的当前值</param>
	/// <returns>返回是否获取成功</returns>
	[DllImport("kernel32.dll", SetLastError = true)]
	public static extern bool QueryPerformanceCounter(out long lpPerformanceCount);
	
	/// <summary>
	/// 得到系统的时钟频率，每秒的周期数
	/// </summary>
	/// <param name="frequency">输出参数，得到系统的每秒周期数</param>
	/// <returns>返回是否获取成功</returns>
	[DllImport("kernel32.dll", SetLastError = true)]
	public static extern bool QueryPerformanceFrequency(out long frequency);
}
