在使用C#开发软件时,我们可以使用.NET Framework中的DateTime结构(System命名空间)来处理日期和时间;但是,在DateTime结构中却少了一些关于星期的常用计算方法,比如:
- 某一天是当年中的第几周。
- 某一天是当月中的第几周。
- 获取星期几的中文名称。
以下就是这三个方法的实现,它们被定义在CDateTime类中:
public class CDateTime
{
// 中文星期名称
private static string[] arrWeekDayName =
{"星期日","星期一","星期二","星期三",
"星期四","星期五","星期六"};
// 某一天是当年中的第几周
public static int WeekOfYear(DateTime dt)
{
DateTime firstDay = new DateTime(dt.Year,1,1);
int firstSunday = (7 - (int)firstDay.DayOfWeek) % 7 + 1;
int curDayOfYear = dt.DayOfYear;
if (curDayOfYear < firstSunday)
return 1;
else if (firstSunday == 1)
return (curDayOfYear - firstSunday) / 7 + 1;
else
return (curDayOfYear - firstSunday) / 7 + 2;
}
// 某一天是当月中的第几周
public static int WeekOfMonth(DateTime dt)
{
DateTime firstDay = new DateTime(dt.Year, dt.Month, 1);
int firstSunday = (7 - (int)firstDay.DayOfWeek) % 7 + 1;
if (dt.Day < firstSunday)
return 1;
else if (firstSunday == 1)
return (dt.Day - firstSunday) / 7 + 1;
else
return (dt.Day - firstSunday) / 7 + 2;
}
// 获取星期几的中文名称
public static string WeekDayName(DateTime dt)
{
int dayOfWeek = (int)dt.DayOfWeek;
return arrWeekDayName[dayOfWeek];
}
}
WeekOfYear()和WeekOfMonth()方法
首先看WeekOfYear()和WeekOfMonth()方法,它们的算法是基本一样的。
firstDay变量用于确定当年或当月的第一天。
firstSunday变量用于保存第一个周日是当年(或当月)的第几天。
如果指定的日期早于第一个周日,则为第一周;否则通过这个日期与第一个周日相差的天数来计算它位于第几周。
算法中的关键在DayOfWeek枚举值中,其中,周日值为0,周一到周六的值分别为1到6,我们正是通过这些关键数据来计算的。
WeekDayName()方法
WeekDayName()方法实现非常简单,有很多朋友使用if语句或switch语句来实现这一功能;而这里,我们使用了一个字符串数组来保存周几的名称,然后,通过DayOfWeek枚举值直接获取相应的名称。
这种使用数组的方法称为“表驱动法”,其特点是:
- 以空间换时间,比条件语句有着更高的执行效率,特别是对于固定的、会经常调用的数据。
- 代码便于阅读和维护,简单的代码会更加直观。
这个说法不确切。
我们可以用DateTime结构的ToString()方法来获取星期几的中文名称。比如:
System.DateTime dt = new System.DateTime(2014, 10, 1);
string name = dt.ToString("dddd", new System.Globalization.CultureInfo("zh-CN").DateTimeFormat);
System.Console.WriteLine(name);
如果线程的当前文化是中文,还可以简化为:
string name = dt.ToString("dddd");
另外,把 "dddd" 改为 "ddd",得到的值就是 "周三" 而不是 "星期三"。
因此,获取星期几的中文名称的扩展方法可以简化为:
// 获取星期几的中文名称
public static string WeekDayName(this DateTime dt)
{
return dt.ToString("dddd", new System.Globalization.CultureInfo("zh-CN").DateTimeFormat);
}
{
public static class CDateTime
{
public static int WeekOfYear(this DateTime dt) {/* ... */}
public static int WeekOfMonth(this DateTime dt) {/* ... */}
public static string WeekDayName(this DateTime dt) {/* ... */}
}
}
建议实现为扩展方法,这样就能把它们伪装成 DateTime 结构的方法来调用:
using ExtensionMethods;
int week = System.DateTime.ToDay.WeekOfYear();