I thk that this just about does it, though there may be some error in my arithmetic.
To check this script you can substitue test times for the $now var and day of week rather than waiting for the earth to spin around.
$now = strtotime(date("H:i"));
$open = strtotime(9:30);
// set up midnight and closing time according to the day of the week
switch (date(w)) {
case 1:
case 2:
case 3:
case 4:
// if it is mon, tues, wed, or thurs, closing time and midnight are normal
$close = strtotime(12:30);
$midnight = 86400;
break;
// friday, add 48 hours to midnight and closing time is normal
case 5:
$close = strtotime(12:30);
$midnight = 345600;
break;
// sat add 24 hours to midnight and closing time is zero
case 6:
$close = 0;
$midnight = 172600;
break;
// sunday midnight is normal and closing time is zero
case 0:
$close = 0;
$midnight = 86400;
}
switch (TRUE) {
// if it is after the market closed calculate time till next open
// setting close to zero for sat and sun covers the weekend
// adding extra days to midnight covers friday and saturday
case ($now > $close):
$diff = ($midnight - $now) + $open;
$hours = floor($diff / 3600);
$minutes = floor(($diff % 3600) / 60);
$state = 'Market Closed<br />' . $hours . 'hours ' . $minutes . 'minutes till the market opens again';
break;
// if it is before opening time then calculate time till open
case ($now < $open):
$diff = $open-$now;
$hours = floor($diff / 3600);
$minutes = floor(($diff % 3600) / 60);
$state = 'Market Closed<br />' . $hours . 'hours ' . $minutes . 'minutes till the market opens again';
break;
// otherwise the market is open
default:
$diff = $close-$now;
$hours = floor($diff / 3600);
$minutes = floor(($diff % 3600) / 60);
$state = 'Market Open<br />' . $hours . 'hours ' . $minutes . 'minutes till the market closes';
}