你处理日期的方式有一个根本问题,如果我把它归结为一件事,我想问题是
ToUniversalTime()
不是你想的那样。
什么
时间()
是的,仅仅是给
UTC
在不同时区定义的时间。例如,假设我的本地时间是
UTC-7
是的。所以如果我定义
DateTime
对象
未指定
DateTimeKind
并将值设置为,比如,
2017/6/1 9:00:00
,也就是说,在那个时候
协调世界时
时间就是
2017/6/1 16:00:00
当时,和
时间()
会给你一个
日期时间
具有该值的对象。
让我把你的
ToUTCString()
方法,并向您展示它的问题。它正在返回一个
long
价值而不是
string
现在,我把第一行代码分成两行。
public static long ToUTC(this DateTime _input)
{
var utcTime = _input.ToUniversalTime();
var totalSeconds = utcTime.Subtract(UnixEpoch).TotalSeconds;
return Convert.ToInt64(totalSeconds);
}
注意到你的
Extensions
班级
UnixEpoch
对象的
日期时间类型
设置为
协调世界时
是的。我把日期改成
2017/6/1 8:00:00
为了便于理解。
private static readonly DateTime UnixEpoch = new DateTime(2017, 6, 1, 8, 0, 0, DateTimeKind.Utc);
public static DateTime ToDateTime(this Int64 _input)
{
return UnixEpoch.AddSeconds(_input);
}
现在我们用
日期时间
对象
日期时间类型
设置为
协调世界时
是的。
// dateObj will have time 2017/6/1 9:00:00 _in UTC_.
var dateObj = new DateTime(2017, 6, 1, 9, 0, 0, DateTimeKind.Utc);
// This method converts to UTC, but it's already in UTC, so no actual conversion takes place.
// Then subtracts UnixEpoch from it, which is also in UTC.
long dateInLong = dateObj.ToUTC();
// The difference is one hour, so dateInLong will be 3600.
Console.WriteLine(dateInLong);
// This method adds the above difference to UnixEpoch, and displays the time.
Console.WriteLine(dateInLong.ToDateTime());
现在,这里,一切都在
协调世界时
您应该看到预期的输出,如下所示:
3600个
2017年6月1日09:00:00
到目前为止一切都很好。
现在改变一下,让我们
dateObj
到本地而不是
协调世界时
,正如您在示例中所做的那样。
// Notice that the object is in local time now.
var dateObj = new DateTime(2017, 6, 1, 9, 0, 0);
long dateInLong = dateObj.ToUTC();
Console.WriteLine(dateInLong);
Console.WriteLine(dateInLong.ToDateTime());
现在,上面
日期对象
会有时间的
9:00:00
我是说,
但在我的本地时间
.我的实际位置是
协调世界时-7
所以请注意这意味着
9AM
对我来说当地时间是
4PM
联合技术公司。但请注意我们没有改变
Unixepoch公司
对象,它仍在
协调世界时
时间被设定为
8AM UTC
在里面。因此,
dateInLong
将
28,800
(8小时x 60分钟x 60秒)。所以当你
ToDateTime()
方法被调用,它添加
28,000
秒到
UTC上午8点
时间,作为
日期时间
对象,现在是
4PM UTC
是的。
28800个
2017年6月1日16:00:00
这就是为什么取决于你设定的时间
日期对象
到,你的输出
变化
时间如你所说。
解决方案
你需要决定使用哪个时区,并坚持这一点。一个办法是把所有的
协调世界时
转换并将所有时间设置为本地时间。
public static class Extensions
{
// NOT set to UTC
private static readonly DateTime UnixEpoch = new DateTime(2017, 6, 1, 8, 0, 0);
public static DateTime ToDateTime(this Int64 _input)
{
return UnixEpoch.AddSeconds(_input);
}
public static long ToUTC(this DateTime _input)
{
// NOT converted to UTC. So... change variable names accordingly.
var utcTime = _input;
var totalSeconds = utcTime.Subtract(UnixEpoch).TotalSeconds;
return Convert.ToInt64(totalSeconds);
}
}
class Program
{
static void Main(string[] args)
{
// Notice that the object is in local time and NOT UTC.
var dateObj = new DateTime(2017, 6, 1, 9, 0, 0);
long dateInLong = dateObj.ToUTC();
Console.WriteLine(dateInLong);
Console.WriteLine(dateInLong.ToDateTime());
Console.ReadLine();
}
}
另一个选项,将所有内容都设置为UTC,但是您必须确保
日期时间
调用的对象
ToUTC()
在UTC中定义,而不是本地。
所以:
private static readonly DateTime UnixEpoch = new DateTime(2017, 6, 1, 8, 0, 0, DateTimeKind.Utc);
以及
var utcTime = _input.ToUniversalTime();
最后
var dateObj = new DateTime(2017, 6, 1, 9, 0, 0, DateTimeKind.Utc);
但是…
我看到你的代码有一个更大的问题,看看第二个代码片段。在
ForecastIORequest()
构造器,作为一个
一串
是的。在我看来,这不是一个理想的解决方案。因为当你发现困难的时候,取决于调用对象创建的时区,你的时间差将会,嗯,不同。你不可能知道。
我宁愿储存
日期时间
按原样创建对象,读取它并在需要时计算差异,同时考虑时区。
希望这有帮助。