Id10T-ERROR
Id10T-ERROR

Reputation: 505

.Net DateTime to DOS Date 32 bit Conversion

I need to convert from a 32 bit Dos Date to a .NET System.DateTime and back again. I'm using the two routines below, however when I convert them back and forth they are out by a number of seconds. Can anyone see why?

public static DateTime ToDateTime(this int dosDateTime)
{
    var date = (dosDateTime & 0xFFFF0000) >> 16;
    var time = (dosDateTime & 0x0000FFFF);

    var year = (date >> 9) + 1980;
    var month = (date & 0x01e0) >> 5;
    var day =  date & 0x1F;
    var hour = time >> 11;
    var minute = (time & 0x07e0) >> 5;
    var second = (time & 0x1F) * 2;

    return new DateTime((int)year, (int)month, (int)day, (int)hour, (int)minute, (int)second);
}

public static int ToDOSDate(this DateTime dateTime)
{
    var years = dateTime.Year - 1980;
    var months = dateTime.Month;
    var days = dateTime.Day;
    var hours = dateTime.Hour;
    var minutes = dateTime.Minute;
    var seconds = dateTime.Second;

    var date = (years << 9) | (months << 5) | days;
    var time = (hours << 11) | (minutes << 5) | (seconds << 1);

    return (date << 16) | time;
}

Upvotes: 4

Views: 1651

Answers (2)

Thomas
Thomas

Reputation: 11

You can see an example

Date value: 2016-01-25 17:33:04

DOS value: 1211730978

Binary: 0100100 0001 11001 10001 100001 00010

But, I found when the second value as 01, the we will convert to DOS value as 0

Upvotes: 1

Chris R. Timmons
Chris R. Timmons

Reputation: 2197

In ToDOSDate, the number of seconds needs to be divided by two before being stored in the time variable. (seconds << 1) left shifts, which multiplies seconds by two. Change that to a right bitwise shift ((seconds >> 1)) to divide by two.

Note that there's no way to avoid losing a second in ToDOSDate when there are an odd number of seconds in dateTime. The right bit shift to divide seconds by two will always drop the least significant bit.

Upvotes: 5

Related Questions