CalendarView StartDateTime 总是在 UTC?

CalendarView StartDateTime always in UTC?

我正在使用图形客户端 sdk。使用 startDateTime = 2019-11-20T10:00:00.0000000endDateTime = 2019-11-20T23:00:00.0000000.

调用 CalendarView

在我继续之前,none 的事件是一整天。许多重复出现,所以这就是为什么我不使用事件端点,而是使用 CalendarView 的原因。

我通过设置 prefer 为日历事件设置了时区,outlook.timezone="Eastern Standard Time" -- 没问题。我可以看到东部标准时间的活动开始和结束时间。

但是,事件不正确。我有一个活动开始于美国东部时间 8:00 上午,还有一个活动开始于美国东部时间 6:30 下午。

所以我在想,因为我是 UTC -5startDateTime 被锁定在 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 格式将该时区编码为 startTimeendTime 值:

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"))
};