在使用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枚举值直接获取相应的名称。

这种使用数组的方法称为“表驱动法”,其特点是:

  • 以空间换时间,比条件语句有着更高的执行效率,特别是对于固定的、会经常调用的数据。
  • 代码便于阅读和维护,简单的代码会更加直观。