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.
what have?
a
datetime
.net object represents date/time combination.datetime datetime = new datetime(2011, 6, 29);
what want?
a dos date/time according specification, 16-bit date component. time component ignored.
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.");
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);
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.
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
Post a Comment