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

13,095

Solution 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.

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

Solution 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.

Solution 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();
}
Share:
13,095

Related videos on Youtube

Shawn
Author by

Shawn

Updated on June 04, 2022

Comments

  • Shawn
    Shawn over 1 year

    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?

  • lixonn
    lixonn over 5 years
    According to: tools.ietf.org/html/rfc4517#section-3.3.13 this will not pass for: 199412160532-0500
  • Alexandre
    Alexandre almost 5 years
    Question's title and tag let clear that OP is talking about C#, not Python. So, this answer is inadequate here.

Related