I think your issue is that you only actually check the time once, in the very first statement in the loop, when you run localtime(time). All the sprintf commands that follow merely format the same snapshot in time.
One of the nice features of localtime and gmtime in Perl is that if you run them in scalar context, you get a string with the time already formatted for you. So all you need to do to fix this issue is replace the assignment to $now every time it appears with:
$now = localtime(time);
and get rid of the first line that begins with "my" in its entirety. This will give you a much clearer picture of whether or not your sleep commands are being messed up by DBI, because they will be more accurate.