Converting the WhenChanged attribute (Generalized-Time) in LDAP to a DateTime in C#

非 Y 不嫁゛ 提交于 2020-01-12 17:15:34

问题


I recently switch from using S.DS namespace (which uses ADSI) to the S.SD.Protocol namespace. The only problem is that ADSI handled the conversion of Generalized-Time to a DateTime for me. Now I'm getting back a value of "20070828085401.0Z" for the WhenChanged attribute. DateTime.Parse() will not convert this so is there another way?


回答1:


The format you are getting is close to the round trip date time pattern ("o") and universal sortable round trip date time pattern ("u") standard date time format strings as described here.

One kludgy solution would be to massage the string you get to fit the pattern and then use the "o" or "u" standard format string with ParseExact.

A better way would be to construct a custom format string that matches the data you are already getting. In the "How Standard Format Strings Work" section of the standard date time format strings page you'll see the full custom formatting strings equivalent to "o" and "u". That should give you a good start.


EDIT: Add code

string format = "yyyyMMddHHmmss.f'Z'";

string target = "20070828085401.0Z";

DateTime d = DateTime.ParseExact(target, format, CultureInfo.InvariantCulture);

In the comments lixonn observes that, using the format string above, ParseExact will not successfully parse a time string like 199412160532-0500.

It also won't parse a number of other valid strings such as times without the trailing 'Zulu' indicator (20070828085401.0); times without a fractional part (20070828085401Z) and times that represent minutes and seconds as a fractional hour (2007082808.90028Z).

The format string can be made slightly more forgiving by replacing the hard-coded 'Z' with the K custom specifier which will accept 'Z', an offset like -0500, and nothing. Whether that additional flexibility is a good thing will depend on your application.

Note that even with the K specifier Lixonn's string won't be parsed successfully since it lacks a fractional part to match the .f component of the format string.




回答2:


You'll have to use DateTime.ParseExact() specifying the exact format. You might have to play with the format a little bit but it would be something like this.

DateTime result;
CultureInfo provider = CultureInfo.InvariantCulture;
string format="yyyyMMddhhmmss.0Z";
result = DateTime.ParseExact(dateString, format, provider);



回答3:


You can use datetime's .strptime().

    import datetime

    # Since 0Z denotes UTC, you can get rid of it and apply the timezone 
    # later if you would like
    time_string = "20070828085401.0Z".split('.')[0]
    time_object = datetime.datetime.strptime(time_string, "%Y%m%d%H%M%S")

time_object should output as datetime.datetime(2007, 8, 28, 8, 54, 1). I believe it will be timezone naive, and equivalent to UTC time.




回答4:


// WIN32 FILETIME is a 64-bit value representing the number of 100-nanosecond intervals since January 1, 1601 (UTC).
// While the unix timestamp represents the seconds since January 1, 1970 (UTC).
private static long Win32FileTimeToUnixTimestamp(long fileTime)
{
    //return fileTime / 10000L - 11644473600000L;
    return DateTimeOffset.FromFileTime(fileTime).ToUnixTimeSeconds();
}

// The GeneralizedTime follows ASN.1 format, something like: 20190903130100.0Z and 20190903160100.0+0300
private static long GeneralizedTimeToUnixTimestamp(string generalizedTime)
{
    var formats = new string[] { "yyyyMMddHHmmss.fZ", "yyyyMMddHHmmss.fzzz" };
    return DateTimeOffset.ParseExact(generalizedTime, formats, System.Globalization.CultureInfo.InvariantCulture).ToUnixTimeSeconds();
}


来源:https://stackoverflow.com/questions/5517695/converting-the-whenchanged-attribute-generalized-time-in-ldap-to-a-datetime-in

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!