The software loop will be inaccurate if you need to execute other code, unless you calculate how much time responding to a button takes. And as soon as you change anything in the code, it's no longer accurate.
This is exactly what the on-chip timers were designed for. Now you probably will not have a timer which goes to 20 min, but you don't have to. Just figure out how many timer interrupts happen in 20 min and make a counter for the interrupts.
There's really no need to get messing with the hardware timers and interrupts for something this simple.
By modifying the delay loop a bit (I didn't say it was a no-brainer) you can get it 100% accurate ans stil check the buttons. It only has to be accurate in the case no buttons are pressed, because all button fuctions stop or reset the timer anyway.
You also don't need button debouncing since all buttons send the program into a permanent state anyway.