我有一个休息api,它给出了当前日期和当前日期的上个月,它有如下输出:
{
fromDate:2018-03-22T00:00:00+04:30
toDate:2018-04-22T00:00:00+04:30
}
如果我在JavaScript中使用这两个日期,如下所示,我会得到不同的结果:
new Date("2018-03-22T00:00:00+04:30")
console output: Wed Mar 21 2018 23:00:00 GMT+0330 (Iran Standard Time)
new Date("2018-04-22T00:00:00+04:30")
console output: Sun Apr 22 2018 00:00:00 GMT+0430 (Iran Daylight Time)
在c#方面,我使用此代码从服务器获取日期:
var toDate = DateTime.Now.Date;
DateTime fromDate = toDate.AddMonths(-1);
如何克服这个没有不同日期的问题?
答案 0 :(得分:1)
由于2018-03-22
上的daylight saving time in Iran开始,当时钟接近00:00:00
时,它会提前一小时到01:00:00
。如果在这段时间内仔细观察时钟,人们会看到它如下:
...
2018-03-21 23:59:58
2018-03-21 23:59:59
2018-03-22 01:00:00
2018-03-21 01:00:01
...
换句话说,当天在当天时区中的值00:00:00
到00:59:59
不存在。
由于您在fromDate
中提供了此类不存在的值,并且您的本地计算机的时区设置为伊朗,因此JavaScript会将其转换为有效的时间点,如下所示:
2018-03-22T00:00:00+04:30 source input value
2018-03-21T19:30:00+00:00 converted to UTC
2018-03-21T23:00:00+03:30 converted to a valid local time
如果您希望当天开始正确的开始,那么fromDate
必须是2018-03-22T01:00:00+04:30
。
要在C#中在服务器端正确计算,您需要使用TimeZoneInfo
API。请考虑以下帮助方法:
static DateTimeOffset GetStartOfDay(DateTime dt, TimeZoneInfo tz)
{
// Work in the time zone provided
if (dt.Kind != DateTimeKind.Unspecified)
{
dt = TimeZoneInfo.ConvertTime(dt, tz);
}
// Start with assuming midnight
var d = dt.Date;
// Check for the time being invalid and handle if so
if (tz.IsInvalidTime(d))
{
// the gap is *usually* 1hr, but not always, so calculate it
var gap = tz.GetUtcOffset(dt.AddDays(1)) - tz.GetUtcOffset(dt.AddDays(-1));
// advance forward by the amount of the gap
d = d.Add(gap);
}
// Also check for the time being ambiguous, such as in a fall-back transition.
// We want the *first* occurrence, which will have a *larger* offset
var offset = tz.IsAmbiguousTime(d)
? tz.GetAmbiguousTimeOffsets(d).OrderByDescending(x => x).First()
: tz.GetUtcOffset(d);
// Now we know when the date starts precisely
return new DateTimeOffset(d, offset);
}
通过声明,现在您可以轻松获得API的准确值:
var tz = TimeZoneInfo.FindSystemTimeZoneById("Iran Standard Time");
var date = new DateTime(2014, 3, 22); // or DateTime.UtcNow for the current date
DateTimeOffset fromDate = GetStartOfDay(date, tz);
DateTimeOffset toDate = GetStartOfDay(fromDate.AddDays(1).Date, tz);
当然,这假设伊朗是您希望从API发出的正确时区。如果您为更广泛的受众群体提供服务,则可能需要相应地调整时区。