【问题标题】:How to split list of dates into weeks如何将日期列表拆分为周
【发布时间】:2016-06-16 00:47:42
【问题描述】:

我有一个日期列表,范围从 2015 年 7 月到 2016 年 1 月

2015/07/20 14:15:23 2015/07/20 14:16:06 2015/07/26 23:39:15 2015/09/02 22:51:46 2015/09/02 22:52:33 2015/10/26 20:42:23 2015/11/12 14:54:31 2015/11/30 06:49:10 2015/12/02 10:18:17 2015/12/10 08:34:53 2015/12/10 15:15:33 2015/12/15 06:43:32 2015/12/29 02:55:01 2016/01/12 19:46:45 2016/01/13 07:31:14 2016/01/13 07:32:59 2016/01/14 05:28:33

我想将这些分成几周,所以我确切地知道已经过去了多少周,并计算每个组的数量。我正在从 web 服务中提取日期并将它们放入 datagridview 中。

我要添加一个名为 week 的列,我无法在其中添加每个列所属的周。

if (SplitChkBox.Checked == true)
{
    column = new DataColumn();
    column.DataType = System.Type.GetType("System.String");
    column.ColumnName = "Week";
    table.Columns.Add(column);
}

最后我会创建一个图表来显示每周有多少实例。

谢谢!

编辑

2015/07/202016/01/14 大约有 25 周的时间。如果超过 0,我想返回 1-25 以及属于该组的周数。

【问题讨论】:

  • 所以您正在寻找一年中的一周?
  • 这里你可以找到如何获得一周stackoverflow.com/questions/11154673/…
  • 我已将日期转换为 ISO 格式,尽管在这个问题中很清楚使用的是什么格式,但使用国际标准以避免歧义仍然是 SO 的良好做法。

标签: c# winforms


【解决方案1】:

计算出你需要什么是相当简单的,但最复杂的是计算出你正在查看一年中的哪一周。 .NET 框架通过提供许多不同的日历来帮助您——包括许多不是Gregorian 的日历。很可能您可以使用CultureInfo.CurrentCulture.DateTimeFormat.Calendar 来获取您的日历。

那么你可以这样做:

var results =
    dates
        .GroupBy(x => CultureInfo.CurrentCulture.DateTimeFormat.Calendar
            .GetWeekOfYear(x, CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Monday))
        .SelectMany(gx => gx, (gx, x) => new
        {
            Week = gx.Key,
            DateTime = x,
            Count = gx.Count(),
        });

请注意,周数基于CalendarWeekRuleDayOfWeek 的两个额外参数。第一个参数可以选择FirstDay, FirstFourDayWeek, FirstFullWeek,第二个参数可以选择一周中的任何一天。

我已使用.SelectMany 将结果展平,以及如何获取周数和计数,但您可能需要以不同的格式生成数据,但这应该有助于计算。

这是我得到的结果:


根据您的编辑,很容易进行从最早日期开始按周分组的查询。

var firstDay = dates.Min().Date;

var results =
    dates
        .GroupBy(x => x.Date.Subtract(firstDay).Days / 7 + 1)
        .SelectMany(gx => gx, (gx, x) => new
        {
            Week = gx.Key,
            DateTime = x,
            Count = gx.Count(),
        });

我现在得到这个结果:

我不明白您所说的“如果超过 0,则属于该组的周数”。

【讨论】:

  • 我添加了一个编辑,我想将日期分成大约 25 周,从最早的日期到最晚的日期,每个星期都有一个。
【解决方案2】:

你的意思是这样吗(它做了一些简化的假设):

List<DateTime> DateList = new List<DateTime>();

DateList.Add(DateTime.Parse("7 / 20 / 2015 2:15:23 PM"));
DateList.Add(DateTime.Parse(" 7 / 20 / 2015 2:16:06 PM"));
DateList.Add(DateTime.Parse(" 7 / 26 / 2015 11:39:15 PM"));
DateList.Add(DateTime.Parse(" 9 / 2 / 2015 10:51:46 PM"));
DateList.Add(DateTime.Parse(" 9 / 2 / 2015 10:52:33 PM"));
DateList.Add(DateTime.Parse(" 10 / 26 / 2015 8:42:23 PM"));
DateList.Add(DateTime.Parse(" 11 / 12 / 2015 2:54:31 PM"));
DateList.Add(DateTime.Parse(" 11 / 30 / 2015 6:49:10 AM"));
DateList.Add(DateTime.Parse(" 12 / 2 / 2015 10:18:17 AM"));
DateList.Add(DateTime.Parse(" 12 / 10 / 2015 8:34:53 AM"));
DateList.Add(DateTime.Parse(" 12 / 10 / 2015 3:15:33 PM"));
DateList.Add(DateTime.Parse(" 12 / 15 / 2015 6:43:32 AM"));
DateList.Add(DateTime.Parse(" 12 / 29 / 2015 2:55:01 AM"));
DateList.Add(DateTime.Parse(" 1 / 12 / 2016 7:46:45 PM"));
DateList.Add(DateTime.Parse(" 1 / 13 / 2016 7:31:14 AM"));
DateList.Add(DateTime.Parse("1 / 13 / 2016 7:32:59 AM"));
DateList.Add(DateTime.Parse("1 / 14 / 2016 5:28:33 AM"));

Dictionary<int, int> MyHistogram = new Dictionary<int, int>();

foreach(DateTime MyDateTime in DateList)
{
    int Week = MyDateTime.DayOfYear / 7;

    if (MyHistogram.ContainsKey(Week))
        MyHistogram[Week]++;
    else
        MyHistogram.Add(Week, 1);
}

【讨论】:

  • 我需要重新回答我的答案,但鉴于最早的日期是 2015 年 7 月 20 日,距离 1 月 14 日还有 26 周。这就是我希望每个日期时间分组的方式,26 周。这可能吗?
  • @Sewder - 您可以使用您希望的任何周组合预初始化直方图“桶”(将每个组合初始化为零)。
【解决方案3】:

如果要一年中的周数,可以使用Calendar类:

DateTime date = new DateTime(2015, 07, 20);

DateTimeFormatInfo dateTimeFormatInfo = DateTimeFormatInfo.CurrentInfo;  // Current culture-specific information about the format of date and time.          
Calendar calendar = dateTimeFormatInfo.Calendar;                         // Calendar used in current culture.

var weekOfYear = calendar.GetWeekOfYear(date,                                // The date
                                        dateTimeFormatInfo.CalendarWeekRule, // Rule for determining the first week of the year.
                                        dateTimeFormatInfo.FirstDayOfWeek);  // Day used as the first day of week

编辑:

您可以为DateTime创建一个扩展,返回一周以便于使用:

public static class DateTimeExtensions
{
    public static int GetWeekOfYear(this DateTime date)
    {
        DateTimeFormatInfo dateTimeFormatInfo = DateTimeFormatInfo.CurrentInfo;
        Calendar calendar = dateTimeFormatInfo.Calendar;

        var weekOfYear = calendar.GetWeekOfYear(date,
                                                dateTimeFormatInfo.CalendarWeekRule,
                                                dateTimeFormatInfo.FirstDayOfWeek);

        return weekOfYear;
    }
}

并使用GroupBy() 对日期进行分组:

var dates = new DateTime[] { /* dates */ };

var groups = dates.GroupBy(d => d.GetWeekOfYear()).Select(g => new 
{
    Week = g.Key,
    Dates = g.ToArray(),
    Count = g.Count()
});

【讨论】:

  • 我会将它与 LINQ 结合起来。像 groupedDates = myDateList.GroupBy(d => myCalendar.GetWeekOfYear(d)) 这样的东西。然后您可以获取每个组的计数,并根据需要以其他方式继续处理。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-08-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-05-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多