タイムズカー予約をスムーズに！ブックマークレットの改訂と改善ポイント

![DALL·E 2025-02-11 09.48.20 - A minimalist, hand-drawn digital illustration of a software developer refining a script on a laptop. The screen displays abstract lines of code, empha_opt.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184128/9ffc456e-1402-313a-8c43-ea4c3dcb5952.jpeg)

## はじめに

[タイムズカー予約のヒヤヒヤ解放: ブックマークレットでの半自動化](https://qiita.com/hann-solo/items/208c893a78342ca4b1c5) で、カーシェア予約を楽にするブックマークレットを作りました。その後、改良を2回実施しました。

- **1回目の改訂:** 入力フォーマットをシンプルにし、エラーチェックを整理
- **2回目の改訂:** 正規表現を導入し、余分な文字を無視できるようにした

この記事では、それぞれの改訂内容を記録します。

---

## 1回目の改訂 – 入力フォーマットの簡略化

### **背景**
当初は `YYYY-MM-DD hh:mm / YYYY-MM-DD hh:mm` という形式で入力する仕様だったが、実際の運用では日をまたぐ予約はほぼないため、**日付を1回だけ入力すればいい仕様に変更**。

### **変更点**
- 入力フォーマットを `YYYY-MM-DD hh:mm / hh:mm` に変更
- 日付が異なる場合の確認ダイアログを削除
- エラーチェックの整理 & エラーメッセージを明確化

### **改善の効果**
✅ 入力の手間が減った
✅ 無駄な確認ダイアログがなくなり、ストレスが減った

ただし、`split()` を使った分割処理のままだったため、
**タブやハイフンなどの余計な文字があるとエラーになる** 問題は未解決。

---

## 2回目の改訂 – 正規表現の導入で入力の柔軟性向上

### **背景**
1回目の改訂では入力がシンプルになったが、**タブやバレット（・）などの余計な文字があるとエラーになった**。また、`split()` による単純な分割では、想定外のフォーマットが入力された場合に正しく処理できないこともあった。

### **変更点**
- 正規表現を導入し、余計な文字を無視しつつ日付と時刻を正しく抽出
  ```js
  s.trim().match(/(\d{4}-\d{2}-\d{2})\s+(\d{1,2}):(\d{2})\s*\/\s*(\d{1,2}):(\d{2})/)
  ```
- フォーマットが間違っていた場合、即エラーを返す処理を追加
- エラーメッセージを明確化し、正しい入力例を提示

### **改善の効果**
✅ 余分な文字が入っていても正しく動作するようになった
✅ エラーメッセージが具体的になり、入力ミスの修正がしやすくなった

### スクリーンショット

![SS 2025-02-11 9.44.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184128/dee2324b-585c-ee4c-f67c-4f22d1a44d81.png)

---

## まとめ

### **改訂の流れ**
1. 入力形式を `YYYY-MM-DD hh:mm / hh:mm` に簡略化（1回目の改訂）
   → 手間を減らし、無駄な確認ダイアログを削除
2. 正規表現で柔軟な入力処理を実装（2回目の改訂）
   → 余分な文字を無視しつつ、確実に日付と時刻を取得

### **最終的な成果**
- **ユーザーの負担が軽減**（より直感的な入力が可能に）
- **ミスが減少**（正規表現による厳密なチェック）
- **コードの可読性と保守性が向上**（単純な `split()` を廃止し、整理された構造に）

細かな改良の積み重ねで、ちょっとづつ使いやすいブックマークレットに進化しています。引き続き、実際の運用での体験を反映して、改善していきます。

---

【関連】
- [タイムズカー予約のヒヤヒヤ解放: ブックマークレットでの半自動化](https://qiita.com/hann-solo/items/208c893a78342ca4b1c5)

---

### **あとがき**
改訂を重ねることで、スクリプトの完成度が高まっていくのは楽しいですね。今後も改善の余地があれば、アップデートしていきたいと思います。

---

## 【ご参考】改訂前・改訂後のコード

スクリプトは以下の順番で記載する。

1. 改訂前（オリジナル）
2. 第1回改訂（入力フォーマットの変更）
3. 第2回改訂（正規表現の導入）






### **1. 改訂前（オリジナル）**
```javascript
javascript:(function(){
    document.getElementById('dateStartSearch').value = '';
    document.getElementById('hourStartSearch').value = '';
    document.getElementById('minuteStartSearch').value = '';
    document.getElementById('dateEndSearch').value = '';
    document.getElementById('hourEndSearch').value = '';
    document.getElementById('minuteEndSearch').value = '';

    var i = prompt('日時を以下のフォーマットで入力：\n"YYYY-MM-DD hh:mm / YYYY-MM-DD hh:mm"', '').split(' / ');
    var sP = i[0].split(' '), eP = i[1].split(' ');
    var sD = sP[0], sT = sP[1].split(':'), eD = eP[0], eT = eP[1].split(':');

    if(sD !== eD && !confirm('開始日と終了日が異なります。これは正しいですか？')) return;

    document.getElementById('dateStartSearch').value = sD + ' 00:00:00.0';
    document.getElementById('hourStartSearch').value = (+sT[0]).toString();
    document.getElementById('minuteStartSearch').value = sT[1];
    document.getElementById('dateEndSearch').value = eD + ' 00:00:00.0';
    document.getElementById('hourEndSearch').value = (+eT[0]).toString();
    document.getElementById('minuteEndSearch').value = eT[1];
})();
```

---

### **2. 第1回改訂**
```javascript
javascript:(function(){
    document.getElementById('dateStartSearch').value = '';
    document.getElementById('hourStartSearch').value = '';
    document.getElementById('minuteStartSearch').value = '';
    document.getElementById('hourEndSearch').value = '';
    document.getElementById('minuteEndSearch').value = '';

    var input = prompt('日時を以下のフォーマットで入力：\n"YYYY-MM-DD hh:mm / hh:mm"', '').trim().split(' / ');
    var startPart = input[0].split(' ');
    var startDate = startPart[0];
    var startTime = startPart[1].split(':');
    var endTime = input[1].split(':');

    document.getElementById('dateStartSearch').value = startDate + ' 00:00:00.0';
    document.getElementById('hourStartSearch').value = (+startTime[0]).toString();
    document.getElementById('minuteStartSearch').value = startTime[1];
    document.getElementById('hourEndSearch').value = (+endTime[0]).toString();
    document.getElementById('minuteEndSearch').value = endTime[1];
})();
```

---

### **3. 第2回改訂（最終版）**
```javascript
javascript:(function(){
    document.getElementById('dateStartSearch').value = '';
    document.getElementById('hourStartSearch').value = '';
    document.getElementById('minuteStartSearch').value = '';
    document.getElementById('hourEndSearch').value = '';
    document.getElementById('minuteEndSearch').value = '';

    var s = prompt('日付を以下のフォーマットで入力：\n"YYYY-MM-DD hh:mm / hh:mm"', '');
    if (!s) return;
    var m = s.trim().match(/(\d{4}-\d{2}-\d{2})\s+(\d{1,2}):(\d{2})\s*\/\s*(\d{1,2}):(\d{2})/);
    if (!m) { alert("入力フォーマットが正しくありません。\n例：2025-02-18 06:45 / 20:00"); return; }

    document.getElementById('dateStartSearch').value = m[1] + ' 00:00:00.0';
    document.getElementById('hourStartSearch').value = parseInt(m[2]).toString();
    document.getElementById('minuteStartSearch').value = m[3];
    document.getElementById('hourEndSearch').value = parseInt(m[4]).toString();
    document.getElementById('minuteEndSearch').value = m[5];
})();
```

---

:::note
この記事は [タイムズカー予約をスムーズに！ブックマークレットの改訂と改善ポイント - MXT Forest](https://silme.zelo-loop.com/mxt/Notes/%E3%82%BF%E3%82%A4%E3%83%A0%E3%82%BA%E3%82%AB%E3%83%BC%E4%BA%88%E7%B4%84%E3%82%92%E3%82%B9%E3%83%A0%E3%83%BC%E3%82%BA%E3%81%AB%EF%BC%81%E3%83%96%E3%83%83%E3%82%AF%E3%83%9E%E3%83%BC%E3%82%AF%E3%83%AC%E3%83%83%E3%83%88%E3%81%AE%E6%94%B9%E8%A8%82%E3%81%A8%E6%94%B9%E5%96%84%E3%83%9D%E3%82%A4%E3%83%B3%E3%83%88) に基づいています。最新の情報や更新は、元の記事で確認してください。
:::