1

I am using a wrapper of a C++ api which isn't really documented. Some of the exposed methods require fields (from and to) which are of type uint. The fields are actually datefrom and dateto, but the types aren't as such. I have tried different approaches, including converting datetime to DOS unsigned int representation

 public  ushort ToDosDateTime( DateTime dateTime)
    {
        uint day = (uint)dateTime.Day;              // Between 1 and 31
        uint month = (uint)dateTime.Month;          // Between 1 and 12
        uint years = (uint)(dateTime.Year - 1980);  // From 1980

        if (years > 127)
            throw new ArgumentOutOfRangeException("Cannot represent the year.");

        uint dosDateTime = 0;
        dosDateTime |= day << (16 - 16);
        dosDateTime |= month << (21 - 16);
        dosDateTime |= years << (25 - 16);

        return unchecked((ushort)dosDateTime);
    }

, but still the api function call returned nothing if not an error. , I also tried the plain representation as : 20160101 which made sense but didn't succeed. Is there a known way of representing dates and times as unsigned integers?

Cogent
  • 404
  • 7
  • 16
  • Can you read a known date out of the API and then analyse the value returned (trying to convert it from [`Ticks`](https://msdn.microsoft.com/en-us/library/system.datetime.ticks(v=vs.110).aspx) etc.) to see what returns you the correct value. – ChrisF Feb 10 '16 at 12:01

2 Answers2

2

I made this function which I tested on dates i was getting from the API as uint.

    public DateTime FromCtmToDateTime(uint dateTime)
    {
        DateTime startTime = new DateTime(1970, 1, 1, 0, 0, 0, 0);
        return startTime.AddSeconds(Convert.ToDouble( dateTime));
    }

@ChrisF : I tried this and it worked. This is indeed C time, which means the start off date is midnight 1970 - 1 -1; The uint represents the number of seconds since that date.

I successfully got meaningful dates by processing the output dates which i got from working functions, and used the following to convert the otherway around:

   public  UInt32 ToDosDateTime( DateTime dateTime)
    {
        DateTime startTime = new DateTime(1970, 1, 1, 0, 0, 0, 0);
        TimeSpan currTime = dateTime - startTime;
        UInt32 time_t = Convert.ToUInt32(Math.Abs(currTime.TotalSeconds));
        return time_t;
    }
Cogent
  • 404
  • 7
  • 16
  • Eh, I guess you mean that as comment on my answer? The date format is used on UNIX and the code you wrote is actually the same as the answer I linked to: http://stackoverflow.com/a/2883645/993547. – Patrick Hofman Feb 10 '16 at 12:35
  • Yes my aplogies... I even got in contact with the guy who wrote the wrapper and confirmed your comments. Thank you. – Cogent Feb 10 '16 at 12:45
1

.NET itself stores DateTime as an unsigned long, representing the ticks from 1/1/0001. From the reference source:

// The data is stored as an unsigned 64-bit integeter
//   Bits 01-62: The value of 100-nanosecond ticks where 0 represents 1/1/0001 12:00am, up until the value
//               12/31/9999 23:59:59.9999999
//   Bits 63-64: A four-state value that describes the DateTimeKind value of the date time, with a 2nd
//               value for the rare case where the date time is local, but is in an overlapped daylight
//               savings time hour and it is in daylight savings time. This allows distinction of these
//               otherwise ambiguous local times and prevents data loss when round tripping from Local to
//               UTC time.
private UInt64 dateData;

Also, UNIX stores the time a little different. According to Wikipedia:

defined as the number of seconds that have elapsed since 00:00:00 Coordinated Universal Time (UTC), Thursday, 1 January 1970

So that can be expressed in an unsigned integer quite easily. You can convert that to a DateTime with not too much code.

Community
  • 1
  • 1
Patrick Hofman
  • 153,850
  • 22
  • 249
  • 325
  • 1
    Yes this indeed seems like what is needed. According to the native c++ api: { ReportGroupRequest req={"some_group"}; req.from=(time(NULL)/86400)*86400; req.to =req.from+86400; So the start offdate should be 1-1-1970. I am getting somewhere now. – Cogent Feb 10 '16 at 11:53