業務文書や正式な報告書では、「2017-08-08」のような標準的な日付形式を「二〇一七年八月八日」といった漢字表記に変換する要件がよく存在します。一見複雑に思えるこの処理ですが、文字列操作と数値演算を巧みに組み合わせることで非常に簡潔に実現できます。以下ではそのアルゴリズムの構造を解説し、LotusScriptによる実装例をもとにJavaScriptでの同等機能を再設計します。
まず、入力された日付文字列から年、月、日を個別に抽出します。
const date = new Date(input.replace(/-/g, '/'));
const yearStr = date.getFullYear().toString();
const month = date.getMonth() + 1;
const day = date.getDate();
次に、西暦年を一文字ずつ漢数字に変換します。ここで用いられるのは「マッピング文字列+位置指定抽出」という技法です。
let result = '';
for (let i = 0; i < 4; i++) {
const digit = parseInt(yearStr.charAt(i));
result += '〇一二三四五六七八九'.charAt(digit);
}
result += '年';
文字列'〇一二三四五六七八九'は、インデックス0~9に対応する漢数字を保持しており、charAt()で直接アクセスすることで配列対応や条件分岐を回避しています。
月の変換では、1~12までの値を固定幅2文字の文字列から切り出す方式を採用します。
const monthKanji = '一 二 三 四 五 六 七 八 九 十 十一十二';
result += monthKanji.substr((month - 1) * 2, 2).trim() + '月';
各項目を半角スペースで2文字分確保することで、substr()による等幅抽出が可能になり、その後のtrim()で不要な空白を除去しています。
日の変換は十位と一位に分けて処理します。1~31までの範囲に対応するため、十位部分には「」「十」「二十」「三十」のパターンを予め連結した文字列を使用します。
const tens = ' 十二十三十'; // インデックス: 0→"", 1→"十", 2→"二十", 3→"三十"
const units = ' 一二三四五六七八九'; // インデックス0は空(使用しない)、1~9に対応
const tenPlace = Math.floor(day / 10);
const unitPlace = day % 10;
result += tens.substr(tenPlace * 2, 2).trim();
if (day !== 10 && unitPlace !== 0) { // 10の場合は"十"のみ
result += units.substr(unitPlace, 1);
}
result += '日';
最終的に得られる結果は、「二〇一七年八月八日」のように自然な日本語表記となります。この手法はループと文字列操作に集中しており、多数のif文やswitch文を避けているため、保守性と実行効率の両面で優れた設計と言えます。