CalendarView StartDateTime 总是在 UTC?
CalendarView StartDateTime always in UTC?
我正在使用图形客户端 sdk。使用 startDateTime
= 2019-11-20T10:00:00.0000000
和 endDateTime
= 2019-11-20T23:00:00.0000000
.
调用 CalendarView
在我继续之前,none 的事件是一整天。许多重复出现,所以这就是为什么我不使用事件端点,而是使用 CalendarView 的原因。
我通过设置 prefer 为日历事件设置了时区,outlook.timezone="Eastern Standard Time"
-- 没问题。我可以看到东部标准时间的活动开始和结束时间。
但是,事件不正确。我有一个活动开始于美国东部时间 8:00 上午,还有一个活动开始于美国东部时间 6:30 下午。
8:00 上午会议显示——什么时候应该而不是,因为我的开始标准是上午 10 点。没什么大不了的,但可能因为它在上午 10 点结束。
6:30 下午的会议没有显示,应该 因为我的结束时间是 11:00 下午。这个是一个问题。
如果我将 6:30 会议移至 6:00,它会显示在 collection.
所以我在想,因为我是 UTC -5
,startDateTime
被锁定在 UTC 时间。它不按 header 时区。我知道上面提到的 header 时区是有效的,因为如果我设置了 header,我的事件的实际 start/end 将显示东部时间,如果没有设置,则显示 UTC。
我找不到任何允许我强制日历视图的东西?$select=subject,start, end&startDateTime=2019-11-20T10:00:00.0000000&endDateTime=2019-11-20T23:30:00.0000000
使用我的本地时间。
我在 Graph Explorer 中尝试了这个,发现我可以在时间后面加上 -5
,它似乎可以工作。我仍然得到 8:00 上午事件,但我也得到我的 6:30 事件。我不想在我的代码中这样做,因为那样我会强迫其他用户使用我的时区。
有谁知道可以更改什么设置来强制 CalendarView 使用本地时间作为参数?抱歉,我是图形客户端的新手,所以我可能没有使用正确的词汇。
代码:
GraphServiceClient graphClient = new GraphServiceClient(AuthProvider);
DateTime d = DateTime.Now.ToLocalTime();
DateTime.SpecifyKind(d, DateTimeKind.Unspecified).ToString("o");
string MicrosoftDateTimeFormat = "yyyy'-'MM'-'dd'T'HH':'mm':'ss'.'fffffff";
var start = d.ToString(MicrosoftDateTimeFormat);
var end = d.ToString("yyyy'-'MM'-'dd'T'23:59:59.0"); //"2019-07-24T23:00:00.0";//
start = "2019-11-20T10:00:00.0000000"; //for debug only
end = "2019-11-20T23:00:00.0000000"; //for debug only
List<Option> options = new List<Option>
{
new QueryOption("startDateTime", start),
new QueryOption("endDateTime", end),
new QueryOption("orderby", "start/dateTime")
};
var events = await graphClient.Me.CalendarView
.Request(options)
.Header("Prefer", "outlook.timezone=\"" + TimeZoneInfo.Local.Id + "\"")
.Select(e => new
{
e.Subject,
e.Body,
e.BodyPreview,
e.Organizer,
e.Attendees,
e.Start,
e.End,
e.Location
})
.GetAsync();
好的,我让它工作了。 This answer was very helpful。早上入住的时候在相关问题里出现了答案
正如他们所说,在罗马时...所以就我而言,在 UTC 时就像 UTC 人一样。所以我只是将所有内容都保存在 UTC 时间。我确实得出结论,CalendarView 请求的日期时间(开始和结束)是 UTC 时间,显然无法更改它。所以我只是将我当前的时间戳记为 UTC。当我在 UI 中显示事件 start/end 次时,我只将时间更改为本地时间。白手起家!哈哈
注意:它仍然保留我早上 8 点的会议,但同样,这不是杀手。我希望我知道为什么,但那是另一天。
如果这可以帮助像我这样的另一个 kinda-newbie 这是我的最终代码段:
GraphServiceClient graphClient = new GraphServiceClient(AuthProvider);
DateTime d = DateTime.UtcNow; //DateTime.Now.ToLocalTime();
//d = DateTime.Parse("11/20/2019 08:14:34 PM"); //for debug only
DateTime.SpecifyKind(d, DateTimeKind.Unspecified).ToString("o");
string MicrosoftDateTimeFormat = "yyyy'-'MM'-'dd'T'HH':'mm':'ss'.'fffffff";
var start = d.ToString(MicrosoftDateTimeFormat);
var end = d.ToString("yyyy'-'MM'-'dd'T'23:59:59.9"); //"2019-07-24T23:00:00.0";//
//start = "2019-11-20T10:00:00.0000000"; //for debug only
//end = "2019-11-20T23:59:59.0000000"; //for debug only
//var link = $"https://graph.microsoft.com/v1.0/me/calendarview?startdatetime={start}&enddatetime={end}&orderby=start/dateTime"; //not used. was previously used for http call; before moving to sdk.
List<Option> options = new List<Option>
{
new QueryOption("startDateTime", start),
new QueryOption("endDateTime", end),
new QueryOption("orderby", "start/dateTime")
};
var events = await graphClient.Me.CalendarView
.Request(options)
//.Header("Prefer", "outlook.timezone=\"" + TimeZoneInfo.Local.Id + "\"")
.Select(e => new
{
e.Subject,
e.Body,
e.BodyPreview,
e.Organizer,
e.Attendees,
e.Start,
e.End,
e.Location
})
.GetAsync();
prefer: outlook.timezone="Eastern Standard Time"
header 仅影响 API 响应。您的 header 将确保结果以 EST 返回,但时区转换发生在检索结果之后。在后端,每个事件都存储为 UTC -0
.
为了请求给定时区范围内的事件,需要使用 ISO 8601 格式将该时区编码为 startTime
和 endTime
值:
YYYY-MM-DDThh:mm:ss±hh:mm
或更简单地说:
{date}T{time}±{offset}
因此,为了将 2019-11-20T10:00:00.0000000
中的 startDateTime
转换为复活节标准,需要 2019-11-20T10:00:00-5
。
在 C# 中,DateTimeOffset
object 可以使用 .ToString("O")
:
为您生成正确的格式
var tzOffset = new TimeSpan(-5, 0, 0);
var dateTime = new DateTimeOffset(2019, 11, 20, 10, 0, 0, tzOffset);
List<Option> options = new List<Option>
{
new QueryOption("startDateTime", dateTime.ToString("O")),
new QueryOption("endDateTime", dateTime.AddHours(24).ToString("O"))
};
您还可以使用 TimeZoneInfo
class 查找给定时区的正确 UTC 偏移量。这通常是个好主意,因为时区的变化比您想象的要频繁得多:
TimeSpan tzOffset = TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time").BaseUtcOffset;
DateTimeOffset dateTime = new DateTimeOffset(2019, 11, 20, 10, 0, 0, tzOffset);
List<Option> options = new List<Option>
{
new QueryOption("startDateTime", dateTime.ToString("O")),
new QueryOption("endDateTime", dateTime.AddHours(24).ToString("O"))
};
我正在使用图形客户端 sdk。使用 startDateTime
= 2019-11-20T10:00:00.0000000
和 endDateTime
= 2019-11-20T23:00:00.0000000
.
在我继续之前,none 的事件是一整天。许多重复出现,所以这就是为什么我不使用事件端点,而是使用 CalendarView 的原因。
我通过设置 prefer 为日历事件设置了时区,outlook.timezone="Eastern Standard Time"
-- 没问题。我可以看到东部标准时间的活动开始和结束时间。
但是,事件不正确。我有一个活动开始于美国东部时间 8:00 上午,还有一个活动开始于美国东部时间 6:30 下午。
8:00 上午会议显示——什么时候应该而不是,因为我的开始标准是上午 10 点。没什么大不了的,但可能因为它在上午 10 点结束。
6:30 下午的会议没有显示,应该 因为我的结束时间是 11:00 下午。这个是一个问题。
如果我将 6:30 会议移至 6:00,它会显示在 collection.
所以我在想,因为我是 UTC -5
,startDateTime
被锁定在 UTC 时间。它不按 header 时区。我知道上面提到的 header 时区是有效的,因为如果我设置了 header,我的事件的实际 start/end 将显示东部时间,如果没有设置,则显示 UTC。
我找不到任何允许我强制日历视图的东西?$select=subject,start, end&startDateTime=2019-11-20T10:00:00.0000000&endDateTime=2019-11-20T23:30:00.0000000
使用我的本地时间。
我在 Graph Explorer 中尝试了这个,发现我可以在时间后面加上 -5
,它似乎可以工作。我仍然得到 8:00 上午事件,但我也得到我的 6:30 事件。我不想在我的代码中这样做,因为那样我会强迫其他用户使用我的时区。
有谁知道可以更改什么设置来强制 CalendarView 使用本地时间作为参数?抱歉,我是图形客户端的新手,所以我可能没有使用正确的词汇。
代码:
GraphServiceClient graphClient = new GraphServiceClient(AuthProvider);
DateTime d = DateTime.Now.ToLocalTime();
DateTime.SpecifyKind(d, DateTimeKind.Unspecified).ToString("o");
string MicrosoftDateTimeFormat = "yyyy'-'MM'-'dd'T'HH':'mm':'ss'.'fffffff";
var start = d.ToString(MicrosoftDateTimeFormat);
var end = d.ToString("yyyy'-'MM'-'dd'T'23:59:59.0"); //"2019-07-24T23:00:00.0";//
start = "2019-11-20T10:00:00.0000000"; //for debug only
end = "2019-11-20T23:00:00.0000000"; //for debug only
List<Option> options = new List<Option>
{
new QueryOption("startDateTime", start),
new QueryOption("endDateTime", end),
new QueryOption("orderby", "start/dateTime")
};
var events = await graphClient.Me.CalendarView
.Request(options)
.Header("Prefer", "outlook.timezone=\"" + TimeZoneInfo.Local.Id + "\"")
.Select(e => new
{
e.Subject,
e.Body,
e.BodyPreview,
e.Organizer,
e.Attendees,
e.Start,
e.End,
e.Location
})
.GetAsync();
好的,我让它工作了。 This answer was very helpful。早上入住的时候在相关问题里出现了答案
正如他们所说,在罗马时...所以就我而言,在 UTC 时就像 UTC 人一样。所以我只是将所有内容都保存在 UTC 时间。我确实得出结论,CalendarView 请求的日期时间(开始和结束)是 UTC 时间,显然无法更改它。所以我只是将我当前的时间戳记为 UTC。当我在 UI 中显示事件 start/end 次时,我只将时间更改为本地时间。白手起家!哈哈
注意:它仍然保留我早上 8 点的会议,但同样,这不是杀手。我希望我知道为什么,但那是另一天。
如果这可以帮助像我这样的另一个 kinda-newbie 这是我的最终代码段:
GraphServiceClient graphClient = new GraphServiceClient(AuthProvider);
DateTime d = DateTime.UtcNow; //DateTime.Now.ToLocalTime();
//d = DateTime.Parse("11/20/2019 08:14:34 PM"); //for debug only
DateTime.SpecifyKind(d, DateTimeKind.Unspecified).ToString("o");
string MicrosoftDateTimeFormat = "yyyy'-'MM'-'dd'T'HH':'mm':'ss'.'fffffff";
var start = d.ToString(MicrosoftDateTimeFormat);
var end = d.ToString("yyyy'-'MM'-'dd'T'23:59:59.9"); //"2019-07-24T23:00:00.0";//
//start = "2019-11-20T10:00:00.0000000"; //for debug only
//end = "2019-11-20T23:59:59.0000000"; //for debug only
//var link = $"https://graph.microsoft.com/v1.0/me/calendarview?startdatetime={start}&enddatetime={end}&orderby=start/dateTime"; //not used. was previously used for http call; before moving to sdk.
List<Option> options = new List<Option>
{
new QueryOption("startDateTime", start),
new QueryOption("endDateTime", end),
new QueryOption("orderby", "start/dateTime")
};
var events = await graphClient.Me.CalendarView
.Request(options)
//.Header("Prefer", "outlook.timezone=\"" + TimeZoneInfo.Local.Id + "\"")
.Select(e => new
{
e.Subject,
e.Body,
e.BodyPreview,
e.Organizer,
e.Attendees,
e.Start,
e.End,
e.Location
})
.GetAsync();
prefer: outlook.timezone="Eastern Standard Time"
header 仅影响 API 响应。您的 header 将确保结果以 EST 返回,但时区转换发生在检索结果之后。在后端,每个事件都存储为 UTC -0
.
为了请求给定时区范围内的事件,需要使用 ISO 8601 格式将该时区编码为 startTime
和 endTime
值:
YYYY-MM-DDThh:mm:ss±hh:mm
或更简单地说:
{date}T{time}±{offset}
因此,为了将 2019-11-20T10:00:00.0000000
中的 startDateTime
转换为复活节标准,需要 2019-11-20T10:00:00-5
。
在 C# 中,DateTimeOffset
object 可以使用 .ToString("O")
:
var tzOffset = new TimeSpan(-5, 0, 0);
var dateTime = new DateTimeOffset(2019, 11, 20, 10, 0, 0, tzOffset);
List<Option> options = new List<Option>
{
new QueryOption("startDateTime", dateTime.ToString("O")),
new QueryOption("endDateTime", dateTime.AddHours(24).ToString("O"))
};
您还可以使用 TimeZoneInfo
class 查找给定时区的正确 UTC 偏移量。这通常是个好主意,因为时区的变化比您想象的要频繁得多:
TimeSpan tzOffset = TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time").BaseUtcOffset;
DateTimeOffset dateTime = new DateTimeOffset(2019, 11, 20, 10, 0, 0, tzOffset);
List<Option> options = new List<Option>
{
new QueryOption("startDateTime", dateTime.ToString("O")),
new QueryOption("endDateTime", dateTime.AddHours(24).ToString("O"))
};