I have the following 5 bytes in the attached image and need to extract the datetime from it. I understand I'll need to bit shift and maybe use bitwise and's, but fail to get the correct information from the bytes.
Asked
Active
Viewed 262 times
2
-
1What code are you using at the moment? – Matthew Watson Dec 17 '15 at 21:56
-
Can you explain more about how the two `Y` are calculated. Are they a single value with bits concationated or is each one represent a single digit of the last two digits of a year? The fact that they are separated from each other makes me think each is a digit, but you can only represent 0-7 with the 3 bits it uses in `Byte 3`. If they are concatenated that gives you 0-127, so you could use that for 0-99 – Scott Chamberlain Dec 17 '15 at 21:57
-
Check http://stackoverflow.com/q/14464/1729885 – Niels Keurentjes Dec 17 '15 at 22:00
-
1 byte = (Y<<4) + Month – Matthew Lamb Dec 17 '15 at 22:05
-
What is the base offset for the year? 2000? – Matthew Watson Dec 17 '15 at 22:06
-
4 bytes = ((Y>>4)<<29) + (Day<<24) + (Hour<<19) + (Minute<<13) + (Seconds<<7) + Hundredths – Matthew Lamb Dec 17 '15 at 22:06
-
Y = Year – 1993. If the top three bits of byte 3 are used, this is valid to 2120. If not, it will roll over after 2008. – Matthew Lamb Dec 17 '15 at 22:06
-
Does that answer what you where after Matt? – Matthew Lamb Dec 17 '15 at 22:14
-
Yep. It's very fiddly this. ;) – Matthew Watson Dec 17 '15 at 22:15
2 Answers
3
Maybe this?
int yearBase = 1993;
int year = yearBase + (int) ((bytes[4] & 0xF0) >> 4) | ((bytes[3] & 0xE0) >> 1);
int month = (int) (bytes[4] & 0x0F);
int day = (int) (bytes[3] & 0x1F);
int hour = (int) ((bytes[2] & 0xF8) >> 3);
int min = (int) (((bytes[2] & 0x03) << 3) | ((bytes[1] & 0xE0) >> 5));
int sec = (int) ((bytes[1] & 0x1F) << 1) | ((bytes[0] & 0x80) >> 7);
int hundreths = (int) (bytes[0] & 0x7F);

Matthew Watson
- 104,400
- 10
- 158
- 276
-
Matt that is given me some good dates, I'll have to test this against the dates that I know. I'll have to track down some data for that, but the above is definitely on the right track, Thank you. – Matthew Lamb Dec 17 '15 at 22:34
1
I recently answer a question about bitshifting and integer packing in C#.
May be helper class written in that case can be usefull to you as starting point
public static class BinaryConverter
{
public static BitArray ToBinary(this int numeral)
{
return new BitArray(new[] { numeral });
}
public static int ToNumeral(this BitArray binary)
{
if (binary == null)
throw new ArgumentNullException("binary");
if (binary.Length > 32)
throw new ArgumentException("must be at most 32 bits long");
var result = new int[1];
binary.CopyTo(result, 0);
return result[0];
}
public static BitArray Take (this BitArray current, int length )
{
if (current.Length < length)
throw new Exception("Invalid length parameter");
List<bool> taken = new List<bool>();
for (int i = 0; i < length; i++)
taken.Add(current.Get(i));
return new BitArray(taken.ToArray());
}
public static BitArray Shift (this BitArray current, int length )
{
if (current.Length < length)
throw new Exception("Invalid length parameter");
List<bool> shifted = new List<bool>();
for (int i = 0; i < current.Length - length; i++)
shifted.Add(current.Get(length + i));
return new BitArray(shifted.ToArray());
}
public static BitArray FitSize (this BitArray current, int size)
{
List<bool> bools = new List<bool>() ;
bools = bools.InitBoolArray(size);
for (int i = 0; i < current.Count; i++)
bools[i] = current.Get(i) ;
return new BitArray(bools.ToArray());
}
public static List<bool> InitBoolArray(this List<bool> current, int size)
{
List<bool> bools = new List<bool> ();
for (int i = 0; i < size; i++)
bools.Add(false);
return bools ;
}
Here the reference to that answer Dynamic Bit Shifting / Unshifting
At the link above is displayed how pack small number on the same integer, your five bytes is pretty close to that question