如何确定特定日期的周数?

12

我正在尝试使用wpf制作日历。通过使用itemsPanel等,我有了一个具有7列(周日至周六)和6行(每月的周数)的网格。如果我可以通过获取每个月份第一天的星期几和月份中的周数来找到其起始位置,那么如何找到每个月份的周数(0-5)呢?另外,我能否从那里开始填写日历?我迷失了方向,不知道还能尝试什么。

public partial class SchedulePage : Page
{        
    MainWindow _parentForm;
    public int dayofweek;

    public SchedulePage(MainWindow parentForm)
    {
        InitializeComponent();
        _parentForm = parentForm;
        // DateTime date = new DateTime(year, month, day);

        _parentForm.bindings = new BindingCamper();          
        _parentForm.bindings.schedule.Add(new Schedule { WeekNo = (int) getWeekNumber(), WeekDay = dayofweek });
        DataContext = _parentForm.bindings;
        // lblTest.Content = dates(2011, 10, 27);
    }

    public double getWeekNumber()
    {
        dayofweek = getWeekDay(2011, 10, 31);
        double h = dayofweek / 7;
        double g = Math.Floor(h);
        return g;
    }

    public int getWeekDay(int year, int month, int day)
    {
        //year = 2011;
        //month = 10;
        //day = 27;
        int[] t = { 0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4 };
        // year -= month < 3;
        return (year + year / 4 - year / 100 + year / 400 + t[month - 1] + day) % 7;
    }
3个回答

17

你必须使用Calendar.GetDayOfWeekCalendar.GetWeekOfYear,而不是自己编写代码。

如果你自己编写日期/时间处理代码,无法保证其在不同的区域设置下能正常工作且不含错误。

public class Row
{
    public string MonthWeek { get; set; }
    public string Year { get; set; }
    public string Month { get; set; }
    public string Day { get; set; }
    public string WeekOfYear { get; set; }
}

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        var l = new List<Row>();
        DateTime startDate = DateTime.Now;
        DateTime d = new DateTime(startDate.Year, startDate.Month, 1);
        var cal = System.Globalization.DateTimeFormatInfo.CurrentInfo.Calendar;
        var ms = cal.GetWeekOfYear(new DateTime(d.Year, d.Month, 1), System.Globalization.CalendarWeekRule.FirstDay, System.DayOfWeek.Sunday);
        for (var i = 1; d.Month == startDate.Month; d = d.AddDays(1))
        {
            var si = new Row();
            var month_week = (d.Day / 7) + 1;
            si.MonthWeek = month_week.ToString();
            si.Month = d.Year.ToString();
            si.Year = d.Month.ToString();
            si.Day = d.Day.ToString();
            si.WeekOfYear = cal.GetWeekOfYear(d, System.Globalization.CalendarWeekRule.FirstDay, DayOfWeek.Sunday).ToString();
            l.Add(si);
        }
        dataGrid1.ItemsSource = l;
    }
}

连同在XAML中必须使用的DataGrid:

    <DataGrid AutoGenerateColumns="true" Name="dataGrid1" />

这将返回该日期属于第几周,范围是1-53。但我该如何使用这些信息呢?因为我的网格有6行grid.row 0-5。对不起,我很无知,这对我来说都是新的。换句话说,列是星期几,而行是周数。我不知道如何将其应用于网格并填充所有内容。 - TMan
谢谢,var ms和i是用来做什么的?它们从未被用于任何事情? - TMan
ms 是本月第几周的起始数字。i 没有被使用,因为它实际上总是与月份日期相同。 - Richard Harrison

11
你可以使用全球化中的 Calendar.GetWeekOfYear 来完成此操作。
这是它的 MSDN 文档: http://msdn.microsoft.com/en-us/library/system.globalization.calendar.getweekofyear.aspx 你应该从 CultureInfo.CurrentCulture 中传递适当的区域设置属性到 GetWeekOfYear ,以便正确匹配当前的文化。
例如:
int GetWeekOfYear(DateTime date)
{
    return Calendar.GetWeekOfYear(
        date,
        CultureInfo.CurrentCulture.DateTimeFormat.CalendarWeekRule,
        CultureInfo.CurrentCulture.DateTimeFormat.FirstDayOfWeek
    );
}

您可以轻松地将此修改为 DateTime 的扩展方法:

static int GetWeekOfYear(this DateTime date)
{
    return Calendar.GetWeekOfYear(
        date,
        CultureInfo.CurrentCulture.DateTimeFormat.CalendarWeekRule,
        CultureInfo.CurrentCulture.DateTimeFormat.FirstDayOfWeek
    );
}

+1 - 但我会说“必须使用”而不是“可以使用”- 参考我的答案。 - Richard Harrison
我会警告你不要过于依赖那种方法 - 它会给你不一致的结果。例如,2012年12月30日是星期日。如果你使用周规则为FirstDay或者FirstFourDayWeek,并将星期天设为一周的第一天调用该方法,它会返回53。然而,如果你使用同一周中的日期Jan 1, 2013来调用该方法,你会得到1。 - AndrewS
这将返回该日期在1-53周中的哪一周,但我该如何使用这些信息呢?因为我的网格有6行grid.row 0-5。对不起,我很无知,这对我来说都是新的。 - TMan
换句话说,列是星期几,行是第几周。我不知道如何将其应用到网格中并填充所有内容。 - TMan
System.Globalization.Calendar.GetWeekOfYear是一个非静态方法。可以使用DateTimeFormatInfo.CurrentInfo下的实例,如此处所示。我更新了答案以反映这一点。 - Marco Lackovic
显示剩余3条评论

0

根据@Polynomial的回答,我遇到了以下错误:

需要对象引用才能访问非静态字段、方法或属性...

如果您在之前实例化了GregorianCalendar,则可以调用GetWeekOfYear方法!

private static int GetWeekNumber(DateTime time)
{
    GregorianCalendar cal = new GregorianCalendar();
    int week = cal.GetWeekOfYear(time, CalendarWeekRule.FirstFullWeek, DayOfWeek.Monday);
    return week;
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接