'01','February'=>'02','March'=>'03','April'=>'04','May'=>'05','June'=>'06', 'July'=>'07','August'=>'08','September'=>'09','October'=>'10','November'=>'11','December'=>'12', 'Jan'=>'01','Feb'=>'02','Mar'=>'03','Apr'=>'04','Jun'=>'06','Jul'=>'07','Aug'=>'08','Sep'=>'09','Oct'=>'10','Nov'=>'11','Dec'=>'12', ]; $thai = ['มกราคม'=>'01','กุมภาพันธ์'=>'02','มีนาคม'=>'03','เมษายน'=>'04','พฤษภาคม'=>'05','มิถุนายน'=>'06','กรกฎาคม'=>'07','สิงหาคม'=>'08','กันยายน'=>'09','ตุลาคม'=>'10','พฤศจิกายน'=>'11','ธันวาคม'=>'12']; function normalDate(int|string $day, string $month, int|string $year, array $english, array $thai): string { $monthNo = $english[$month] ?? $thai[$month] ?? null; if ($monthNo === null) return (string)$day . ' ' . $month . ' ' . (string)$year; $yearNo = (int)$year; if ($yearNo >= 2400) $yearNo -= 543; return sprintf('%02d/%s/%02d', (int)$day, $monthNo, $yearNo % 100); } function normalizeDates(string $text, array $english, array $thai): string { $months = implode('|', array_map(static fn($v) => preg_quote($v, '/'), array_keys($english + $thai))); // Compact Buddhist document/report dates, e.g. 25690817. $text = preg_replace_callback('/\b(25\d{2})(\d{2})(\d{2})\b/', static function ($m) { return sprintf('%02d/%02d/%02d', (int)$m[3], (int)$m[2], ((int)$m[1] - 543) % 100); }, $text) ?? $text; // Shared-month range: 11–13 May 2026. $text = preg_replace_callback('/\b(\d{1,2})\s*[–-]\s*(\d{1,2})\s+('.$months.')\s+(20\d{2}|25\d{2})\b/u', static function ($m) use ($english,$thai) { return normalDate($m[1],$m[3],$m[4],$english,$thai).'–'.normalDate($m[2],$m[3],$m[4],$english,$thai); }, $text) ?? $text; // Two-month range with a shared year: 5 January–14 August 2026. $text = preg_replace_callback('/\b(\d{1,2})\s+('.$months.')\s*[–-]\s*(\d{1,2})\s+('.$months.')\s+(20\d{2}|25\d{2})\b/u', static function ($m) use ($english,$thai) { return normalDate($m[1],$m[2],$m[5],$english,$thai).'–'.normalDate($m[3],$m[4],$m[5],$english,$thai); }, $text) ?? $text; // Hyphenated two-month range: 19-Feb–29-May-2026. $text = preg_replace_callback('/\b(\d{1,2})-('.$months.')\s*[–-]\s*(\d{1,2})-('.$months.')-(20\d{2}|25\d{2})\b/u', static function ($m) use ($english,$thai) { return normalDate($m[1],$m[2],$m[5],$english,$thai).'–'.normalDate($m[3],$m[4],$m[5],$english,$thai); }, $text) ?? $text; // A full single date using a month name or abbreviation. $text = preg_replace_callback('/\b(\d{1,2})(?:-|\s+)('.$months.')(?:-|\s+)(20\d{2}|25\d{2})\b/u', static function ($m) use ($english,$thai) { return normalDate($m[1],$m[2],$m[3],$english,$thai); }, $text) ?? $text; // Period descriptions without a repeated year, all known to be in 2026. $text = preg_replace_callback('/\b(\d{1,2})\s*[–-]\s*(\d{1,2})\s+('.$months.')(?=\s+(?:commits|accounting|May|April|January|February|March|June|July|August))/u', static function ($m) use ($english,$thai) { return normalDate($m[1],$m[3],2026,$english,$thai).'–'.normalDate($m[2],$m[3],2026,$english,$thai); }, $text) ?? $text; // Commit-period shorthand: 30-Apr through 08-May. $text = preg_replace_callback('/\b(\d{1,2})-('.$months.')\s+through\s+(\d{1,2})-('.$months.')\b/u', static function ($m) use ($english,$thai) { return normalDate($m[1],$m[2],2026,$english,$thai).'–'.normalDate($m[3],$m[4],2026,$english,$thai); }, $text) ?? $text; return $text; } $iterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($root, FilesystemIterator::SKIP_DOTS)); $updated = 0; foreach ($iterator as $file) { if (!$file->isFile() || !str_starts_with($file->getFilename(), '200-WMS-')) continue; $path = $file->getPathname(); $extension = strtolower($file->getExtension()); if ($extension === 'md') { $before = file_get_contents($path); if ($before === false) continue; $after = normalizeDates($before, $english, $thai); if ($after !== $before) { file_put_contents($path, $after); $updated++; } continue; } if (!in_array($extension, ['docx','xlsx'], true)) continue; $zip = new ZipArchive(); if ($zip->open($path) !== true) continue; $changed = false; for ($i=0; $i<$zip->numFiles; $i++) { $name = $zip->getNameIndex($i); if (!str_ends_with($name, '.xml')) continue; $before = $zip->getFromIndex($i); $after = normalizeDates($before, $english, $thai); if ($after === $before) continue; $dom = new DOMDocument(); if (!$dom->loadXML($after)) throw new RuntimeException("Invalid XML after date conversion: {$path}::{$name}"); $zip->addFromString($name, $after); $changed = true; } $zip->close(); if ($changed) $updated++; } echo "Updated {$updated} BRN WMS document(s).\n";