.NET DirectoryServices 查找方法使用 UTC 还是本地时间?

标签 .net datetime active-directory

According to MSDNUserPrincipleComputerPrinciple 类的查找方法(如 FindByLogonTime 和 FindByBadPasswordAttempt)使用 UTC 时间来筛选结果。但是,测试表明这些方法似乎将本地时间作为输入,而生成的对象使用 UTC 作为其时间属性,并且需要转换为本地时间。

下面的示例似乎正确列出了自本地时间早上 6 点以来在服务器上尝试登录失败的所有用户:

    static void Main()
    {
        var pc = new PrincipalContext(ContextType.Domain, dcServer);
        PrincipalSearchResult<UserPrincipal> uFailed = UserPrincipal.FindByBadPasswordAttempt(pc, DateTime.Now.Date.AddHours(6), MatchType.GreaterThan);
        string s = "";
        foreach (UserPrincipal u in uFailed)
        {
            s += u.SamAccountName + ": " + Convert.ToDateTime(u.LastBadPasswordAttempt).ToLocalTime().ToString() + "\r\n";
        }
        Console.Write(s);
        Console.Read();
    }

请注意 LastBadPasswordAttempt 属性的 UTC 转换,但 FindByBadPasswordAttempt 过滤器中没有转换。

在不知道我是否遗漏了某些内容(可能)或者 MSDN 文档是否错误的情况下,我对将其投入生产感到紧张。该代码在其查询的 DC 上运行,因此应该不存在时区问题。

最佳答案

MSDN 文档是准确的,您只需要注意传入的 DateTime 值的 .Kind 属性即可。

如果您深入研究引用源或反汇编,您会发现您传递的 DateTime 值最终会传递到 DateTime.ToFileTimeUtc ,它确实在其行为中考虑了 Kind

因此,您可以传入一个基于 DateTime.UtcNow 的值,该值的 .KindDateTimeKind.Utc 并且它将起作用,或者您可以像当前正在做的那样传递 DateTime.Now ,它的 .KindDateTimeKind.Local 并且本地时间将在查询之前将其转换为 UTC。只需确保您认识到这是运行代码的计算机的本地时间。如果这有可能与您的用户不在同一时区,那么您可能需要使用 TimeZoneInfo 来获取与其他本地时区等效的 UTC 时间。

如果由于某种原因您决定传入您自己构建的日期,它可能会有 DateTimeKind.Unspecified。对于此特定函数,将被视为 UTC。这并不一定适用于所有日期/时间函数,因此请小心。

此外,在输出中,当您使用的值已经是 DateTime 时,无需调用 Convert.ToDateTime。就此而言,您甚至不需要此代码中的 ToString,除非您计划传递格式说明符。再次强调,如果您的用户可能位于其他时区,请不要使用 .ToLocalTime,而是使用 TimeZoneInfo 上的方法之一进行转换。

另一个微小的优化,如果需要,您可以使用 DateTime.Today 而不是 DateTime.Now.Date。 (除了可读性稍微好一点之外,没有什么区别。)

关于.NET DirectoryServices 查找方法使用 UTC 还是本地时间?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19599870/

相关文章:

c# - 用 C# 绘制一系列位图的最快方法

c# - LINQ to Entities 不支持“TimeOfDay” - 在 Linq 2 SQL 中查找总秒数

c# - 在 C# 中使用 vpn 的事件目录身份验证

c# - 如何获取所有Windows组?

.net - 如何在不处理子控件事件的情况下检查鼠标单击是否在用户控件中?

c# - %在C#中是什么意思?

c# - 打开 "known file type"进入自定义应用程序的运行实例 - .NET

javascript - d3 时间格式返回 null

python - 如何基于相同的日期时间 x 轴同时绘制两个不同的数据框列

c# - 这段异步代码有什么问题?