转换日期列表的最佳方法是什么,如果它包含连续的日期,它会以组的形式显示?

时间:2015-05-31 16:09:11

标签: c# datetime collections

我有一个日期列表

 var list = new List<DateTime>();
 list.Add(new DateTime(2014, 1,1);
 list.Add(new DateTime(2014, 1,2);
 list.Add(new DateTime(2014, 1,3);
 list.Add(new DateTime(2014, 1,5);
 list.Add(new DateTime(2014, 1,6);
 list.Add(new DateTime(2014, 1,11);

并且某些日期是连续的。我想将连续的日期组合在一起并在UI上呈现为:

"Jan 1-3, 2015; Jan 5-6, 2015; Jan 11, 2015"

这样做的正确方法是什么?没有这个。我会做这样的事情:

 var display = String.Join(";", list.Select(r=>r.ToString("dd-MMM-yyyy"));

2 个答案:

答案 0 :(得分:1)

void Main()
{
    var list = new List<DateTime>();
    list.Add(new DateTime(2014, 1, 1));
    list.Add(new DateTime(2014, 1, 2));
    list.Add(new DateTime(2014, 1, 3));
    list.Add(new DateTime(2014, 1, 5));
    list.Add(new DateTime(2014, 1, 6));
    list.Add(new DateTime(2014, 1, 11));

    string output = string.Join("; ", GetRanges(list).Select(FormatRange));

    Console.WriteLine(output);
    // Jan 1–3, 2014; Jan 5–6, 2014; Jan 11, 2014
}

private string FormatRange (DateRange range)
{
    if (range.Start.Year != range.End.Year)
        return range.Start.ToString("MMM d, yyyy") + " – " + range.End.ToString("MMM d, yyyy");
    else if (range.Start.Month != range.End.Month)
        return range.Start.ToString("MMM d") + " – " + range.End.ToString("MMM d, yyyy");
    else if (range.Start.Day != range.End.Day)
        return range.Start.ToString("MMM d") + "–" + range.End.ToString("d, yyyy");
    else
        return range.Start.ToString("MMM d, yyyy");
}

private List<DateRange> GetRanges (IEnumerable<DateTime> dates)
{
    List<DateRange> ranges = new List<DateRange>();
    DateRange current = null;
    DateTime? previous = null;

    foreach (DateTime date in dates)
    {
        if (!previous.HasValue)
            current = new DateRange() { Start = date };
        else if ((date - previous.Value).Days > 1)
        {
            current.End = previous.Value;
            ranges.Add(current);
            current = new DateRange() { Start = date };
        }   
        previous = date;
    }

    if (previous.HasValue)
    {
        current.End = previous.Value;
        ranges.Add(current);
    }

    return ranges;
}

public class DateRange
{
    public DateTime Start { get; set; }
    public DateTime End { get; set; }
}

答案 1 :(得分:0)

这将完成工作:

    private string BuildRanges(List<DateTime> DateList)
    {
        string result = "";

        int start = 0;
        int end = 0;
        DateTime curr, prev;

        for (int i = 1; i <= DateList.Count; i++)
        {
            if (i < DateList.Count)
            {
                curr = DateList[i];
                prev = DateList[i - 1];

                if (curr.Year == prev.Year && curr.Month == prev.Month && curr.Day == prev.Day + 1)
                {
                    end = i;
                    continue;
                }
            }

            if (start == end)
            {
                result += DateList[start].ToString("MMM d, yyyy");
            }
            else
            {
                result += DateList[start].ToString("MMM d") + "-" + DateList[end].ToString("d, yyyy");
            }
            result += "; ";

            start = end = i;
        }

        return result.Substring(0, result.Length - 2);
    }

像这样使用它:

        var list = new List<DateTime>();
        list.Add(new DateTime(2014, 1, 1));
        list.Add(new DateTime(2014, 1, 2));
        list.Add(new DateTime(2014, 1, 3));
        list.Add(new DateTime(2014, 1, 5));
        list.Add(new DateTime(2014, 1, 6));
        list.Add(new DateTime(2014, 1, 11));

        var display = BuildRanges(list);