Decoding a 1 Byte Date into Year, Month and Day

Updated solution:

I’m still not sure whether this is what OP is looking as no concrete code was stated in his question.

Similarly he did not state what the expected output would be, all we know now was that a 16 bit binary was given to OP, and he will need to figure out the binary codes for the Year, Month and Day through certain bit position.

Once the binary has been captured then convert the binary bits into numeric values, which then it is used for further comparison. For instance, year value of > 100 means it is year > 2000.

My solution:

private long unsetBit(long value, int pos) { return value & ~(1<<pos); }

private long getYear(long value) { return value >> /*total 0 in month and day=*/9; }

private long getMonthDay(long value) {
    int[] leftBitPos = new int[]{ 16, 15, 14, 13, 12, 11, 10 };
    for (Integer position : leftBitPos) value = unsetBit(value, position);
    return value;
}

private long getMonth(long value) {
    value = getMonthDay(value);
    return value >> /*total 0 in day=*/5;
}

private long getDay(long value) {
    int[] leftBitPos = new int[]{ 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5 };
    for (Integer position : leftBitPos) value = unsetBit(value, position);
    return value;
}

private void doIt() {
    long fullDate = 0b1111111110100001;
     System.out.println("Year binary: " + getYear(fullDate));
     System.out.println("Month binary: " + getMonth(fullDate));
     System.out.println("Day binary: " + getDay(fullDate));

Year binary: 127
Month binary: 29

Day binary: 1

Old solution, the regexpr way.

Assuming OP has the luxury to convert the binary value into a piece of String and then also assuming he is just interested in the binary code for the “Year”, “Month” and “Day”.

I would propose doing a simple capture regular expression to look for the 0s and 1s for a particular date and then process the captured values further by padding some zeros to it. Or alternatively if you don’t like using regexpr you can look at doing a string.substring and do the same, padding it with zeros.

Recommend using the regexpr;
^(?=[0-1]{16})([0-1]{7})([0-1]{4})([0-1]{5})

Essentially what this does is;

  1. From the first character ^
  2. (?=[0-1]{16) Check and see if there is 16 zero and one characters in the string
  3. From the first character capture the first 7 0 and 1, ([0-1]{7}) for the year.
  4. Do the same for month and day respectively through ([0-1]{4})([0-1]{5})

Now prefix and pad your year month and day result values with the appropriate amount of zeroes.

Example:

final String YEAR_PADDING = "0000000";
final String MONTH_PADDING = "0000";
final String DAY_PADDING = "00000";

private void doIt() {

    Pattern binaryDateFormat = Pattern.compile("^(?=[0-1]{16})([0-1]{7})([0-1]{4})([0-1]{5})");
    Matcher m = binaryDateFormat.matcher("1111111111100000");

    while (m.find()) {
        System.out.println("Year binary: " + m.group(1) + MONTH_PADDING + DAY_PADDING);
        System.out.println("Month binary: " + YEAR_PADDING + m.group(2) + DAY_PADDING);
        System.out.println("Day binary: " + YEAR_PADDING + MONTH_PADDING + m.group(3));
    }

}

Output:

Year binary: 1111111000000000
Month binary: 0000000111100000
Day binary: 0000000000000000

Leave a Comment