You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将ScheduleController返回数组适配DateTimePicker的disabledTimeIntervals

如何将PHP返回的时间数组转换为Bootstrap DateTimePicker的disabledTimeIntervals格式

我有一个ScheduleController,从schedules表中获取start_time和end_time,代码如下:

$schedules = Schedule::select('start_time', 'end_time')
    ->where('weekday', $request->input('weekday'))
    ->get()
    ->toArray();

$collection = collect($schedules)->map(function ($time) {
    return [date("g:i", strtotime($time['start_time'])), date("g:i", strtotime($time['end_time']))];
})->flatten();

$data = $collection->values()->all();

// $data 输出格式类似:
// ['6:30', '7:30'],
// ['11:30', '12:30']

需要将上述格式转换为Bootstrap DateTimePicker的disabledTimeIntervals要求的格式,示例如下:

// 目标格式
disabledTimeIntervals: [
    [ moment({ hour: 6, minute: 30 }), moment({ hour: 7, minute: 30 }) ],
    [ moment({ hour: 11, minute: 30 }), moment({ hour: 12, minute: 30 }) ]
],

已尝试的方案及问题

1. JavaScript处理方案(多数组失效)

尝试用moment转换时间,但传入多数组时无法禁用对应时间,单数组正常:

const stringToDate = (dateString) => {
    const [hours, minutes] = dateString.split(':');
    return moment().hours(hours).minutes(minutes);
}
const formatDates = datesToFormat => datesToFormat.map(dateString => {
    if (Array.isArray(dateString)) {
        return dateString.map(s => stringToDate(s));
    } else {
        return stringToDate(dateString);
    }
})

let customOptions = {
    format: 'hh:mm A',
    disabledTimeIntervals: [
        // 多数组时失效
        formatDates([ ['6:30', '7:30'], ['11:30', '12:30'] ])
        // 单数组(不嵌套外层[])时正常
        // formatDates(['6:30', '7:30'])
    ],
}

$('.timepicker').datetimepicker(customOptions)

控制台输出显示格式不符合预期。

2. PHP处理方案(无法移除引号和多余逗号)

尝试用PHP直接生成目标格式,但结果存在引号和末尾多余逗号:

$user = User::find(1);
$schedules = Schedule::select('start_time', 'end_time')
    ->whereBelongsTo($user)
    ->where('weekday', 1)
    ->get()
    ->toArray();

$collection = collect($schedules)->map(function ($time) {
    return [date("g:i", strtotime($time['start_time'])), date("g:i", strtotime($time['end_time']))];
});

$data = $collection->values()->all();

// $data 输出:
// [
//   [
//     "6:45",
//     "7:45",
//   ],
//   [
//     "10:30",
//     "11:30",
//   ],
// ]

$carrier = [];

foreach ($data as $key => $a) {
    $detail1 = preg_split('/:/i', $a[0]);
    $detail2 = preg_split('/:/i', $a[1]);

    array_push($carrier, array(str_replace('"', "", 'moment({ hour:'.$detail1[0].', minute:'.$detail1[1].' }), moment({ hour:'.$detail2[0].', minute:'.$detail2[1].' })')));
}

return $carrier;

当前输出结果:

[
  [
    "moment({ hour:6, minute:45 }), moment({ hour:7, minute:45 })",
  ],
  [
    "moment({ hour:10, minute:30 }), moment({ hour:11, minute:30 })",
  ],
]

需要去掉引号和末尾多余逗号,得到目标格式。


解决方案

方案一:修正JavaScript处理逻辑

问题出在disabledTimeIntervals的结构上,原代码将处理后的二维数组又嵌套了一层[],导致变成三维数组。修改后直接将处理后的二维数组赋值给disabledTimeIntervals:

const stringToDate = (dateString) => {
    const [hours, minutes] = dateString.split(':');
    return moment().hours(hours).minutes(minutes);
}

// 专门处理时间区间数组,返回符合要求的二维moment数组
const formatDisabledIntervals = (intervals) => {
    return intervals.map(intervalPair => {
        return intervalPair.map(timeStr => stringToDate(timeStr));
    });
}

// 在Blade中直接将PHP数组转为JSON
const disabledTimePairs = {{ json_encode($data) }};

let customOptions = {
    format: 'hh:mm A',
    disabledTimeIntervals: formatDisabledIntervals(disabledTimePairs)
}

$('.timepicker').datetimepicker(customOptions);

方案二:PHP直接生成符合要求的JS代码字符串

通过PHP解析时间为小时和分钟,直接生成对应的moment代码片段,再在Blade中输出:

$user = User::find(1);
$schedules = Schedule::select('start_time', 'end_time')
    ->whereBelongsTo($user)
    ->where('weekday', 1)
    ->get();

// 生成每个时间区间的moment字符串
$disabledIntervalStrings = $schedules->map(function ($schedule) {
    // 解析start_time的小时和分钟
    $startParsed = date_parse_from_format('H:i:s', $schedule->start_time);
    // 解析end_time的小时和分钟
    $endParsed = date_parse_from_format('H:i:s', $schedule->end_time);
    
    return "[moment({ hour: {$startParsed['hour']}, minute: {$startParsed['minute']} }), moment({ hour: {$endParsed['hour']}, minute: {$endParsed['minute']} })]";
})->implode(',');

在Blade模板中使用:

<script>
let customOptions = {
    format: 'hh:mm A',
    disabledTimeIntervals: [<?= $disabledIntervalStrings ?>]
}
$('.timepicker').datetimepicker(customOptions);
</script>

内容的提问来源于stack exchange,提问作者Lucky Person

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 05:55:14