sembokulove
@sembokulove (Missing place)

Are you sure you want to delete the question?

If your question is resolved, you may close it.

Leaving a resolved question undeleted may help others!

We hope you find it useful!

列車在宣プログラムについて。平日、土休日という分け方ではなく、ダイヤを分けたいです。

平日、土休日という分け方ではなく、ダイヤを分けたいです。
以下を参考に作っています。
http://r113.web.fc2.com/p/viewer/jrw-hokuriku/
Flag形式のままだと、2通りのダイヤ表示しか出せなくて困っています。
if関数で、平日ダイヤと土休日ダイヤをさばいているのがわかりますが、
それ以外のことはわかりかねます。
以下はそのjavascriptの文ですが、こちらを、js文を省略なしに書いていただけたら幸いと思っております。

//平日ダイヤか土・休日ダイヤかを判定する
function dayJudge(year, month, date, day)
{
	//alert(year +" "+ month +" "+ date +" "+ day)
	//フラグ
	var weekdayFlag = true;
	
	//月〜金なら立てる
	if(day >= 1 && day <= 5)
		weekdayFlag = true;
	else
		weekdayFlag = false;
	
	//祝日ならたおす
	if(year == 2013 && month == 1 && date == 1)
		weekdayFlag = false;
	else if(year == 2013 && month == 10 && date == 14)
		weekdayFlag = false;
	else if(year == 2013 && month == 11 && date == 4)
		weekdayFlag = false;
	else if(year == 2013 && month == 12 && date == 23)
		weekdayFlag = false;
	else if(year == 2014 && month == 1 && date == 1)
		weekdayFlag = false;
	else if(year == 2014 && month == 1 && date == 2)
		weekdayFlag = false;
	else if(year == 2014 && month == 1 && date == 3)
		weekdayFlag = false;
	else if(year == 2014 && month == 1 && date == 13)
		weekdayFlag = false;
	else if(year == 2014 && month == 2 && date == 11)
		weekdayFlag = false;
	else if(year == 2014 && month == 3 && date == 21)
		weekdayFlag = false;
	else if(year == 2014 && month == 4 && date == 29)
		weekdayFlag = false;
	else if(year == 2014 && month == 5 && date == 5)
		weekdayFlag = false;
	else if(year == 2014 && month == 7 && date == 21)
		weekdayFlag = false;
	else if(year == 2014 && month == 9 && date == 15)
		weekdayFlag = false;
	else if(year == 2014 && month == 9 && date == 23)
		weekdayFlag = false;
	else if(year == 2014 && month == 10 && date == 12)
		weekdayFlag = false;
	else if(year == 2014 && month == 11 && date == 3)
		weekdayFlag = false;
	else if(year == 2014 && month == 11 && date == 24)
		weekdayFlag = false;
	else if(year == 2014 && month == 12 && date == 23)
		weekdayFlag = false;
	else if(year == 2015 && month == 1 && date == 1)
		weekdayFlag = false;
	else if(year == 2015 && month == 1 && date == 2)
		weekdayFlag = false;
	else if(year == 2015 && month == 1 && date == 3)
		weekdayFlag = false;
	else if(year == 2015 && month == 1 && date == 12)
		weekdayFlag = false;
	else if(year == 2015 && month == 2 && date == 11)
		weekdayFlag = false;
	else if(year == 2015 && month == 3 && date == 21)
		weekdayFlag = false;
	
	return weekdayFlag;
}
1

2Answer

まず前置きとして

script文は省略話されずにご所望いたします。

という希望は無意味であることをご認識ください.そちらの想定されるプログラム設計が具体的に見えない以上,こちらも具体案を出すことはできません.

そもそも特にJRの場合結構な頻度で臨時列車が運転されるので,本来は列車ごとに運転日を指定してDB化するのが本来一番取り回しやすい形かと思われます.(JR全国時刻表にも時刻表は毎月変わっていますとの注意書きがあります)

// 日付を指定して列車一覧を取得できるようなAPIがあるとする
const trainList = await fetch("***/**");
trainList.forEach(t => {
  const {number, destination} = t;
});

さすがにそれをただの通勤路線の時刻表でやろうとすると個人開発では無理がありますが,いずれにせよ臨時ダイヤに対応したいのであれば,まずプログラムの構造として

「平日」と「土休日」のどちらを持ってくるかをdayJudgeのような関数で判断する

のではなく

「○月×日」のダイヤをDBに保存しておき,getDiagramなる関数でfetchする

という想定を以て設計しなければなりません.

// 指定された日のダイヤを取得する処理を仮にgetDiagramとする
const todayDiagram = await getDiagram(new Date())

todayDiagram.trains.forEach(t => ...);

当然臨時でない平時のダイヤは「平日用」「土休日用」とまとめておくことはできるでしょうが,その設計を考察することこそがシステム設計における重要な部分だったりします.繰り返しになりますが,実際にどのようなコードを書くかはその設計が定まらなければ自分で書くことはおろか,こちらから提案することもできませんので,それはもう少しご自身で設計を固められる必要があります.

2Like

上のコードでは、曜日と祝日を判断して、平日と土休日を分けています。

平日、土休日という分け方ではなく、ダイヤを分けたいです。

何を判断して、どういうようにダイヤを分けたいのか?、この文章だけではご要望が理解できません。

1Like

Comments

  1. @sembokulove

    Questioner

    何を判断する→jrの特急列車のダイヤにおいて、年末年始の例でいうと、
    1月1日だけ運転の列車もあれば、2日、3日も運転し、4日以降は、運転しないというタイプの列車もあります。
    つまり、在線プログラムの場合でしたら、いくつかダイヤパターンを用意する必要がございます。
    しかし、この場合、Flagによる分け方では、onとoffの2パターンの分け方しかないため、例外規定を設け、1月1日だけ運転ということはできても、
    1月2・3日の時の場合のの運行パターンはどうするかという問題が生じてくるわけです。
    要するに、1月1日の運行パターン、2・3日の運行パターン、4日以降の運行パターンを作りたいわけです。
    1月1日だけのパターン、2・3日の運行パターン、4日の運行パターンにダイヤを分割するには、
    どのようにすればいいのでしょうか。
    個人的には、日ごとに分けるやり方のほうが好ましい気がいたします。
    script文は省略話されずにご所望いたします。

  2. 「フラグだと、true か false の2値しか表せないが、もっとたくさんの場合を表したい」ということであれば、整数とすることで、うん十億もの場合を表すことができます。
    入力情報としては、year, month, date, day だとして、各要素をそれぞれ判断して、ダイヤを表す数値を設定することになるかと思います。
    「js文を省略なしに書いていただけたら」というご要望ですが、あくまで例示しかできないことをご理解ください。

    //year, month, date, dayを判断して、該当するダイヤの数値を返却する
    function dayJudge(year, month, date, day)
    {
        var result = -1; 
        /* ダイヤ情報<例>
           -1: 未設定
            0: 月〜金ダイヤ  //day >= 1 && day <= 5
            1: 土曜日ダイヤ  //day == 6
            2: 日曜日ダイヤ  //day == 7
            3: 祝日ダイヤ
            4: 1月1日ダイヤ
            5: 1月2日3日ダイヤ
            6: 1月4日ダイヤ
            7: xxxダイヤ
        */
    
        //月〜金ダイヤ
        if (day >= 1 && day <= 5) result = 0;
        //土曜日ダイヤ
        if (day == 6) result = 1;
        //日曜日ダイヤ
        if (day == 7) result = 2;
        
        //祝日ダイヤ
        if (year == 2013 && month == 1 && date == 1) result = 3;
        if (year == 2013 && month == 10 && date == 14) result = 3;
        if (year == 2013 && month == 11 && date == 4) result = 3;
        if (year == 2013 && month == 12 && date == 23) result = 3;
        if (year == 2014 && month == 1 && date == 1) result = 3;
        if (year == 2014 && month == 1 && date == 13) result = 3;
        if (year == 2014 && month == 2 && date == 11) result = 3;
        if (year == 2014 && month == 3 && date == 21) result = 3;
        if (year == 2014 && month == 4 && date == 29) result = 3;
        if (year == 2014 && month == 5 && date == 5) result = 3;
        if (year == 2014 && month == 7 && date == 21) result = 3;
        if (year == 2014 && month == 9 && date == 15) result = 3;
        if (year == 2014 && month == 9 && date == 23) result = 3;
        if (year == 2014 && month == 10 && date == 12) result = 3;
        if (year == 2014 && month == 11 && date == 3) result = 3;
        if (year == 2014 && month == 11 && date == 24) result = 3;
        if (year == 2014 && month == 12 && date == 23) result = 3;
        if (year == 2015 && month == 1 && date == 1) result = 3;
        if (year == 2015 && month == 1 && date == 12) result = 3;
        if (year == 2015 && month == 2 && date == 11) result = 3;
        if (year == 2015 && month == 3 && date == 21) result = 3;
    
        //正月ダイヤ(年は問わず)
        if (month == 1 && date == 1) result = 4;
        if (month == 1 && (date == 2 || date == 3)) result = 5;
        if (month == 1 && date == 4) result = 6;
    
        //以降、必要によりif文を追加してダイヤを示す数値を設定する
        //if (...) result = xx;
    
        return result;
    }
    

    if文のelseは不要です。優先するダイヤ設定を後方に書くことで、resultを上書きしていきます。

  3. @sembokulove

    Questioner

    @nak435さん、ありがとうございます。
    新たな知見が増えました。
    ただ問題なのは、月が変わった際に、挙動に異常が出ないかどうかです。

  4. ただ問題なのは、月が変わった際に、挙動に異常が出ないかどうかです。

    上に例示したコードでを判断しているのは、正月祝日だけで(祝日も判断していますが)、挙動に変化はないです。
    何を心配をされていますか? もう少し具体的に示せないでしょうか?

  5. @sembokulove

    Questioner

    お返事が遅くなり申し訳ございません。
    以前、別サイトで質問したところ、
    以下のようなご返答をいただきました。
    その時は5月でしたが、5月の時はうまく挙動しました。
    ところが月が替わり、6月に入って挙動がおかしくなりました。
    このようなことがあるため、月が替わった時の動作を少し憂慮しております。
    以下は、以前別のサイトでご返答いただいたjs文です。

    const diagram = {
    A: 1, //Aダイヤ
    B: 2, //Bダイヤ
    C: 3, //Cダイヤ
    WeekDay: 4, //平日ダイヤ
    Holiday: 5, //休日ダイヤ
    }
    
    //ダイヤを判定する
    function dayJudge(year, month, date, day)
    {
    //フラグ(初期値:平日ダイヤ)
    var diagramFlag = diagram.WeekDay;
    
    //土日判定
    if(day == 0 || day == 6) {
    diagramFlag = diagram.Holiday;
    }
    
    //特別な日
    if(month == 5 && date == 16) {
    diagramFlag = diagram.A;
    } 
    else if(month == 1 && date == 2) {
    diagramFlag = diagram.B;
    } 
    else if(month == 1 && date == 2) {
    diagramFlag = diagram.C;
    }
    return diagramFlag;
    }
    
  6. 上のコードで5月を判断しているのは、21行目の5月16日をAダイヤと判定しているところだけ。
    他の月では、24行目の1月2日をBダイヤと判定しているところ。その2箇所のみ。
    それ以外は、平日か休日ダイヤのどちらか。
    Cダイヤと判定されることは無いです(27行目はコード誤りと思われる)。

    その時は5月でしたが、5月の時はうまく挙動しました。
    ところが月が替わり、6月に入って挙動がおかしくなりました。

    6月に入って挙動が変わるような箇所は見当たりませんが、具体的に示せないでしょうか?
    「m月d日w曜日のXダイヤ判定が、6月に入って、Yダイヤ判定に変わってしまった」とか・・・

  7. @sembokulove

    Questioner

    ご返信が遅れ大変申し訳ございません。
    僕が参照していたのは、こちらのhpです。
    http://r113.web.fc2.com/p/viewer/jrw-hokuriku-20150314/index.html
    をもとに、改造していただいております。
    話が横道にそれるかもしれないのですが、
    このhpのソースの、

    <script type="text/javascript" src="../diaTypeJudge.js" charset="UTF-8"></script>
    
    

    の部分の、diatypejuge.jsの部分のソースがあり、それを改変したのが
    以下のjavascript文となります。

    //今日が平日ダイヤか休日ダイヤか
    function judgeDiaDay()
    {
    	
    	setYear = nowYear; //年
    	setMonth = nowMonth; //月
    	setDate = nowDate; //日
    	setDay = nowDay; //曜日
    	
    	//3時より前なら前日扱いにする
    	if(HHMMSSToSecond(nowHour, nowMinute, nowSecond) < dayChangeTime)
    	{
    		nowDateSet.setDate(nowDateSet.getDate()-1);
    		
    		setYear = nowDateSet.getYear(); //年
    		setMonth = nowDateSet.getMonth() + 1; //月
    		setDate = nowDateSet.getDate(); //日
    		setDay = nowDateSet.getDay(); //曜日
    		
    	}
    	
    	if(setYear < 2000)  setYear += 1900; //年の補正、1900プラスしとかないといけない場合があるため
    	
    	//平日ダイヤか祝日ダイヤの判定
    	if(dayJudge(setYear, setMonth, setDate, setDay))
    	{
    		//表示させる欄が存在すれば、表示させる
    		if(document.getElementById("todayDiaDaySpan") != null)
    		{
    			document.getElementById("todayDiaDaySpan").innerHTML = " 平日ダイヤ ";
    			document.getElementById("todayDiaDaySpan").style.backgroundColor = "#fcf";
    		}
    		DiaDay = 0;
    	}
    	else if((document.getElementById("todayDiaDaySpan") != null))
    	{
    		//表示させる欄が存在すれば、表示させる
    		if(document.getElementById("todayDiaDaySpan") != null)
    		{
    			document.getElementById("todayDiaDaySpan").innerHTML = "土・休日ダイヤ";
    			document.getElementById("todayDiaDaySpan").style.backgroundColor = "#9ff";
    		}
        	DiaDay = 1;
    	}
    	else if((document.getElementById("todayDiaDaySpan") != null))
    	{
    		//表示させる欄が存在すれば、表示させる
    		if(document.getElementById("todayDiaDaySpan") != null)
    		{
    			document.getElementById("todayDiaDaySpan").innerHTML = "10月9・12・31日・11月3・21・24日ダイヤ";
    			document.getElementById("todayDiaDaySpan").style.backgroundColor = "#ff0";
    		}
    		DiaDay = 2;
    	}
    	else ((document.getElementById("todayDiaDaySpan") != null))
    	{
    		//表示させる欄が存在すれば、表示させる
    		if(document.getElementById("todayDiaDaySpan") != null)
    		{
    			document.getElementById("todayDiaDaySpan").innerHTML = "10月12日・11月3・24日ダイヤ";
    			document.getElementById("todayDiaDaySpan").style.backgroundColor = "#0f0";
    		}
    		DiaDay = 3;
    	}					
    }
    
    
    
    //各列車が本日運転する列車なのかそうでないのかを判定する
    //引数はその列車の運転日情報 例:平日 全日 土・休日
    function judgeTrainRunningDay(value)
    {
    	if(value == "全日")
    		return true;
    		
    	//平日ダイヤ
    	else if(value == "平日" && DiaDay == 0)
    		return true;
    	else if(value == "土曜・休日運休" && DiaDay == 0)
    		return true;
    	else if(value == "毎日運転" && DiaDay == 0)
    		return true;
    		
    	//土・休日ダイヤ
    	else if(value == "休日" && DiaDay == 1)
    		return true;
    	else if(value == "土休日" && DiaDay == 1)
    		return true;
    	else if(value == "土・休日" && DiaDay == 1)
    		return true;
    	else if(value == "土曜・休日運転" && DiaDay == 1)
    		return true;
    	else if(value == "毎日運転" && DiaDay == 1)
    		return true;
    		
    	//10月9・12・31日・11月3・21・24日ダイヤ
    	else if(value == "10月9・12・31日・11月3・21・24日運転" && DiaDay == 2)
    		return true;
    	else if(value == "10月12日・11月3・24日運転" && DiaDay == 2)
    		return true;
    		
    	//10月12日・11月3・24日ダイヤ
        else if(value == "10月12日・11月3・24日運転" && DiaDay == 3)
    		return true;
    	
    	else
    		return false;
    	
    }
    
    
    //平日ダイヤと土・休日ダイヤの入れ替え
    function changeDiaType()
    {
    	if(!DiaDay == 3)
    	{
    		document.getElementById("todayDiaDaySpan").innerHTML = "10月12日・11月3・24日ダイヤ";
    		document.getElementById("todayDiaDaySpan").style.backgroundColor = "#0f0";
    		DiaDay = 3;
    	}
    	else if(!DiaDay == 2)
    	{
    	    document.getElementById("todayDiaDaySpan").innerHTML = "10月9・12・31日・11月3・21・24日ダイヤ";
    		document.getElementById("todayDiaDaySpan").style.backgroundColor = "#ff0";
    		DiaDay = 2;
    	}
    	else if(!DiaDay == 1)
    	{
    		document.getElementById("todayDiaDaySpan").innerHTML = "土休日ダイヤ";
    		document.getElementById("todayDiaDaySpan").style.backgroundColor = "#fcf";
    		DiaDay = 1;
    	}
    	else
    	{
    		document.getElementById("todayDiaDaySpan").innerHTML = " 平日ダイヤ ";
    		document.getElementById("todayDiaDaySpan").style.backgroundColor = "#9ff";
    		DiaDay = 0;
    	}
    

    このうちのfunction judgeDiaDay()は、先ほどの、
    javascript文、

    //year, month, date, dayを判断して、該当するダイヤの数値を返却する
    function dayJudge(year, month, date, day)
    {
        var result = -1; 
        /* ダイヤ情報<例>
           -1: 未設定
            0: 月〜金ダイヤ  //day >= 1 && day <= 5
            1: 土曜日ダイヤ  //day == 6
            2: 日曜日ダイヤ  //day == 7
            3: 祝日ダイヤ
            4: 1月1日ダイヤ
            5: 1月2日3日ダイヤ
            6: 1月4日ダイヤ
            7: xxxダイヤ
        */
    
        //月〜金ダイヤ
        if (day >= 1 && day <= 5) result = 0;
        //土曜日ダイヤ
        if (day == 6) result = 1;
        //日曜日ダイヤ
        if (day == 7) result = 2;
        
        //祝日ダイヤ
        if (year == 2013 && month == 1 && date == 1) result = 3;
        if (year == 2013 && month == 10 && date == 14) result = 3;
        if (year == 2013 && month == 11 && date == 4) result = 3;
        if (year == 2013 && month == 12 && date == 23) result = 3;
        if (year == 2014 && month == 1 && date == 1) result = 3;
        if (year == 2014 && month == 1 && date == 13) result = 3;
        if (year == 2014 && month == 2 && date == 11) result = 3;
        if (year == 2014 && month == 3 && date == 21) result = 3;
        if (year == 2014 && month == 4 && date == 29) result = 3;
        if (year == 2014 && month == 5 && date == 5) result = 3;
        if (year == 2014 && month == 7 && date == 21) result = 3;
        if (year == 2014 && month == 9 && date == 15) result = 3;
        if (year == 2014 && month == 9 && date == 23) result = 3;
        if (year == 2014 && month == 10 && date == 12) result = 3;
        if (year == 2014 && month == 11 && date == 3) result = 3;
        if (year == 2014 && month == 11 && date == 24) result = 3;
        if (year == 2014 && month == 12 && date == 23) result = 3;
        if (year == 2015 && month == 1 && date == 1) result = 3;
        if (year == 2015 && month == 1 && date == 12) result = 3;
        if (year == 2015 && month == 2 && date == 11) result = 3;
        if (year == 2015 && month == 3 && date == 21) result = 3;
    
        //正月ダイヤ(年は問わず)
        if (month == 1 && date == 1) result = 4;
        if (month == 1 && (date == 2 || date == 3)) result = 5;
        if (month == 1 && date == 4) result = 6;
    
        //以降、必要によりif文を追加してダイヤを示す数値を設定する
        //if (...) result = xx;
    
        return result;
    }
    

    と連動しているものと思われますが、
    残念ながら、function judgeDiaDay()のうちの、最後の部分、

    	else ((document.getElementById("todayDiaDaySpan") != null))
    	{
    		//表示させる欄が存在すれば、表示させる
    		if(document.getElementById("todayDiaDaySpan") != null)
    		{
    			document.getElementById("todayDiaDaySpan").innerHTML = "10月12日・11月3・24日ダイヤ";
    			document.getElementById("todayDiaDaySpan").style.backgroundColor = "#0f0";
    		}
    		DiaDay = 3;
    	}
    

    のところが、ずっと反映しており、これは、

        //if (...) result = xx;
    
        return result;
    

    の部分に書き足して、仮にresult=0としても、1としても、相変わらず、最後の部分を反映します。
    もし可能であれば、例えば、今日の8月15日のダイヤを指定した場合に、
    ページのオープン時から、指定したダイヤ、function judgeDiaDay()の最後の部分を毎回表示するのではなく、途中の部分でも表示が可能な状態にするのと、
    ボタンクリックで、ダイヤの切り替えができるように出来たら幸いですが、
    ボタンクリックまで手が回らなければ、そこは省略していただいてもかまわないです。
    最悪、切り替えボタンをカットすればいいので。

  8. This comment has been deleted for violation of our Terms of Service.
  9. ざっと見た限りではdayJudge関数が何種類かの整数値を返す割には0かそれ以外かしか判定していないですし(おまけに平日で0を返すなら真偽判定が逆),

    else if((document.getElementById("todayDiaDaySpan") != null))
    

    複数あるこの判定が何を意図しているのか不明です.
    この絡みで分岐が意味をなさなくなっていると思われます.

    フローチャートがちゃんとかけてればこのようなちぐはぐな設計はしないでしょうから,中途半端に改造したためにどこかの文を壊したか,関数の役割の把握ができていないか,そもそも設計を理解出来てないと思われます.

    繰り返し投稿して回答がついたところで貴方がきちんと情報を整理できるのかについては現状相当の疑問があります.一度基礎を学習されてみては?

    経験上,すでにあるプログラムの改変って,イチから書くのより大変です.まずロジック理解しないといけませんから……

Your answer might help someone💌