You should refer to an ascii character chart. For historical reasons, the numbers 0 to 9 are not the same as ascii values '0' to '9'. Note that I'm using ' ' around the character versions to distingush them from actual values.
The number you start with (from the DS1307) is in packed BCD format, that means two digits have been combined (packed) into one byte. The byte has 8 bits and one digit is in the top 4 bits, the other in the bottom 4 bits. To display them as two ascii characters you first have to seperate the upper and lower parts of the byte so each digit can be dealt with alone. I'll break you program down line by line to explain how it's done:
This reserves a 'char' sized variable and gives it the name 'buf'. A char is 8-bits or 1 byte. It also intializes it's value as zero although ths isn't actually necessary in this application as it will be overwritten by the next line anyway.
'time' is the BCD value from the clock. Remember that brackets '(' and ')' are used to change the order in which a calculationis done, just as in normal math. So (time >> 4) takes the BCD value and shifts it four bits to the right, the bits already at the right end are lost and zero bits are loaded in from the left. Effectively, the high 4 bits are now where the lower 4 bits used to be. For example 0x50 would now be 0x05 and 0x23 would now be 0x02.
At this point the result is the actual value that was in the upper 4 bits but they need to be converted to ascii before being displayed. Looking at the ascii chart, the value zero is equal to ascii value 0x30, one is equalto 0x31 and so on. So to make values 0x00 through 0x09 into 0x30 to 0x39 we have to add 0x30 to them. You could write +0x30 or +'0', they are identical as far as the compiler is concerned because '0' (character xero) has the value 0x30 anyway. So 'buf' become the upper bits of 'time' with 0x30 added to it, that makes the ascii character for the high bits of 'time' ready to be dsplayed.
I think you can work that one out for yourself!
This is the same calculation as before except this time the lower 4 bits of 'time' are being used. As they are already in the right positions, all you have to do is remove the top 4 bits so they don't get added to the 0x30 and produce the wrong cgaracter. To make sure they are all zero the AND '&' function is used. The logic of AND says that to get a '1' out, one input AND the other both have to be '1'. The binary of 0x0F is 00001111 so if you AND that with the BCD value in 'time' the top 4 bits will always be zero and the bottom bits will remain as they are. All that remnains to be done is again add the 0x30 to align 0-9 to '0' to '9' in the ascii chart before putting the result in 'buf'.
I hope that explains.
Brian.