C# 日期时间数组

本文关键字:数组 时间 日期 | 更新日期: 2023-09-27 18:33:48

我有两个数组,array1 具有从上午 8 点到下午 2 点按分钟计算的日期时间数据,array2 具有从同一日期上午 8 点到下午 1 点按小时计算的日期时间数据。

我想输出两个具有相同 datetime.hour 的数组的索引号,并且它应该与 array2 中所有 Array1 中晚于 array2 的日期时间数据的最后一个可用索引号相匹配。

例如,如果我有两个这样的日期时间数组:

DateTime[] dateTimes1 = new DateTime[]
        {
            new DateTime(2010, 10, 1, 8, 15, 0),
            new DateTime(2010, 10, 1, 8, 30, 1),
            new DateTime(2010, 10, 1, 8, 45, 2),
            new DateTime(2010, 10, 1, 9, 15, 3),
            new DateTime(2010, 10, 1, 9, 30, 4),
            new DateTime(2010, 10, 1, 9, 45, 5),
            new DateTime(2010, 10, 1, 10, 15, 6),
            new DateTime(2010, 10, 1, 10, 30, 7),
            new DateTime(2010, 10, 1, 10, 45, 8),
            new DateTime(2010, 10, 1, 11, 15, 9),
            new DateTime(2010, 10, 1, 11, 30, 10),
            new DateTime(2010, 10, 1, 11, 45, 11),
            new DateTime(2010, 10, 1, 12, 15, 12),
            new DateTime(2010, 10, 1, 12, 30, 13),
            new DateTime(2010, 10, 1, 12, 45, 14),
            new DateTime(2010, 10, 1, 13, 15, 15),
            new DateTime(2010, 10, 1, 13, 30, 16),
            new DateTime(2010, 10, 1, 13, 45, 17),
            new DateTime(2010, 10, 1, 14, 15, 18),
            new DateTime(2010, 10, 1, 14, 30, 19),
            new DateTime(2010, 10, 1, 14, 45, 20),
        };
        DateTime[] dateTimes2 = new DateTime[]
        {
            new DateTime(2010, 10, 1, 8, 0, 0),
            new DateTime(2010, 10, 1, 9, 0, 1),
            new DateTime(2010, 10, 1, 10, 0, 2),
            new DateTime(2010, 10, 1, 11, 0, 3),
            new DateTime(2010, 10, 1, 12, 0, 4),
            new DateTime(2010, 10, 1, 13, 0, 5),
        };

它应该给我输出:

0, 0
1, 0
2, 0
3, 1
4、1
5, 1
6, 2
7, 2
8, 2
9、3
10, 3
11, 3
12, 4
13, 4
14, 4
15, 5
16, 5
17, 5
18, 5
19, 5
20, 5

这是我尝试过的:

            int i = 0;
            int j = 0;
            while (i < dateTimes1.Length && j < dateTimes2.Length)
            {     
                if (dateTimes1[i].Date == dateTimes2[j].Date && dateTimes1[i].Hour == dateTimes2[j].Hour)
                {
                    list.Add(i);
                    list2.Add(j);
                    i++;
                }
                else if (dateTimes1[i] < dateTimes2[j])
                {
                    i++;
                }
                else if (dateTimes1[i] > dateTimes2[j])
                {
                    j++;
                }
            }
            for (int k = 0; k < list.Count; k++)
            {
                Console.WriteLine(list[k] + " , " + list2[k];
            }

但它不会在下午 1 点之后输出索引号。

C# 日期时间数组

您的两个列表的长度不同。在您的 while 语句中,您正在尝试同时迭代两个不同的长度列表。

如果我正确理解您的要求,您应该使用内部循环来执行以下操作:

DateTime[] dateTimes1 = new DateTime[]
    {
        new DateTime(2010, 10, 1, 8, 15, 0),
        new DateTime(2010, 10, 1, 8, 30, 1),
        new DateTime(2010, 10, 1, 8, 45, 2),
        new DateTime(2010, 10, 1, 9, 15, 3),
        new DateTime(2010, 10, 1, 9, 30, 4),
        new DateTime(2010, 10, 1, 9, 45, 5),
        new DateTime(2010, 10, 1, 10, 15, 6),
        new DateTime(2010, 10, 1, 10, 30, 7),
        new DateTime(2010, 10, 1, 10, 45, 8),
        new DateTime(2010, 10, 1, 11, 15, 9),
        new DateTime(2010, 10, 1, 11, 30, 10),
        new DateTime(2010, 10, 1, 11, 45, 11),
        new DateTime(2010, 10, 1, 12, 15, 12),
        new DateTime(2010, 10, 1, 12, 30, 13),
        new DateTime(2010, 10, 1, 12, 45, 14),
        new DateTime(2010, 10, 1, 13, 15, 15),
        new DateTime(2010, 10, 1, 13, 30, 16),
        new DateTime(2010, 10, 1, 13, 45, 17),
        new DateTime(2010, 10, 1, 14, 15, 18),
        new DateTime(2010, 10, 1, 14, 30, 19),
        new DateTime(2010, 10, 1, 14, 45, 20),
    };
    DateTime[] dateTimes2 = new DateTime[]
    {
        new DateTime(2010, 10, 1, 8, 0, 0),
        new DateTime(2010, 10, 1, 9, 0, 1),
        new DateTime(2010, 10, 1, 10, 0, 2),
        new DateTime(2010, 10, 1, 11, 0, 3),
        new DateTime(2010, 10, 1, 12, 0, 4),
        new DateTime(2010, 10, 1, 13, 0, 5),
    };
    int i = 0;
    while (i < dateTimes1.Length)
    {
        int j = 0;
        while (j < dateTimes2.Length))
        {
            if (dateTimes1[i].Date == dateTimes2[j].Date && dateTimes1[i].Hour == dateTimes2[j].Hour)
            {
                list.Add(i);
                list2.Add(j);
                i++;
            }
            else if (dateTimes1[i] < dateTimes2[j])
            {
                i++;
            }
            else if (dateTimes1[i] > dateTimes2[j])
            {
                j++;
            }
        }
    }
    for (int k = 0; k < list.Count; k++)
    {
        Console.WriteLine(list[k] + " , " + list2[k];
    }       

这是一个使用 Array.FindIndexforeach 的非常基本的方法:

编辑:更新了此答案以处理">匹配 array2 中晚于 array2 的所有日期时间数据的 array2 的最后一个可用索引号"问题。

foreach (DateTime dt in dateTimes1)
{   
    int currentHour = dt.Hour;
    int lastHour = dateTimes2[dateTimes2.GetUpperBound(0)].Hour; //GetUpperBound(0) is the last index
    int dt1index = Array.FindIndex(dateTimes1, a => a == dt); //get the index of the current item in dateTimes1
    int dt2index = Array.FindIndex(dateTimes2, x => x.Hour == currentHour); //get the index of the item in dateTimes2 matching dateTimes1 hour field        
    if (currentHour > lastHour)
    {
        Console.WriteLine("{0}, {1}", dt1index, dateTimes2.GetUpperBound(0));
    }
    else
    {
        Console.WriteLine("{0}, {1}", dt1index, dt2index);
    }             
}

这只会查看 dateTimes1dateTimes2 中的每个值,并返回它找到的第一个匹配项(与您的循环非常相似(。

为了确定dt1index,我们查看dateTimes1并返回第一个匹配项,其中a => a == dt(a只是谓词,表示dateTimes1中的"当前"值 - 想想i = 0,1,2,etc在常规循环中(。

类似地,为了确定dt2index,我们寻找x => x.Hour == dt.Hour上的第一个匹配项——也就是说,"当前"dt的小时字段与dateTimes2中的小时字段匹配。

在这两种情况下,都会返回第一个匹配项 - 如果未找到匹配项,则返回-1

当我们去写入控制台时,我们检查currentHour是否大于dateTimes2的最后一小时,如果是,我们只写入dateTimes1的当前索引和dateTimes2的最后一个索引。否则,我们写入 dateTimes1 的当前索引和小时匹配的索引 dateTimes2 .

使用 Linq:

var hour = new TimeSpan(1, 0, 0);
var dt2MaxValue = dateTimes2.Max();
for (int i = 0; i < dateTimes1.Length; i++)
{
    var output = string.Format("{0}, {1}",
        i,
        dateTimes2
           .Select((o, index) => new { index = index, value = o })
           .Where(dt2 => (dateTimes1[i] - dt2.value) < hour 
                           || dt2.value == dt2MaxValue)
           .Select(dt2 => dt2.index)
           .FirstOrDefault());
    Console.WriteLine(output);
}

上述 Linq 语句的作用:

  • 第一个Select使用该方法的重载,该方法也传递项的索引。这仅允许该信息级联。它使用匿名对象,索引和集合项分别是indexvalue属性。

  • Where 子句查询这些匿名对象的集合,并将其valuedateTime1[i]进行比较。它得到value小于 dateTime1[i] 但不超过 1 小时的那个,或者如果它是整个集合中的最大value

  • 第二个Select只是获取Where筛选的项目的索引。

  • FirstOrDefault只返回该值(即,第一个或默认值,即所选项目的索引,如果未选择任何项目,则返回 0(。