转换负时代时间的公式是什么?

时间:2016-05-25 19:17:18

标签: c# unix-timestamp

我有负时代的问题。我有一个第三方程序,它生成了我的纪元时间。我正在使用该程序为我生成纪元时间,我保持所有人的日期和时间相同,而只更改年份以获得下面的纪元时间进行测试。所有yyyy的日期和时间应该是01/01 / yyyy 12:00:00 AM。

这就是我所拥有的:

import matplotlib.pyplot as plt
data = [1] * 10 + [2] * 20 + [3] * 30
plt.hist(data, bins=[1, 2, 3, 4])

输出结果为:

 var epoch = new DateTime(1904, 1, 1, 0, 0, 0, DateTimeKind.Utc);
        var ofset = 6*60*60; // 6hr different

        Console.WriteLine("1900: " + epoch.AddSeconds(-126122400 - ofset)); // 1900
        Console.WriteLine("1904: " + epoch.AddSeconds(21600 - ofset)); // 1904
        Console.WriteLine("1905: " + epoch.AddSeconds(31644000 - ofset)); // 1905
        Console.WriteLine("1970: " + epoch.AddSeconds(2082866400 - ofset)); // 1970
        Console.WriteLine("1971: " + epoch.AddSeconds(2114402400 - ofset)); // 1971
        Console.WriteLine("1972: " + epoch.AddSeconds(2145938400 - ofset)); // 1972
        Console.WriteLine("1973: " + epoch.AddSeconds(-2117406496 - ofset)); // 1973
        Console.WriteLine("1974: " + epoch.AddSeconds(-2085870496 - ofset)); // 1974
        Console.WriteLine("2016: " + epoch.AddSeconds(-760494496 - ofset)); // 2016

正如你所看到的,从第1973行开始(纪元时间为负),日期,年份和时间都是错误的。我该怎么做才能得到正确的日期,年份和时间?

更新:

对于日期设置为10:11:45.654 AM 5/26/2016的原始数据,这就是我在数据库中看到的内容:

1900: 1/1/1900 12:00:00 AM
1904: 1/1/1904 12:00:00 AM
1905: 1/1/1905 12:00:00 AM
1970: 1/1/1970 12:00:00 AM
1971: 1/1/1971 12:00:00 AM
1972: 1/1/1972 12:00:00 AM
1973: 11/24/1836 5:31:44 PM
1974: 11/24/1837 5:31:44 PM
2016: 11/24/1879 5:31:44 PM

1 个答案:

答案 0 :(得分:1)

我想我发现了这个问题:整数溢出。我不知道发生了什么,但这就是问题所在。

考虑一下,从1904年1月1日到1973年1月1日的秒数为2,177,539,200。整数的最大值为2,147,483,648。所以1973年的偏移值大于整数。

如果您取数字2,177,539,200并将其转换为int,则得到的值为-2,117,428,096。如果你将这个数字插入日期计算中,你会得到1836/11/24 17:31:44。这是测试代码:

private static void Main(string[] args)
{
    var epoch = new DateTime(1904, 01, 01, 0, 0, 0, DateTimeKind.Utc);
    var offset = TimeSpan.FromHours(6);

    // How many seconds between 1904/01/01 and 1973/01/01?
    var timestamp1973 = (new DateTime(1973, 01, 01, 0, 0, 0, DateTimeKind.Local) - epoch).TotalSeconds;
    Console.WriteLine("1973 timestamp = {0:N0}", timestamp1973);
    Console.WriteLine("Verify calculation: {0}", epoch.AddSeconds(timestamp1973));

    // How many seconds is that different from int.MaxValue?
    var overflow = timestamp1973 - int.MaxValue;
    Console.WriteLine("Overflow = {0:N0}", overflow);

    // So take int.MaxValue and add the overflow
    var wrongTimeStamp = int.MaxValue;
    wrongTimeStamp += (int) overflow;
    Console.WriteLine("wrong time stamp = {0:N0}", wrongTimeStamp);

    // And the calculation with that value is:
    Console.WriteLine("Wrong date = {0}", epoch.AddSeconds(wrongTimeStamp));
    Console.ReadLine();
}

输出:

1973 timestamp = 2,177,539,200
Verify calculation: 1973-01-01 00:00:00
Overflow = 30,055,553
wrong time stamp = -2,117,428,096
Wrong date = 1836-11-24 17:31:44

因此,要么第三方程序错误地在数据中发送带符号的32位整数,要么程序中的某些内容错误地将LabView创建的带符号64位数字转换为带符号的32位数字。 某处有人将64位转换为32位,事情就这样发生了。

评论后

如果数据确实是有符号整数,那么看起来您唯一的选择就是将其视为无符号整数。这将阻止你在1904年之前显示日期,但它会给你到2040年2月的范围。为此:

int signedValue = ReadFromDatabase();
uint unsignedValue = (uint)signedValue;
var theDate = epoch.AddSeconds(unsignedValue);