日付選択コンポーネントのデフォルト設定と時間範囲の制御

日付選択コンポーネントの警告と解決策

**警告:** [antdv: DatePicker] `value` が無効な moment 時間を提供しています。空の値を設定したい場合は、代わりに `null` を使用してください。

**原因:** a-range-picker コンポーネントが期待する value は moment オブジェクト配列 [ "2024-07-10T07:46:14.632Z", "2024-07-11T07:46:14.632Z" ] であり、文字列配列 ['2020-10-10 10:10:10', '2020-10-20 10:10:10'] ではありません。バインドしている dateList にフォーマットされた文字列ではなく、moment オブジェクトを格納する必要があります。

デフォルト日付の設定

**修正前:** dateList: [moment().subtract(1, 'd').format('YYYY-MM-DD HH'), moment().format('YYYY-MM-DD HH')],

**修正後:** dateList: [moment().subtract(1, 'd'), moment()]

基本的な使用方法

<template>
  <a-range-picker
    v-model="dateRange"
    style="width:466px;"
    :allow-clear="false"
    :show-time="{ format: 'YYYY-MM-DD HH:mm:ss' }"
    format="YYYY-MM-DD HH:mm:ss"
    :placeholder="['開始日時', '終了日時']"
    @ok="handleDateConfirm"
  />
</template>

<script>
import moment from 'moment';

export default {
  data() {
    return {
      searchParams: {
        startDate: null,
        endDate: null
      },
      dateRange: [moment().subtract(1, 'd'), moment()]
    };
  },
  methods: {
    moment,
    // 日時確認処理
    handleDateConfirm(selectedDates) {
      this.searchParams.startDate = null;
      this.searchParams.endDate = null;
      
      if (selectedDates && selectedDates.length === 2) {
        const timeDiff = Date.parse(selectedDates[1]) - Date.parse(selectedDates[0]);
        
        if (timeDiff > (1000 * 60 * 60 * 24 * 1)) {
          this.$message.warning('時間範囲は1日を超えることはできません');
          this.searchParams.startDate = moment(selectedDates[0]).format('YYYY-MM-DD HH');
          this.searchParams.endDate = moment(selectedDates[0]).add(1, 'd').format('YYYY-MM-DD HH');
          this.dateRange = [moment(selectedDates[0]), moment(selectedDates[0]).add(1, 'd')];
        } else {
          this.searchParams.startDate = moment(selectedDates[0]).format('YYYY-MM-DD HH');
          this.searchParams.endDate = moment(selectedDates[1]).format('YYYY-MM-DD HH');
        }
      }
      
      console.log('検索パラメータ:', this.searchParams, '選択日時:', selectedDates);
    }
  }
};
</script>

カスタム時間範囲の設定

<template>
  <div ref="chartContainer">
    <a-range-picker
      style="width:370px;"
      :default-value="defaultDateTimeRange"
      :allow-clear="false"
      :get-calendar-container="() => $refs.chartContainer"
      :ranges="timeRanges"
      :show-time="{ format: 'HH:mm:ss' }"
      format="YYYY-MM-DD HH:mm:ss"
      :placeholder="['開始時間', '終了時間']"
      @change="handleDateChange"
      @ok="handleDateConfirm"
    />
  </div>
</template>

<script>
import moment from 'moment';

export default {
  data() {
    return {
      defaultDateTimeRange: [
        moment().subtract(1, 'd').startOf('day'), 
        moment().endOf('day')
      ],
      timeRanges: {
        '最近15分': [moment().subtract(15, 'minutes'), moment()],
        '最近30分': [moment().subtract(30, 'minutes'), moment()],
        '最近1時間': [moment().subtract(1, 'hours'), moment()],
        '昨日': [
          moment().subtract(1, 'days').startOf('day'), 
          moment().subtract(1, 'days').endOf('day')
        ],
        '今日': [moment().startOf('day'), moment().endOf('day')],
        '過去7日間': [moment().subtract(7, 'd'), moment()],
        '過去1ヶ月': [moment().subtract(1, 'month'), moment()]
      }
    };
  },
  methods: {
    moment,
    // 日時変更処理
    handleDateChange(dates) {
      // 必要に応じて日時変更時の処理を実装
    },
    // 日時確認処理
    handleDateConfirm(selectedDates) {
      if (selectedDates && selectedDates.length === 2) {
        this.defaultDateTimeRange = [
          moment(selectedDates[0]).format('YYYY-MM-DD HH:mm:ss'),
          moment(selectedDates[1]).format('YYYY-MM-DD HH:mm:ss')
        ];
      }
    }
  }
};
</script>

<style lang="less" scoped>
  /deep/.ant-calendar-picker-container {
    .ant-tag-blue {
      color: #fff !important;
      background-color: #007d7b !important;
    }
  }
</style>

カスタム日付形式の設定

1. デフォルトの日付形式のカスタマイズ

<div ref="datePickerContainer">
  <a-range-picker
    v-model="customDateRange"
    style="width:466px;"
    :allow-clear="false"
    :get-calendar-container="() => $refs.datePickerContainer"
    :show-time="{ format: 'HH' }"
    format="YYYY-MM-DD HH時"
    :placeholder="['開始日時', '終了日時']"
    @ok="handleCustomDateConfirm"
  />
</div>

2. 擬似要素を使用したコンテンツの追加

::v-deep .ant-calendar-time-picker-select li::after {
  display: inline-block;
  content: ' 時';
}

日付範囲のカスタマイズ

日付範囲をカスタマイズするには、コンポーネントのプロパティを適切に設定します。特定の日付範囲のみを選択可能にする場合は、disabled-date 関数を実装します。

el-date-picker での年月日時分秒の制限

Vue3 で el-date-picker を使用し、現在時刻以前のみを選択可能にする場合です。el-date-picker ドキュメントでは年月日の制限のみが提供されているため、時分秒の制限は自分で実装する必要があります。

<el-date-picker 
  v-model="selectedDateTime" 
  type="datetime" 
  format="YYYY-MM-DD HH:mm:ss" 
  value-format="YYYY-MM-DD HH:mm:ss"
  :disabled-date="disableFutureDates"
  :disabled-hours="disableFutureHours"
  :disabled-minutes="disableFutureMinutes"
  :disabled-seconds="disableFutureSeconds"
>
</el-date-picker>

<script setup>
import { ref } from 'vue';

const selectedDateTime = ref(undefined);

// 未来の日付を無効化
const disableFutureDates = (time) => {
  return time.getTime() > Date.now();
};

// 未来の時間を無効化
const disableFutureHours = () => {
  const currentHour = new Date().getHours();
  return Array.from({ length: 24 }, (_, i) => i).filter(hour => hour > currentHour);
};

// 現在時間以降の分を無効化
const disableFutureMinutes = (hour) => {
  const currentMinute = new Date().getMinutes();
  if (hour === new Date().getHours()) {
    return Array.from({ length: 60 }, (_, i) => i).filter(minute => minute > currentMinute);
  }
  return [];
};

// 現在時間以降の秒を無効化
const disableFutureSeconds = (hour, minute) => {
  const currentSecond = new Date().getSeconds();
  if (hour === new Date().getHours() && minute === new Date().getMinutes()) {
    return Array.from({ length: 60 }, (_, i) => i).filter(second => second > currentSecond);
  }
  return [];
};
</script>

タグ: 日付選択 時間範囲 moment.js ant-design Vue

7月10日 00:14 投稿