简体   繁体   中英

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

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?

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.

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

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM