c# - Converting date to DOS date -


i having trouble dos date formats. need convert:

 from:        29th june of 2011  to:        16093 

i know 16093 correct result, how can result?


i can convert dos date integer value recognized datetime don't know how reverse process. how conversion dos date datetime:

var number = 16093;  var year = (number >> 9) + 1980; var month = (number & 0x01e0) >> 5; var day = number & 0x1f; var date = new datetime((int)year, (int)month, (int)day); 

this works. need reverse it.

let me teach how fish, , in process fix problem.

  1. what have?

    a datetime .net object represents date/time combination.

    datetime datetime = new datetime(2011, 6, 29); 
  2. what want?

    a dos date/time according specification, 16-bit date component. time component ignored.

  3. what need?

    the day of month, month number, , year since 1980. let's them unsigned integers , ensure in proper range.

    uint day = (uint)datetime.day;              // between 1 , 31 uint month = (uint)datetime.month;          // between 1 , 12 uint years = (uint)(datetime.year - 1980);  // 1980 

    note there 7 bits year, can represent years 1980 2107. outside of range invalid. since years unsigned, can't represent negative values. value 1970 (minus 1980) 4294967286, out of range.

    if (years > 127)     throw new argumentoutofrangeexception("cannot represent year."); 
  4. how combine it?

    we need shift values appropriate spot in resulting integer.

    start all-zero integer. need lower 16 bits convenience we'll use uint here.

    uint dosdatetime = 0; 

    the specification lists bit indices of each value starts. since we're ignoring time part (the 16 least significant bits), need subtract 16 values.

    days start @ bit 16. shift left 16 - 16 positions (i.e. no shifting), , can or bits result.

    dosdatetime |= day << (16 - 16); 

    months start @ bit 21 (minus 16), , years @ bit 25.

    dosdatetime |= minutes << (21 - 16); dosdatetime |= years << (25 - 16); 

    then turn unsigned 16-bit integer. won't overflow.

    ushort result = unchecked((ushort)dosdatetime); 
  5. how put together?

    putting extension method:

    public static class datetimeextensions {     public static ushort todosdatetime(this datetime datetime)     {         uint day = (uint)datetime.day;              // between 1 , 31         uint month = (uint)datetime.month;          // between 1 , 12         uint years = (uint)(datetime.year - 1980);  // 1980          if (years > 127)             throw new argumentoutofrangeexception("cannot represent year.");          uint dosdatetime = 0;         dosdatetime |= day << (16 - 16);         dosdatetime |= month << (21 - 16);         dosdatetime |= years << (25 - 16);          return unchecked((ushort)dosdatetime);     } } 

    of course can write more concise, shows what's going on. , compiler optimize many of constants.

  6. testing it

    you should write unit tests see code works correctly. quick test verifies basic idea:

    static void main(string[] args) {     datetime datetime = new datetime(2011, 6, 29);     ushort dosdatetime = datetime.todosdatetime();     console.writeline(dosdatetime);     // prints: 16093     console.readline(); } 

Comments

Popular posts from this blog

Delphi XE2 Indy10 udp client-server interchange using SendBuffer-ReceiveBuffer -

Qt ActiveX WMI QAxBase::dynamicCallHelper: ItemIndex(int): No such property in -

Enable autocomplete or intellisense in Atom editor for PHP -