日历视图开始日期时间总是采用 UTC?



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

在我进一步讨论之前,没有一个事件是一整天。许多重复出现,所以这就是为什么我不使用事件端点,而是使用日历视图。

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

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

  • 上午 8:00 的会议显示 - 不应该,因为我的开始标准是上午 10 点。没什么大不了的,但可能是因为它在上午 10 点结束。

  • 下午 6:30 的会议没有显示,它应该显示,因为我的结束时间是晚上 11:00。这是一个问题。

  • 如果我将 6:30 会议提前到 6:00,它会显示在集合中。

所以我在想,因为我UTC -5startDateTime被锁定在UTC时间。 它不按标题时区。 我知道上面提到的标题时区正在工作,因为如果我设置了标题,我的事件的实际开始/结束将显示东部,如果我没有设置,则显示 UTC。

我找不到任何允许我强制使用日历视图的内容?$select=subject,start, end&startDateTime=2019-11-20T10:00:00.0000000&endDateTime=2019-11-20T23:30:00.0000000使用我的当地时间。

我在图形资源管理器中玩了一下,发现我可以在时间之后放-5,它似乎有效。我仍然得到上午 8:00 的活动,但我也得到我的 6:30 事件。 我不想在我的代码中这样做,因为那样我会强迫其他用户使用我的时区。

有谁知道可以更改什么设置来强制日历视图使用本地时间作为参数? 很抱歉,我是图形客户端的新手,所以我可能没有使用正确的词汇。

法典:


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();

prefer: outlook.timezone="Eastern Standard Time"标头仅影响 API 响应。您的标头将确保以 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 对象可以使用.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 类查找给定时区的正确 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"))
};

好的,所以我让它工作了。 这个答案非常有帮助。答案出现在我今天早上入住的相关问题中。

正如他们所说,在罗马时...所以就我而言,当在 UTC 中像 UTC'ans 一样做。 所以我只是将所有内容都保持在 UTC 时间。 我确实得出结论,CalendarView 请求的日期时间(开始和结束(是 UTC 时间,显然无法更改它。 所以我只是在 UTC 中保留我当前的时间戳。 我仅在UI中显示事件开始/结束时间时将时间更改为本地时间。 无中生有!哈哈。

注意:它仍然保留了我早上8点的会议,但同样,这不是杀手锏。我希望我能知道为什么,但那是另一天。

如果这可以帮助像我这样的新手,这是我的最后一个代码段:

 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();

最新更新