I have two functions, one to convert a datetime to a hex word, and one to convert a word to a datetime. I was just wondering if there was a more efficient way to convert back and forth.
/// <summary>
/// Converts a date time to a hexadecimal word
/// </summary>
/// <param name="date">the date time</param>
/// <returns>returns the Hex value of the date</returns>
private int convertToWordFromDate(DateTime date)
{
int m, d, y;
int month = date.Month;
int day = date.Day;
int year = int.Parse(date.Year.ToString().Substring(2, 2));
int yearShift = 9;
int monthShift = 5;
int word;
y = year << yearShift;
m = month << monthShift;
d = day;
if (year == 0)
word = m + d + (y * 100);
if (year < 10)
word = (m + d + y) * 16;
else
word = m + d + y;
return word;
}
/// <summary>
/// Converts a hexadecimal word to a valid dateTime
/// </summary>
/// <param name="word">the word</param>
/// <returns>the date time</returns>
private DateTime convertToDateFromWord(int word)
{
int month, day, year;
int monthMask = 0x01E0;
int dayMask = 0x001F;
int yearMask = 0xFE00;
int monthShift = 32;
int yearShift = 512;
DateTime date = new DateTime();
try
{
year = (word & yearMask) / yearShift;
month = (word & monthMask) / monthShift;
day = (word & dayMask);
if (year >= 80 && year <= 99)
year += 1900;
else if (year >= 0 && year <= 79)
year += 2000;
else if (year < 0 || month <= 0 || day <= 0)
{
year = 1;
month = 1;
day = 1;
}
else
{
year = 1;
month = 1;
day = 1;
}
date = new DateTime(year, month, day);
}
catch
{
date = new DateTime(1, 1, 1);
}
return date;
}
-
\$\begingroup\$ Out of curiousity, why are you doing this? And you should really see about getting the shifts and masks defined at the class level, and ideally, have one depend on the other (so changes are automatically propogated). \$\endgroup\$Clockwork-Muse– Clockwork-Muse2011年11月18日 17:15:41 +00:00Commented Nov 18, 2011 at 17:15
1 Answer 1
I note that your functions are not doing what they say they're doing. For example, you don't convert a date to a hexadecimal word, you convert to an integer value, a value that also happens to disregard the century and the time component entirely. In getting the date back, you also perform some business rules against the date, by treating certain years as last century, other years as current century.
What I would expect when seeing these functions is that I would certainly get the same date I passed into one function as the output from the other. That is not necessarily going to be the case.
You also have issues with a blanket catch
that swallows any exception. If you are going to catch an exception, be specific and catch what you truly can handle, something you might expect. Work towards eliminating those exceptions entirely, so instead of catching them, you are preventing them by validating against their causes beforehand, if possible.
You have an if/else chain where an else if
and else
have the exact some code in their code blocks. Eliminate the redundancy.
There are issues with shifts and masks not being consistent, in terms of where they are defined and the methodology being used. If you change something in one place, you have to change it in another. More than that, you have to change it in a different way.
To be blunt, it's basically not clear what the code is doing at an initial glance, nor is it necessarily clear why it is doing it.
I don't know what your business case is, but if I was writing a class to convert a date to a "hexadecimal word" and then back again, I would probably expect to write something that takes a date and returns a string, and then takes a string and returns a date. The quick, not completely tested version might be something simple like this
public class DateConverter
{
public string ConvertToHexString(DateTime date)
{
return date.Ticks.ToString("X2");
}
public DateTime ConvertFromHexString(string hexInput)
{
long ticks = Convert.ToInt64(hexInput, 16);
return new DateTime(ticks);
}
}
Which you could validate with
DateTime originalDate = new DateTime(1955, 11, 11, 22, 4, 0);
DateConverter converter = new DateConverter();
string hexValue = converter.ConvertToHexString(originalDate);
DateTime returnedDate = converter.ConvertFromHexString(hexValue);
Debug.Assert(originalDate == returnedDate);