Holy Trinity Church, MI Hourly Weather Updates

Feedback E-mail the Weather

Quick Clicks

Weather World

Holy Trinity Church, MI Weather Maps

°F °C°F °C
Holy Trinity Church Weather Map
UTC Time: 9/12/2026, 13:39
Your Time:

Aeronautical Observation: Automated synoptic observations via NWS Gateway.
Auto-refresh in: 5:02

Holy Trinity Church, MI Regional Weather

Expires:202609121400;;326050
ASUS43 KDTX 121310
RWRMI 
MICHIGAN HOURLY REGIONAL WEATHER ROUNDUP
NATIONAL WEATHER SERVICE DETROIT/PONTIAC MI
900 AM EDT SAT SEP 12 2026

NOTE: "FAIR" INDICATES FEW OR NO CLOUDS BELOW 12,000 FEET WITH NO
SIGNIFICANT WEATHER AND/OR OBSTRUCTION TO VISIBILITY.


MIZ004>006-011>014-085-121400-
CENTRAL UPPER MICHIGAN
  
CITY           SKY/WX    TMP DP  RH WIND       PRES   REMARKS
MANISTIQUE     CLOUDY    66  64  94 S9        29.72F TC  19           
ESCANABA       CLOUDY    67  63  87 SW12G21   29.74R TC  19           
MENOMINEE      CLOUDY    68  64  87 SW12      29.74F TC  20           
SAWYER-GWINN   SUNNY     63  59  88 S14       29.71R TC  17           
MUNISING         N/A     68  60  75 S8        29.70S TC  20           
$$

SKY/WX - Weather  TMP - Temperature  DP - Dew Point  RH - Humidity
WIND - Wind Direction/Speed PRES - Barometric Pressure VSB - Visibility
WCI - Wind Chill Index E13G22 Wind - East Wind 13 mph/Gusts of 22 mph
2026-09-12 09:39:14 %%CODE $stateCode = 'ne'; $cwaKey = 'oax'; $currentCity = 'omaha'; $refLat = 41.26390; $refLon = -96.01170; $refZone = 'NEZ052'; $targetLimit = 30; $enableMissingLinkLogging = true; $stateCode = !empty($GET['state']) ? $GET['state'] : (!empty($stateCode) ? $stateCode : 'ct'); $cwaKey = !empty($GET['cwa']) ? $GET['cwa'] : (!empty($cwaKey) ? $cwaKey : 'box'); $stateCode = strtolower(preg_replace('/[^a-z]/i', '', $stateCode)); $cwaKey = strtolower(preg_replace('/[^a-z0-9]/i', '', $cwaKey)); if (!function_exists('getWxDbConnection')) { function getWxDbConnection() { static $pdo = null; if ($pdo === null) { $dbConfigFile = '/home/wxworld/public_html/database.ini.php'; if (file_exists($dbConfigFile)) { require $dbConfigFile; try { $dsn = "mysql:host={$dbserver};dbname={$dbdatabase};charset=utf8mb4"; $pdo = new PDO($dsn, $dbuser, $dbpassword, array( PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, PDO::ATTR_EMULATE_PREPARES => true, )); } catch (PDOException $e) { error_log("WeatherWorld DB Connection Error: " . $e->getMessage()); return null; } } } return $pdo; } } if (!function_exists('getNwsConditionMap')) { function getNwsConditionMap() { return array( 'SUNNY' => array('label' => 'Sunny', 'icon' => 'wi-day-sunny'), 'CLEAR' => array('label' => 'Clear', 'icon' => 'wi-day-sunny'), 'PTCLDY' => array('label' => 'Partly Cloudy', 'icon' => 'wi-day-cloudy'), 'MOCLDY' => array('label' => 'Mostly Cloudy', 'icon' => 'wi-day-cloudy-high'), 'CLOUDY' => array('label' => 'Cloudy', 'icon' => 'wi-cloudy'), 'HAZE' => array('label' => 'Haze', 'icon' => 'wi-day-haze'), 'WINDY' => array('label' => 'Windy', 'icon' => 'wi-day-windy'), 'DRZL' => array('label' => 'Drizzle', 'icon' => 'wi-day-sprinkle'), 'DRIZZLE' => array('label' => 'Drizzle', 'icon' => 'wi-day-sprinkle'), 'SPRINKLES' => array('label' => 'Sprinkles', 'icon' => 'wi-day-sprinkle'), 'RAIN' => array('label' => 'Rain', 'icon' => 'wi-day-rain'), 'SHWRS' => array('label' => 'Rain Showers', 'icon' => 'wi-day-showers'), 'RNSNOW' => array('label' => 'Rain & Snow Mix', 'icon' => 'wi-day-rain-mix'), 'SNOW' => array('label' => 'Snow', 'icon' => 'wi-day-snow'), 'SNOSHWR' => array('label' => 'Snow Showers', 'icon' => 'wi-day-snow'), 'SNOWSHWRS' => array('label' => 'Snow Showers', 'icon' => 'wi-day-snow'), 'SLEET' => array('label' => 'Sleet', 'icon' => 'wi-day-sleet'), 'TSTRMS' => array('label' => 'Thunderstorms', 'icon' => 'wi-day-thunderstorm'), 'TSTMS' => array('label' => 'Thunderstorms', 'icon' => 'wi-day-thunderstorm'), 'VRYHOT' => array('label' => 'Very Hot', 'icon' => 'wi-hot') ); } } if (!function_exists('renderSftAreaForecast')) { function renderSftAreaForecast($parsedDataCollection, $defaultStateCode = 'ct') { global $refLat, $refLon, $refZone, $targetLimit, $currentCity, $stateCode, $enableMissingLinkLogging; $map = getNwsConditionMap(); $pdo = getWxDbConnection(); $maxLimit = isset($targetLimit) ? intval($targetLimit) : 30; $lLat = !empty($refLat) ? floatval($refLat) : 45.18400; $lLon = !empty($refLon) ? floatval($refLon) : -84.95670; $zoneAliasMap = array( 'COZ040' => 'COZ038', ); $resolvedRefZone = !empty($refZone) ? strtoupper(trim($refZone)) : ''; if (isset($zoneAliasMap[$resolvedRefZone])) { $resolvedRefZone = $zoneAliasMap[$resolvedRefZone]; } $forcedState = !empty($stateCode) ? strtolower($stateCode) : strtolower($defaultStateCode); $forcedCityName = !empty($currentCity) ? trim($currentCity) : ''; $masterZones = array(); foreach ($parsedDataCollection as $parsedData) { if (isset($parsedData['zones']) && is_array($parsedData['zones'])) { foreach ($parsedData['zones'] as $zKey => $zVal) { $zKeyUpper = strtoupper(trim($zKey)); if (!isset($masterZones[$zKeyUpper])) { $masterZones[$zKeyUpper] = $zVal; } } } } if (empty($masterZones)) { return 'No regional zone data found in cache payloads.'; } $dbZoneCoords = array(); $targetZones = array_keys($masterZones); if ($pdo && !empty($targetZones)) { $chunkedZones = array_chunk($targetZones, 50); foreach ($chunkedZones as $chunk) { $placeholders = array(); $params = array(); foreach ($chunk as $i => $zKey) { $ph = ":z_" . md5($zKey) . "{$i}"; $placeholders[] = $ph; $params[$ph] = strtoupper(trim($zKey)); } $sql = "SELECT UPPER(a.wxzone) AS wxzone_raw, p.lat, p.lon, p.name, p.state, " . "(3959 * ACOS(COS(RADIANS(:currentLat)) * COS(RADIANS(p.lat)) * COS(RADIANS(p.lon) - RADIANS(:currentLon)) + SIN(RADIANS(:currentLat)) * SIN(RADIANS(p.lat)))) AS distance " . "FROM places p " . "JOIN alt_zone_info a ON p.places_id = a.places_id " . "WHERE UPPER(TRIM(a.wxzone)) IN (" . implode(',', $placeholders) . ") " . "ORDER BY distance ASC"; $stmt = $pdo->prepare($sql); $execParams = array_merge(array(':currentLat' => $lLat, ':currentLon' => $lLon), $params); $stmt->execute($execParams); while ($row = $stmt->fetch()) { $zUpper = strtoupper($row['wxzone_raw']); if (!isset($dbZoneCoords[$zUpper])) { $dbZoneCoords[$zUpper] = array( 'lat' => floatval($row['lat']), 'lon' => floatval($row['lon']), 'nearest_place' => $row['name'] . ', ' . $row['state'] ); } } } } $tempRankedZones = array(); foreach ($masterZones as $zoneKey => $zoneData) { $zKeyUpper = strtoupper(trim($zoneKey)); $zStatePrefix = strtolower(substr($zKeyUpper, 0, 2)); $isRef = ($zKeyUpper === $resolvedRefZone); $zoneState = !empty($zoneData['state_code']) ? strtolower($zoneData['state_code']) : $zStatePrefix; if (!preg_match('/^[a-z]{2}$/', $zoneState)) { $zoneState = $forcedState; } $closestCity = ''; if (!empty($zoneData['cities'][0])) { $closestCity = trim($zoneData['cities'][0]) . ', ' . strtoupper($zoneState); } elseif (!empty($zoneData['primary_name'])) { $closestCity = trim($zoneData['primary_name']) . ', ' . strtoupper($zoneState); } elseif (!empty($zoneData['zone_name'])) { $closestCity = trim($zoneData['zone_name']) . ', ' . strtoupper($zoneState); } elseif (!empty($zoneData['name'])) { $closestCity = trim($zoneData['name']) . ', ' . strtoupper($zoneState); } else { $closestCity = trim($zKeyUpper) . ', ' . strtoupper($zoneState); } if ($isRef) { if ($forcedCityName !== '') { $formattedRefCity = ucwords(strtolower($forcedCityName)); $closestCity = $formattedRefCity . ', ' . strtoupper($forcedState); } $zoneState = $forcedState; } $distance = 9999.0; $zoneLat = null; $zoneLon = null; if (isset($dbZoneCoords[$zKeyUpper])) { $zoneLat = $dbZoneCoords[$zKeyUpper]['lat']; $zoneLon = $dbZoneCoords[$zKeyUpper]['lon']; } elseif (isset($zoneData['lat']) && isset($zoneData['lon'])) { $zoneLat = floatval($zoneData['lat']); $zoneLon = floatval($zoneData['lon']); } if ($zoneLat !== null && $zoneLon !== null) { $theta = $lLon - $zoneLon; $dist = sin(deg2rad($lLat)) * sin(deg2rad($zoneLat)) + cos(deg2rad($lLat)) * cos(deg2rad($zoneLat)) * cos(deg2rad($theta)); $dist = acos(min(1.0, max(-1.0, $dist))); $distance = rad2deg($dist) * 69.09; } if ($isRef) { $distance = -1.0; } $parts = explode(',', $closestCity); $cleanCityName = trim($parts[0]); $displayState = isset($parts[1]) ? trim($parts[1]) : strtoupper($zoneState); $citySignature = strtolower($cleanCityName) . '|' . strtolower($displayState); if (!isset($tempRankedZones[$citySignature])) { $tempRankedZones[$citySignature] = array( 'zoneKey' => $zoneKey, 'zoneData' => $zoneData, 'zoneState' => $zoneState, 'cleanCityName' => $cleanCityName, 'displayState' => $displayState, 'distance' => $distance, 'is_ref' => $isRef ); } else { if ($isRef || (!$tempRankedZones[$citySignature]['is_ref'] && $distance < $tempRankedZones[$citySignature]['distance'])) { $tempRankedZones[$citySignature] = array( 'zoneKey' => $zoneKey, 'zoneData' => $zoneData, 'zoneState' => $zoneState, 'cleanCityName' => $cleanCityName, 'displayState' => $displayState, 'distance' => $distance, 'is_ref' => $isRef ); } } } $rankedZones = array_values($tempRankedZones); usort($rankedZones, 'sft_sort_ranked_zones'); $existingPlacesMap = array(); if ($pdo && !empty($rankedZones)) { $uniquePairs = array(); foreach ($rankedZones as $item) { $pairKey = strtolower($item['cleanCityName']) . '|' . strtolower($item['displayState']); if ($item['is_ref']) { $existingPlacesMap[$pairKey] = true; } else { $uniquePairs[$pairKey] = array( 'name' => $item['cleanCityName'], 'state' => $item['displayState'] ); } } if (!empty($uniquePairs)) { $pairChunks = array_chunk(array_values($uniquePairs), 50); foreach ($pairChunks as $chunk) { $tuples = array(); $params = array(); $idx = 0; foreach ($chunk as $p) { $namePlaceholder = ":pname{$idx}"; $statePlaceholder = ":pstate_{$idx}"; $tuples[] = "({$namePlaceholder}, {$statePlaceholder})"; $params[$namePlaceholder] = $p['name']; $params[$statePlaceholder] = $p['state']; $idx++; } $sql = "SELECT DISTINCT name, state FROM places WHERE (name, state) IN (" . implode(',', $tuples) . ")"; $stmt = $pdo->prepare($sql); $stmt->execute($params); while ($row = $stmt->fetch()) { $mapKey = strtolower(trim($row['name'])) . '|' . strtolower(trim($row['state'])); $existingPlacesMap[$mapKey] = true; } } } } $cityCounter = 0; $html = ''; foreach ($rankedZones as $item) { if ($cityCounter >= $maxLimit) { break; } $zoneKey = $item['zoneKey']; $zoneData = $item['zoneData']; $cleanCityName = $item['cleanCityName']; $displayState = $item['displayState']; $zoneState = $item['zoneState']; $cityCounter++; $displayTitle = $cleanCityName . ', ' . strtoupper($displayState); $citySlug = strtolower(str_replace(' ', '+', $cleanCityName)); $forecastUrl = 'https://www.weatherworld.com/14dayweather/' . strtolower($displayState) . '/' . $citySlug . '.html'; $warningUrl = 'https://www.weatherworld.com/stormwarnings/' . strtolower($displayState) . '/' . $citySlug . '.html'; $pairKey = strtolower($cleanCityName) . '|' . strtolower($displayState); $placeExistsInDb = isset($existingPlacesMap[$pairKey]) || $item['is_ref']; if ($placeExistsInDb) { $titleContent = '' . htmlspecialchars($displayTitle) . ''; } else { $titleContent = htmlspecialchars($displayTitle); if (!empty($enableMissingLinkLogging)) { $logMessage = sprintf("[%s] Unlinked place: %s (Zone: %s) not found in database.\n", date('Y-m-d H:i:s'), $displayTitle, $zoneKey); @error_log($logMessage, 3, '/home/wxworld/public_html/php-includes/missing_links.log'); } } $forecastPeriods = array(); if (isset($zoneData['forecast_periods']) && is_array($zoneData['forecast_periods'])) { $forecastPeriods = $zoneData['forecast_periods']; } elseif (isset($zoneData['periods']) && is_array($zoneData['periods'])) { $forecastPeriods = $zoneData['periods']; } elseif (isset($zoneData['properties']['periods']) && is_array($zoneData['properties']['periods'])) { $forecastPeriods = $zoneData['properties']['periods']; } $activeAlerts = array(); if (!empty($zoneData['active_alert'])) { if (is_array($zoneData['active_alert'])) { $activeAlerts = $zoneData['active_alert']; } else { $splitAlerts = preg_split('/(?=...[A-Z])/', $zoneData['active_alert']); foreach ($splitAlerts as $sa) { $trimmed = trim($sa); if ($trimmed !== '') $activeAlerts[] = $trimmed; } } } $columns = array(); foreach ($forecastPeriods as $period) { $pName = trim(isset($period['period']) ? $period['period'] : (isset($period['name']) ? $period['name'] : '')); $rawDate = isset($period['day_date']) ? $period['day_date'] : (isset($period['startTime']) ? substr($period['startTime'], 0, 10) : ''); $pDate = $rawDate !== '' ? date('m-d', strtotime($rawDate)) : ''; $temp = isset($period['hi_lo_temp']) ? $period['hi_lo_temp'] : (isset($period['temperature']) ? $period['temperature'] : ''); $cond = isset($period['condition']) ? $period['condition'] : (isset($period['shortForecast']) ? $period['shortForecast'] : ''); $icon = isset($period['condition_icon']) ? $period['condition_icon'] : (isset($period['icon']) ? $period['icon'] : ''); $popRaw = isset($period['pop']) ? $period['pop'] : (isset($period['probabilityOfPrecipitation']['value']) ? $period['probabilityOfPrecipitation']['value'] : ''); $pop = ($popRaw !== '' && $popRaw !== null) ? intval($popRaw) : 0; $desc = isset($period['day_night_zone_text']) ? $period['day_night_zone_text'] : (isset($period['detailed_forecast']) ? $period['detailed_forecast'] : (isset($period['detailedForecast']) ? $period['detailedForecast'] : '')); $isDaytimeFlag = isset($period['isDaytime']) ? $period['isDaytime'] : null; $pNameLower = strtolower($pName); if (strpos($pNameLower, 'early this morning') !== false || strpos($pNameLower, 'this morning') !== false) { $pName = 'This Morning'; } elseif (strpos($pNameLower, 'today') !== false && strpos($pNameLower, 'tonight') === false) { $pName = 'Today'; } $isNight = ($isDaytimeFlag !== null) ? !$isDaytimeFlag : (stripos($pName, 'night') !== false); if ($isNight) { $matched = false; foreach ($columns as &$col) { if (isset($col['full_date']) && $col['full_date'] === $rawDate && $col['low'] === '') { $col['low'] = $temp; $col['night_pop'] = $pop; if (!empty($desc)) $col['night_desc'] = $desc; $matched = true; break; } } unset($col); if ($matched) continue; } $columns[] = array( 'day' => $pName, 'date' => $pDate, 'full_date' => $rawDate, 'high' => !$isNight ? $temp : '', 'low' => $isNight ? $temp : '', 'condition' => $cond, 'condition_icon' => $icon, 'day_pop' => !$isNight ? $pop : 0, 'night_pop' => $isNight ? $pop : 0, 'day_desc' => !$isNight ? ($desc !== '' ? $desc : ($pName . ': ' . $cond)) : '', 'night_desc' => $isNight ? ($desc !== '' ? $desc : ($pName . ': ' . $cond)) : '' ); } $html .= ''; $html .= ' ' . $titleContent . ''; if (!empty($activeAlerts)) { foreach ($activeAlerts as $alertText) { $cleanAlert = trim($alertText, '. '); if ($cleanAlert !== '') { $html .= ''; $html .= ' ' . htmlspecialchars(strtoupper($cleanAlert)) . ''; $html .= ''; } } } $html .= ''; $colIndex = 0; foreach ($columns as $col) { $rawWx = strtoupper($col['condition_icon'] !== '' ? $col['condition_icon'] : $col['condition']); $cond = isset($map[$rawWx]) ? $map[$rawWx] : array('label' => ($col['condition'] !== '' ? $col['condition'] : $rawWx), 'icon' => 'wi-cloud'); $displayPop = max($col['day_pop'], $col['night_pop']); $activeClass = ($colIndex === 0) ? ' active' : ''; $targetId = 'desc-' . md5($zoneKey . $cleanCityName) . '-' . $colIndex; $rawDayName = trim($col['day']); $cleanDayName = preg_replace('/]fa-moon[^>]>.?/i', 'Night', $rawDayName); if (stripos($cleanDayName, 'night') !== false || preg_match('/(/|to|thru|through|and|-)/i', $cleanDayName)) { $daysRegex = '/\b(Sunday|Monday|Tuesday|Wednesday|Thursday|Friday|Saturday)\b/i'; $cleanDayName = preg_replace_callback($daysRegex, 'sft_ucfirst_substr', $cleanDayName); $cleanDayName = preg_replace('/\s[/-]\s*/', '-', $cleanDayName); } $html .= ''; $html .= '' . str_replace('','', $cleanDayName) . ''; $html .= ''; $html .= '' . htmlspecialchars($cond['label']) . ''; $html .= ''; if ($col['high'] !== '' && $col['low'] !== '') { $fHigh = (int)$col['high']; $fLow = (int)$col['low']; $cHigh = round(($fHigh - 32) * 5 / 9); $cLow = round(($fLow - 32) * 5 / 9); $html .= '' . $fHigh . '°/ ' . $fLow . '° '; $html .= '' . $cHigh . '°/ ' . $cLow . '°'; } elseif ($col['high'] !== '') { $fHigh = (int)$col['high']; $cHigh = round(($fHigh - 32) * 5 / 9); $html .= '' . $fHigh . '°' . $cHigh . '°'; } elseif ($col['low'] !== '') { $fLow = (int)$col['low']; $cLow = round(($fLow - 32) * 5 / 9); $html .= '' . $fLow . '°' . $cLow . '°'; } $html .= ''; $isPrecip = (stripos($col['condition'], 'rain') !== false || stripos($col['condition'], 'showers') !== false || stripos($col['condition'], 'snow') !== false || stripos($col['condition'], 'thunderstorm') !== false); if ($displayPop > 0) { $html .= ' ' . $displayPop . '%'; } elseif ($isPrecip) { $html .= 'N/A'; } else { $html .= '0%'; } $html .= ''; $colIndex++; } $html .= ''; $html .= ''; $colIndex = 0; foreach ($columns as $col) { $displayStyle = ($colIndex === 0) ? 'display: block;' : 'display: none;'; $targetId = 'desc-' . md5($zoneKey . $cleanCityName) . '-' . $colIndex; $html .= ''; $hasDay = !empty($col['day_desc']); $hasNight = !empty($col['night_desc']); if ($hasDay && $hasNight) { $html .= ' Day: ' . htmlspecialchars($col['day_desc']) . ''; $html .= ' Night: ' . htmlspecialchars($col['night_desc']) . ''; } elseif ($hasDay) { $html .= ' Day: ' . htmlspecialchars($col['day_desc']) . ''; } elseif ($hasNight) { $html .= ' Night: ' . htmlspecialchars($col['night_desc']) . ''; } else { $html .= '' . $col['day'] . ': ' . $col['condition'] . ''; } $html .= ''; $colIndex++; } $html .= ''; $html .= ''; } $html .= ''; return $html; } } if (!function_exists('sft_sort_ranked_zones')) { function sft_sort_ranked_zones($a, $b) { if ($a['is_ref'] && !$b['is_ref']) return -1; if (!$a['is_ref'] && $b['is_ref']) return 1; if ($a['distance'] == $b['distance']) return 0; return ($a['distance'] < $b['distance']) ? -1 : 1; } } if (!function_exists('sft_ucfirst_substr')) { function sft_ucfirst_substr($m) { return ucfirst(substr($m[1], 0, 3)); } } $cacheDir = '/home/wxworld/public_html/cachezone/sftcache/'; $primaryFile = $cacheDir . $cwaKey . '.json'; if (file_exists($primaryFile)) { $jsonContent = file_get_contents($primaryFile); $parsedPrimary = json_decode($jsonContent, true); if ($parsedPrimary && is_array($parsedPrimary)) { $parsedDataCollection = array($parsedPrimary); if (!empty($parsedPrimary['adjoining_cwas']) && is_array($parsedPrimary['adjoining_cwas'])) { foreach ($parsedPrimary['adjoining_cwas'] as $adjKey) { $adjFile = $cacheDir . strtolower(trim($adjKey)) . '.json'; if (file_exists($adjFile)) { $adjContent = file_get_contents($adjFile); $adjData = json_decode($adjContent, true); if ($adjData && is_array($adjData)) { $parsedDataCollection[] = $adjData; } } } } echo renderSftAreaForecast($parsedDataCollection, $stateCode); } else { echo 'Invalid JSON structure or decode failure in primary cache file.'; } } else { echo 'Source JSON cache file not found: ' . htmlspecialchars($primaryFile) . ''; } CODE%%

Trending Headlines

Trending Entertainment Headlines

Holy Trinity Church Radar Loop

Use the map search tool if you want to place a location marker on the radar map...

Holy Trinity Church Quick Facts

National Two Day Weather Forecast


E-mail the Holy Trinity Church Weather Forecast

Voice your opinion or tell us about page issues...