4
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

【JavaScript】「和暦を西暦に変換」って、もうやめようよ。えっ?無理??

Last updated at Posted at 2020-10-02

「和暦を西暦に変換」って、もうやめようよ。えっ?無理??

👩‍🦰「ところで、あなたのおじいさんは何年生まれですか?」

🤔「昭和12年、、、」

👩‍🦰「西暦だと何年?」

🙄「さぁ?1900年くらいかなぁ?」

👩‍🦰「さすがにそれはないだろ!逆に、西暦1900年って、和暦だと何年になるの?」

😥「ちょっとまって、コード書く」

👩‍🦰(まじか、、、ググればいいのに、、、)

プログラマ泣かせの「和暦」ですが、なくなる気配はありません。あきらめましょう。

和暦を西暦に変換するコードはなら、ググれば転がっていそうですが、そもそも変換って必要なのでしょうか。

ということで、「HTML の select タグに西暦と和暦を併記してで選べばいいじゃん」っていうのを作りましたので、こちらに置いておきます。

解決策(ソリューション)がこちら

こちらが、select タブに西暦と和暦が併記される解決策(ソリューション😜)です。西暦で選びたい人も、和暦で選びたい人も、両方を確認しながら慎重に選びたい人も、みなさん満足いただける仕上がりになっております😁。

使い方1,select タグを準備

まず、HTML に select タグを用意します。
その後、JavaScript で select タグの data アトリビュートをキーにして option タグを挿入する仕組みです。

select タグの data アトリビュートに data-yyyy="2000-1990" と書くと、西暦 2000年から 1990年までの10年分の option タグが追加されます。
または、data-yyyy="-10" と書くと、今年(2020年)から10年前(2010年)までの11項目の option タグが追加されます。
この2つの記述をサポートしています。

HTMLの記述例:

<body>
select タブに和暦を入れる JavaScript サンプル<br/>
<form name="fm">
hu: <select name="hu" data-yyyy="2000-1900"></select><br/>
ji: <select name="ji" data-yyyy="1980-2020"></select><br/>
ko: <select name="ko" data-yyyy="-10"></select><br/>
lp: <select name="lp" data-yyyy="-20"><option selected disabled value="-">--- 西暦(和暦)
    を選択してください↓ ---</option></select><br/>
</form>

<button onclick="alert(
`hu: ${ document.forms.fm.elements.hu.value },
ji: ${ document.forms.fm.elements.ji.value },
ko: ${ document.forms.fm.elements.ko.value },
lp: ${ document.forms.fm.elements.lp.value }`
)">Check</button>
</body>

form タグや、name アトリビュートは、button タグの onclick で内容を確認するために使っています。ここでは本筋ではないので説明を省略させていただきます。「document.forms」ってなに?なひとは forms をご覧ください。

使い方2,西暦+和暦の option を追加

次に、以下の JavaScript のコード(「西暦+和暦」の option を追加する)を起動時に一回だけ実行します。
script タグに書いておけば起動時に一回だけ実行されます。

<script>
/*
使い方:
1,select tag に data アトリビュート属性 data-yyyy を記述する
    例:
            <select data-yyyy="2000-1900"></select>
        or
            <select data-yyyy="-10"></select>

2,以下のコードを実行する(起動時に1回)と option tag が追加される仕組み
3,それだけ
*/
  for ( const el of document.querySelectorAll( 'select' ) )
  {
    if ( ('dataset' in el) == false ) continue
    if ( ('yyyy' in el.dataset) == false ) continue
    const yyyy = el.dataset.yyyy.split( '-' )
    if ( yyyy.length != 2 ) continue

    let last  = parseInt( yyyy[1] )
    if ( isNaN( last ) ) continue

    let start = parseInt( yyyy[0] )
    if ( isNaN( start ) ) {
      start = parseInt( (new Date()).getFullYear() )
      last  = start - last
    }

    const a = ( start > last ? -1 : 1 )
    for ( let y=start ; y != last+a ; y+= a )
    {
      const opt = document.createElement( 'option' )
      opt.setAttribute( 'value', `${ y }` )
      opt.innerText = `${ y }年`

      // 和暦を追加
      for ( const w of [
        [ '令和', 2019, 9999 ], // ←いまのところいつになるかわからないけど、書き換える必要があります
        [ '平成', 1989, 2019 ], // 平成31年
        [ '昭和', 1926, 1989 ], // 昭和64年
        [ '大正', 1912, 1926 ], // 大正15年
        [ '明治', 1868, 1912 ], // 明治45年
      ] )
      {
        if ( w[1] <= y && y <= w[2] )
          opt.innerText += ` (${ w[0] } ${ y - w[1] + 1 }年)`
      }

      el.appendChild( opt )
    }
  }
</script>

難しいことは、なにもしていないので、普通に読んで、メンテできるレベルと思っています。

令和がいつ終わるのかわからないので、仮に 9999 とか入れていますが。ここはメンテが必要って、わかりますよね。<未来の自分に語りかけています。

対応しているのは、明治元年(西暦1868年)までです。明治以前の元号を知りたい方はこちら Wikipedia 元号一覧 をご覧ください。

ちなみに、このサイト↓で minifi したコードも置いておきます。(動作は未確認です😜)
https://javascript-minifier.com/

for(const el of document.querySelectorAll("select")){if("dataset"in el==0)continue;if("yyyy"in el.dataset==0)continue;const e=el.dataset.yyyy.split("-");if(2!=e.length)continue;let t=parseInt(e[1]);if(isNaN(t))continue;let n=parseInt(e[0]);isNaN(n)&&(t=(n=parseInt((new Date).getFullYear()))-t);const l=n>t?-1:1;for(let e=n;e!=t+l;e+=l){const t=document.createElement("option");for(const w of(t.setAttribute("value",`${e}`),t.innerText=`${e}年`,[["令和",2019,9999],["平成",1989,2019],["昭和",1926,1989],["大正",1912,1926],["明治",1868,1912]]))w[1]<=e&&e<=w[2]&&(t.innerText+=` (${w[0]} ${e-w[1]+1}年)`);el.appendChild(t)}}

おまけ(その1)和暦を西暦に変換するコード

↑では使わなかったけど副産物として、和暦を西暦に変換するコードも生まれたので、捨てずに置いておきます。

// 和暦を西暦に変換するコードも置いておきます

function create_WAREKI_to_YEAR_table()
{
    const w_tbl = {}
    const last  = parseInt( (new Date()).getFullYear() )
    for ( let y=1868 ; y <= last ; y++ )
    {
        for ( const w of [
            [ 'R', 2019, 9999 ], // 令和
            [ 'H', 1989, 2019 ], // 平成31年
            [ 'S', 1926, 1989 ], // 昭和64年
            [ 'T', 1912, 1926 ], // 大正15年
            [ 'M', 1868, 1912 ], // 明治45年
        ] )
        {
            if ( w[1] <= y && y <= w[2] )
                w_tbl[ `${ w[0] }${ y - w[1] + 1 }` ] = y
        }
    }
    return w_tbl
}

// 使い方
const wareki = create_WAREKI_to_YEAR_table()

console.log( 'R1 ->',  wareki['R1'] )
console.log( 'R2 ->',  wareki['R2'] )
console.log( 'H1 ->',  wareki['H1'] )
console.log( 'H10 ->', wareki['H10'] )
console.log( 'S1 ->',  wareki['S1'] )
console.log( 'S10 ->', wareki['S10'] )
console.log( 'T1 ->',  wareki['T1'] )
console.log( 'T10 ->', wareki['T10'] )
console.log( 'M1 ->',  wareki['M1'] )
console.log( 'M10 ->', wareki['M10'] )

おまけ(その2)input lint + datalist タブ版

input lint + datalist タブ版も作ったので置いて置きます。
結局は好みの問題だと思うけど、キーボードから入力するのなら、オートコンプリート機能のあるこっちのほうがいいのかな🙄。

それでは、みなさまのプログラミングライフを応援しています😉(なにそれ😁)。

4
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?