以线性方式在列表中的日期时间之间进行插值,并将这些值重新应用于列表



我有这样的类:

public class Datumsobjekt
{
    public string dateiname { get; set; }
    public DateTime zeit { get; set; }
}

创建List<Datumsobjekt>并用值填充它时,我有时不会设置zeitzeit始终是升序的,无需排序。

这导致一个(示例(

filename1.ext - 03.01.15
filename2.ext - 04.01.15
filename3.ext - 
filename4.ext - 08.01.15

如何以线性方式在日期之间插值,以便每个dateiname都有一个zeit并将其重新应用于列表?

目标应该是类似于

filename1.ext - 03.01.15
filename2.ext - 04.01.15
filename3.ext - 06.01.15
filename4.ext - 08.01.15

对于第一个示例。

PS:也可能是

filename1.ext - 03.01.15
filename2.ext - 04.01.15
filename3.ext - 
filename4.ext - 
filename5.ext - 08.01.15

filename1.ext - 03.01.15
filename2.ext - 04.01.15
filename3.ext - 
filename4.ext - 
filename5.ext - 08.01.15
filename6.ext - 
filename7.ext - 
...
filenamen.ext - 
filenamen+1.ext - 09.01.15

即没有zeit的任意数量的dateiname并被给定的zeit中断。

DateTime有一个运算符Subtract,结果给出了一个TimeSpan对象。

这可用于减去 2 个DateTime对象;

System.DateTime date1 = new System.DateTime(1996, 6, 3, 22, 15, 0);
System.DateTime date2 = new System.DateTime(1996, 12, 6, 13, 2, 0);
System.DateTime date3 = new System.DateTime(1996, 10, 12, 8, 42, 0);
// diff1 gets 185 days, 14 hours, and 47 minutes.
System.TimeSpan diff1 = date2.Subtract(date1);
// diff2 gets 55 days 4 hours and 20 minutes.
System.TimeSpan diff2 = date2 - date3;

TimeSpan有一个有用的运算符Division它以双精度作为除数并给出TimeSpan结果。

可以将TimeSpan添加到DateTime以获得DateTime结果。


如果您需要在两个选定的DateTime之间有 n 个值,那么TimeSpan必须除以 n+1

示例 1:

dateTime1 = d1
datetime2 = ?    > 1 empty value
datetime3 = d3

所以interval = (datetime1 - datetime3) / (1 + 1)

datetime2 = datetime1 + interval.

示例 2:

dateTime1 = d1
datetime2 = ?  
datetime3 = ?   |
datetime4 = ?   |
datetime5 = ?   | 8 empty values
datetime6 = ?   |
datetime7 = ?   |
datetime8 = ?   |
datetime9 = ?  /
datetime10 = d10

所以interval = (datetime1 - dateime10) / (8 + 1)

datetime2 = datetime1 + interval.

datetime3 = datetime2 + interval.

datetime4 = datetime3 + interval.


数组索引的有趣之处在于,如果将 2 个索引相互减去,则它们给出所需的值:

例如 1:

index's: 3 - 1 = 2

例如 2:

index's: 10 - 1 = 9

class Program
{
    static void Main()
    {
        DateTime?[] dates = new DateTime?[]
        {
            new DateTime(2019,1,1),
            null,
            new DateTime(2019,1,3),
            null,null,
            new DateTime(2019,1,6),
            null,null,null,
            new DateTime(2019,1,10),
            null,null,null, null,null,null, null,null,null,
            new DateTime(2019,1,20),
        };
        Console.WriteLine("Before:");
        foreach (var zeit in dates)
            Console.WriteLine(zeit.HasValue ? zeit.ToString() : "<empty>");
        Interpolate_dates(dates);
        Console.WriteLine("nAfter:");
        foreach (var zeit in dates)
            Console.WriteLine(zeit.HasValue ? zeit.ToString() : "!!ERROR!! - all dates should be interpolated.");
    }
    public static void Interpolate_dates(Span<DateTime?> dates)
    {
        if (dates.Length == 0)
            return;
        if (!dates[0].HasValue)
            throw new ArgumentException("First date cannot be null.");
        if (!dates[dates.Length - 1].HasValue)
            throw new ArgumentException("Last date value cannot be null");
        int last_filled_date_index = 0;
        for (int checking_index = 1; checking_index < dates.Length; checking_index++)
        {
            if (dates[checking_index].HasValue)
            {
                if (checking_index != last_filled_date_index + 1)
                {
                    Interpolate(dates, last_filled_date_index, checking_index);
                }
                last_filled_date_index = checking_index;
            }
        }
    }
    private static void Interpolate(Span<DateTime?> dates, int earlier_date_idx, int later_date_idx)
    {
        TimeSpan interval = (dates[later_date_idx].Value - dates[earlier_date_idx].Value) / (later_date_idx - earlier_date_idx);
        for (int index = earlier_date_idx + 1; index < later_date_idx; index++)
        {
            dates[index] = dates[index - 1] + interval;
        }
    }
}

最新更新