// 踏切音スイッチボタン function buttonClick(){ console.log('click'); const message1 = "踏切音 鳴りません"; const message2 = "踏切音 鳴ります"; let temp = document.getElementById("sound").value if (temp==message2){temp=message1;document.getElementById("sound").style.backgroundColor = "lightgray";} else {temp=message2; document.getElementById("sound").style.backgroundColor = "yellow";} document.getElementById("sound").value = temp; } // 時計表示 function twoDigit(num) { let ret; if( num < 10 ) ret = "0" + num; else ret = num; return ret; } // 時計表示 function showClock() { let nowTime = new Date(); let nowHour = twoDigit( nowTime.getHours() ); let nowMin = twoDigit( nowTime.getMinutes() ); let nowSec = twoDigit( nowTime.getSeconds() ); let msg = "現在時刻:" + nowHour + ":" + nowMin + ":" + nowSec; document.getElementById("realtime").innerHTML = msg; } // ★行く先表示置換 function destReplace(deststr) { let newdeststr; newdeststr = deststr.replace("枚 方","枚方着"); newdeststr = newdeststr.replace("淀屋橋","枚方着"); newdeststr = newdeststr.replace("中之島","枚方着"); newdeststr = newdeststr.replace("守 口","枚方着"); newdeststr = newdeststr.replace("出町柳","枚方発"); newdeststr = newdeststr.replace("樟 葉","枚方発"); newdeststr = newdeststr.replace("三 条","枚方発"); newdeststr = newdeststr.replace(" 淀 ","枚方発"); newdeststr = newdeststr.replace("私 市","枚方発"); return newdeststr; } // ★種別表示置換 function typeReplace(type) { let newtype; if (type == "") { newtype = "普通"; } else if (type == "トーマス") { newtype = "トーマス"; } else if (type == "ライナー") { newtype = "ライナー"; } else { newtype = type; } return newtype; } // ★土日祝判定 async function fetchHolidays(year) { const cacheKey = `holidays_${year}`; const cacheDateKey = `holidays_${year}_date`; // const today = new Date().toLocaleDateString().replaceAll("/","-"); // YYYY-MM-DD 形式 const today = new Date().toLocaleDateString("ja-JP", {year: "numeric",month: "2-digit", day: "2-digit"}).replaceAll('/', '-') // キャッシュチェック(保存されている日付と今日の日付を比較) const cachedData = localStorage.getItem(cacheKey); const cachedDate = localStorage.getItem(cacheDateKey); if (cachedData && cachedDate === today) { return JSON.parse(cachedData); } // APIから取得 const url = `https://holidays-jp.github.io/api/v1/${year}/date.json`; try { const response = await fetch(url); if (!response.ok) throw new Error("Failed to fetch holidays"); const holidays = await response.json(); // キャッシュに保存(今日の日付も記録) localStorage.setItem(cacheKey, JSON.stringify(holidays)); localStorage.setItem(cacheDateKey, today); return holidays; } catch (error) { console.error("Error fetching holiday data:", error); return cachedData ? JSON.parse(cachedData) : {}; // キャッシュがあればそれを返す } } // ★土日祝判定 async function getDayType(date = new Date()) { const year = date.getFullYear(); const holidays = await fetchHolidays(year); // const dateStr = date.toLocaleDateString().replaceAll("/","-"); // YYYY-MM-DD 形式 const dateStr = date.toLocaleDateString("ja-JP", {year: "numeric",month: "2-digit", day: "2-digit"}).replaceAll('/', '-') if (holidays[dateStr]) { return "holiday"; } const day = date.getDay(); // 0:日曜, 6:土曜 if (day === 0 || day === 6) { return "weekend"; } return "weekday"; } // ★土日祝判定表示 //async function displayResult() { // const loadingElement = document.getElementById("loading"); // const result = await getDayType(); // loadingElement.style.display = "none"; // 読み込み中メッセージを非表示 //} // ★時刻表データ取得 async function fetchSchedule() { const url = "json/train_schedule_hirakata_full.json"; // JSONファイルのURL let b5info_url = "../json/b5info_log.json"; // JSONファイル名 b5info_url = b5info_url+"?20250602225548"; try { const response = await fetch(url); const data = await response.json(); displayNextTrains(data); let response2 = await fetch(b5info_url); let b5info_data = await response2.json(); let message = b5info_data.KEIHAN.INFO; if (message == "京阪本線は全線平常運転中です") { // 京阪情報 document.getElementById('message-text').style.backgroundColor = 'green'; document.getElementById('message-text').style.color = 'yellow'; } else { document.getElementById('message-text').style.backgroundColor = 'red'; document.getElementById('message-text').style.color = 'yellow'; } document.getElementById('message-text').innerHTML=message; } catch (error) { document.getElementById("fromkyoto").innerHTML = "データ取得に失敗しました"; //枚方着大阪方面行き document.getElementById("tokyoto").innerHTML = "データ取得に失敗しました"; //枚方発京都方面行き document.getElementById("fromkatano").innerHTML = "データ取得に失敗しました"; //枚方着枚方方面行き document.getElementById("tokatano").innerHTML = "データ取得に失敗しました"; //枚方発私市方面行き console.error("Error fetching data:", error); } } // ★時刻表データ表示 async function displayNextTrains(data) { // console.log(data); const honsuu=5; const pasttime=2; const red_time = 31; const hoseitime_fromkyoto =20; const hoseitime_tokyoto =55; const hoseitime_fromkatano =20; const hoseitime_tokatano =55; const now = new Date(); const currentTime = now.getHours() * 60 + now.getMinutes(); // 現在時刻を分単位で取得 const currentTimeSec = now.getHours() * 60 * 60 + now.getMinutes() * 60 + now.getSeconds(); // 現在時刻を秒単位で取得 const result = await getDayType(); // console.log(result); let fromkyotoTrains; let tokyotoTrains; let fromkatanoTrains; let tokatanoTrains; let honsenTitle; let katanosenTitle; if (result == "weekday") { honsenTitle = "京阪本線(平日)"; katanosenTitle = "交野線(平日)"; fromkyotoTrains = data.fromKyotoWeekday.filter(train => { const [hours, minutes] = train.time.split(":").map(Number); return hours * 60 + minutes > currentTime - pasttime; // 2分過去から表示 // return hours * 60 + minutes > currentTime + 5; // 5分未来から表示 }).slice(0, honsuu); // 次の10本を取得 tokyotoTrains = data.toKyotoWeekday.filter(train => { const [hours, minutes] = train.time.split(":").map(Number); return hours * 60 + minutes > currentTime - pasttime; // 2分過去から表示 }).slice(0, honsuu); // 次の10本を取得 fromkatanoTrains = data.fromKatanoWeekday.filter(train => { const [hours, minutes] = train.time.split(":").map(Number); return hours * 60 + minutes > currentTime - pasttime; // 2分過去から表示 }).slice(0, honsuu); // 次の10本を取得 tokatanoTrains = data.toKatanoWeekday.filter(train => { const [hours, minutes] = train.time.split(":").map(Number); return hours * 60 + minutes > currentTime - pasttime; // 2分過去から表示 }).slice(0, honsuu); // 次の10本を取得 } else { honsenTitle = "京阪本線(休日)"; katanosenTitle = "交野線(休日)"; fromkyotoTrains = data.fromKyotoWeekend.filter(train => { const [hours, minutes] = train.time.split(":").map(Number); return hours * 60 + minutes > currentTime - pasttime; // 2分過去から表示 // return hours * 60 + minutes > currentTime + 5; // 5分未来から表示 }).slice(0, honsuu); // 次の10本を取得 tokyotoTrains = data.toKyotoWeekend.filter(train => { const [hours, minutes] = train.time.split(":").map(Number); return hours * 60 + minutes > currentTime - pasttime; // 2分過去から表示 }).slice(0, honsuu); // 次の10本を取得 fromkatanoTrains = data.fromKatanoWeekend.filter(train => { const [hours, minutes] = train.time.split(":").map(Number); return hours * 60 + minutes > currentTime - pasttime; // 2分過去から表示 }).slice(0, honsuu); // 次の10本を取得 tokatanoTrains = data.toKatanoWeekend.filter(train => { const [hours, minutes] = train.time.split(":").map(Number); return hours * 60 + minutes > currentTime - pasttime; // 2分過去から表示 }).slice(0, honsuu); // 次の10本を取得 } //★from京都★ let derection; derection = 'fromkyoto'; let fromkyotoHtml = ""; if (fromkyotoTrains.length > 0) { fromkyotoTrains.forEach(train => { let className = "local"; if (train.type === "特急") className = "special"; else if (train.type === "ライナー") className = "special"; else if (train.type === "急行") className = "express"; else if (train.type === "快急") className = "express"; else if (train.type === "通快") className = "express"; else if (train.type === "準急") className = "semi-express"; else if (train.type === "通準") className = "semi-express"; else if (train.type === "区急") className = "local-express"; const [hours, minutes] = train.time.split(":").map(Number); let hourminute = train.time if (hours < 10){hourminute=" "+hourminute} //10時以前の一桁台の処理 let remaintime; //残り時間の算出と表示 // remaintime = hours * 60 + minutes - currentTime; remaintime = hours * 60 * 60 + minutes * 60 - currentTimeSec + hoseitime_fromkyoto; let className2 = "standby-train"; if ((remaintime < red_time) && (remaintime > red_time-3)) { // await play_sound('osaka'); play_sound(derection); } else if ((remaintime < red_time-3) && (remaintime > red_time-6)) { sessionStorage.setItem(derection, 'off'); console.log("stop play humikiri : " + derection + ", remaintime : " + remaintime); } if ((remaintime < red_time) && (remaintime > -1*red_time)) { className2 = "next-train"; } else if (remaintime < 0) { className2 = "leaved-train"; } let spacer; spacer = ""; if (remaintime < -99) {spacer=spacer} else if (remaintime < -9) {spacer=" "} else if (remaintime < 0) {spacer=" "+" "} else if (remaintime < 10) {spacer=" "+" "+" "} else if (remaintime < 100) {spacer=" "+" "} else if (remaintime < 1000) {spacer=" "} else if (remaintime < 10000){spacer=spacer} else {remaintime=remaintime} let dest; dest = destReplace(train.destination); fromkyotoHtml += `
本日の列車はすべて終了しました
"; } //★to京都★ derection = 'tokyoto'; let tokyotoHtml = ""; if (tokyotoTrains.length > 0) { tokyotoTrains.forEach(train => { let className = "local"; if (train.type === "特急") className = "special"; else if (train.type === "ライナー") className = "special"; else if (train.type === "急行") className = "express"; else if (train.type === "快急") className = "express"; else if (train.type === "通快") className = "express"; else if (train.type === "準急") className = "semi-express"; else if (train.type === "通準") className = "semi-express"; else if (train.type === "区急") className = "local-express"; const [hours, minutes] = train.time.split(":").map(Number); let hourminute = train.time if (hours < 10){hourminute=" "+hourminute} //10時以前の一桁台の処理 let remaintime; //残り時間の算出と表示 // remaintime = hours * 60 + minutes - currentTime; remaintime = hours * 60 * 60 + minutes * 60 - currentTimeSec + hoseitime_tokyoto; let className2 = "standby-train"; if ((remaintime < red_time) && (remaintime > red_time-3)) { // await play_sound('osaka'); play_sound(derection); } else if ((remaintime < red_time-3) && (remaintime > red_time-6)) { sessionStorage.setItem(derection, 'off'); console.log("stop play humikiri : " + derection + ", remaintime : " + remaintime); } if ((remaintime < red_time) && (remaintime > -1*red_time)) { className2 = "next-train"; } else if (remaintime < 0) { className2 = "leaved-train"; } spacer = ""; if (remaintime < -99) {spacer=spacer} else if (remaintime < -9) {spacer=" "} else if (remaintime < 0) {spacer=" "+" "} else if (remaintime < 10) {spacer=" "+" "+" "} else if (remaintime < 100) {spacer=" "+" "} else if (remaintime < 1000) {spacer=" "} else if (remaintime < 10000){spacer=spacer} else {remaintime=remaintime} let dest; dest = destReplace(train.destination); tokyotoHtml += `本日の列車はすべて終了しました
"; } //★from交野★ derection = 'fromkatano'; let fromkatanoHtml = ""; if (fromkatanoTrains.length > 0) { fromkatanoTrains.forEach(train => { let className = "local"; if (train.type === "特急") className = "special"; else if (train.type === "ライナー") className = "special"; else if (train.type === "急行") className = "express"; else if (train.type === "快急") className = "express"; else if (train.type === "通快") className = "express"; else if (train.type === "準急") className = "semi-express"; else if (train.type === "通準") className = "semi-express"; else if (train.type === "区急") className = "local-express"; else if (train.type === "トーマス") className = "Thomas"; const [hours, minutes] = train.time.split(":").map(Number); let hourminute = train.time if (hours < 10){hourminute=" "+hourminute} //10時以前の一桁台の処理 let remaintime; //残り時間の算出と表示 // remaintime = hours * 60 + minutes - currentTime; remaintime = hours * 60 * 60 + minutes * 60 - currentTimeSec + hoseitime_fromkatano; let className2 = "standby-train"; if ((remaintime < red_time) && (remaintime > red_time-3)) { // await play_sound('osaka'); play_sound(derection); } else if ((remaintime < red_time-3) && (remaintime > red_time-6)) { sessionStorage.setItem(derection, 'off'); console.log("stop play humikiri : " + derection + ", remaintime : " + remaintime); } if ((remaintime < red_time) && (remaintime > -1*red_time)) { className2 = "next-train"; } else if (remaintime < 0) { className2 = "leaved-train"; } spacer = ""; if (remaintime < -99) {spacer=spacer} else if (remaintime < -9) {spacer=" "} else if (remaintime < 0) {spacer=" "+" "} else if (remaintime < 10) {spacer=" "+" "+" "} else if (remaintime < 100) {spacer=" "+" "} else if (remaintime < 1000) {spacer=" "} else if (remaintime < 10000){spacer=spacer} else {remaintime=remaintime} let dest; dest = destReplace(train.destination); let traintype; traintype = typeReplace(train.type); fromkatanoHtml += `本日の列車はすべて終了しました
"; } //★to交野★ derection = 'tokatano'; let tokatanoHtml = ""; if (tokatanoTrains.length > 0) { tokatanoTrains.forEach(train => { let className = "local"; if (train.type === "特急") className = "special"; else if (train.type === "ライナー") className = "special"; else if (train.type === "急行") className = "express"; else if (train.type === "快急") className = "express"; else if (train.type === "通快") className = "express"; else if (train.type === "準急") className = "semi-express"; else if (train.type === "通準") className = "semi-express"; else if (train.type === "区急") className = "local-express"; else if (train.type === "トーマス") className = "Thomas"; const [hours, minutes] = train.time.split(":").map(Number); let hourminute = train.time if (hours < 10){hourminute=" "+hourminute} //10時以前の一桁台の処理 let remaintime; //残り時間の算出と表示 // remaintime = hours * 60 + minutes - currentTime; remaintime = hours * 60 * 60 + minutes * 60 - currentTimeSec + hoseitime_tokatano; let className2 = "standby-train"; if ((remaintime < red_time) && (remaintime > red_time-3)) { // await play_sound('osaka'); play_sound(derection); } else if ((remaintime < red_time-3) && (remaintime > red_time-6)) { sessionStorage.setItem(derection, 'off'); console.log("stop play humikiri : " + derection + ", remaintime : " + remaintime); } if ((remaintime < red_time) && (remaintime > -1*red_time)) { className2 = "next-train"; } else if (remaintime < 0) { className2 = "leaved-train"; } spacer = ""; if (remaintime < -99) {spacer=spacer} else if (remaintime < -9) {spacer=" "} else if (remaintime < 0) {spacer=" "+" "} else if (remaintime < 10) {spacer=" "+" "+" "} else if (remaintime < 100) {spacer=" "+" "} else if (remaintime < 1000) {spacer=" "} else if (remaintime < 10000){spacer=spacer} else {remaintime=remaintime} let dest; dest = destReplace(train.destination); traintype = typeReplace(train.type); tokatanoHtml += `本日の列車はすべて終了しました
"; } document.getElementById("honsen-title").innerHTML = honsenTitle; document.getElementById("katanosen-title").innerHTML = katanosenTitle; document.getElementById("fromkyoto").innerHTML = fromkyotoHtml; document.getElementById("tokyoto").innerHTML = tokyotoHtml; document.getElementById("fromkatano").innerHTML = fromkatanoHtml; document.getElementById("tokatano").innerHTML = tokatanoHtml; } // ★踏切音 //function play_sound(derection) { async function play_sound(derection) { // データの取得 const humikiri_status = sessionStorage.getItem(derection); const sound_status = document.getElementById("sound").value; if (humikiri_status == 'on') { // console.log("playing humikiri : " + derection) } else if ((sound_status == "踏切音 鳴ります") && (humikiri_status == 'off')) { console.log("start play humikiri : " + derection) const url = "./mp3/humikiri.mp3"; // mp3ファイルのURL const audio = new Audio(url); // ファイルのパスを指定 audio.play(); // データの保存 sessionStorage.setItem(derection, 'on'); } } document.addEventListener("DOMContentLoaded", function() { // これだと最優先反映 loading="lazy"項目より優先される sessionStorage.setItem('tokyoto', 'off'); sessionStorage.setItem('fromkyoto', 'off'); sessionStorage.setItem('tokatano', 'off'); sessionStorage.setItem('fromkatano', 'off'); setInterval(fetchSchedule, 1000); // 1sごとに更新 setInterval(showClock, 1000); // 1sごとに更新 });