Filament 日期时间选择器(DatePicker / DateTimePicker / TimePicker)完整实战指南
发布时间:2026/9/11 16:42:48 作者:尧图编辑部 阅读量:1,286
完整实战指南)
Filament 日期时间选择器DatePicker / DateTimePicker / TimePicker完整实战指南【免费下载链接】filamentA powerful open-source UI framework for Laravel • Build and ship apps admin panels fast with Livewire项目地址: https://gitcode.com/GitHub_Trending/fi/filament日期与时间选择是后台管理系统中最常用的表单控件之一。Filament Forms 包提供了DatePicker、DateTimePicker与TimePicker三个组件用于在表单中交互式地选择日期、时间或两者的组合。本指南以 Filament Forms 的官方文档 08-date-time-picker.md 为核心结合仓库源码DateTimePicker.php与测试用例DateTimePickerTest.php系统讲解存储格式、时区处理、原生/JavaScript 双渲染模式、校验规则等核心能力。读完本文你将掌握如何在 Filament 面板中构建贴合业务需求、可国际化、可自定义交互细节的日期时间表单字段。三种组件与基本用法Filament 把日期时间选择拆分为三个语义清晰的组件类它们共同继承自同一个基类DateTimePickerDatePicker只选择日期如出生日期、发布日期DateTimePicker同时选择日期与时间如文章发布时间published_atTimePicker只选择时间如闹钟时刻、预约时刻。基本用法非常简单在表单 schema 中直接调用make()并绑定模型字段名即可use Filament\Forms\Components\DatePicker; use Filament\Forms\Components\DateTimePicker; use Filament\Forms\Components\TimePicker; DateTimePicker::make(published_at) DatePicker::make(date_of_birth) TimePicker::make(alarm_at)从源码看三个组件的关系极为简洁DatePicker.php 仅重写了hasTime()返回falseTimePicker.php 仅重写了hasDate()返回false其余全部能力都来自DateTimePicker基类。这意味着本文介绍的所有方法对三者都适用组件会根据是否有日期/是否有时间/是否有秒自动推导渲染形态。自定义存储格式format()默认情况下日期时间字段以 Laravel 数据库约定的Y-m-d、Y-m-d H:i、Y-m-d H:i:s格式存储。若你的数据库列或业务层需要其他格式例如欧洲常见的d/m/Y可通过format()方法自定义该方法接受 PHP 日期格式令牌参见 PHP date formatting tokensuse Filament\Forms\Components\DatePicker; DatePicker::make(date_of_birth) -format(d/m/Y)format()既支持静态字符串也支持传入闭包动态计算闭包内可以注入各种实用工具如组件实例、Livewire 组件、记录等作为参数例如根据当前操作create/edit返回不同的存储格式。从源码实现看getFormat()会按以下规则推导默认存储格式DateTimePicker.php场景默认存储格式仅日期DatePickerY-m-d日期 时间无秒Y-m-d H:i日期 时间含秒Y-m-d H:i:s仅时间无秒H:i仅时间含秒H:i:s而getInternalFormat()L333-L348则控制组件内部与状态绑定的中间格式使用非原生JavaScript选择器时固定为Y-m-d H:i:s使用原生选择器时则按是否有日期/时间/秒生成对应的中间格式。关闭秒输入seconds()时间类字段默认包含秒的输入。若业务只需要精确到分钟例如预约时间可通过seconds(false)隐藏秒输入use Filament\Forms\Components\DateTimePicker; DateTimePicker::make(published_at) -seconds(false)seconds()同样支持传入闭包做条件判断。关闭秒输入后存储与显示格式都会自动去掉:s部分见上文默认格式表。与该能力相关的还有两个便捷方法date()与time()可分别控制字段是否包含日期部分、时间部分。例如DateTimePicker::make(dt)-date(false)-seconds(false)等价于一个仅时分的选择器该用法在 DateTimePickerTest.php 的测试中有覆盖。源码中旧版方法withoutDate()、withoutTime()、withoutSeconds()已标记为deprecated建议改用新的date()、time()、seconds()。多时区支持timezone() 与 FilamentTimezone若应用面向多时区用户例如跨国团队可让用户在自己的时区内操作日期再按应用时区存储。使用timezone()指定字段所使用的时区use Filament\Forms\Components\DateTimePicker; DateTimePicker::make(published_at) -timezone(America/New_York)其工作流程为字段加载时存储值会转换到指定时区显示表单保存时再转换回应用配置的时区config(app.timezone)落库。这一转换由状态转换器 DateTimeStateCast.php 完成——get()时将状态shiftTimezone()到字段时区再setTimezone()回应用时区set()时则反方向解析并格式化从而保证用户看到本地时间、数据库存应用时区。如果不为组件显式传入timezone()则使用 Filament 的默认时区。可在服务提供者如AppServiceProvider的boot()中通过FilamentTimezone门面全局设置use Filament\Support\Facades\FilamentTimezone; public function boot(): void { FilamentTimezone::set(America/New_York); }该默认时区同样被 Filament 中其他涉及时区的位置使用。底层实现位于 TimezoneManager.php其get()在未设置时回退到config(app.timezone)。需要特别注意文档中的警告Filament 的默认时区只在字段包含时间部分时生效。如果字段仅存储日期DatePicker而非DateTimePicker/TimePicker时区将不会被应用以避免纯日期在无时间的情况下发生时区偏移。从源码可以印证这一点——getTimezone()的实现为显式设置的timezone()优先否则含时间字段用 Filament 默认时区、纯日期字段回退到config(app.timezone)DateTimePicker.php。原生与 JavaScript 双渲染模式native(false)默认情况下Filament 使用浏览器原生的 HTML5 日期选择器typedate/typetime/typedatetime-local。如果需要更可定制的界面可使用native(false)启用基于 Alpine.js 构建的 JavaScript 日期选择器use Filament\Forms\Components\DatePicker; DatePicker::make(date_of_birth) -native(false)两种模式在底层渲染上差异明显见 toEmbeddedHtml()原生模式渲染为普通input附加type由getType()推导分别为date/time/datetime-local、min、max、step、list等原生属性直接使用wire:model绑定状态JavaScript 模式通过x-load懒加载date-time-pickerAlpine 组件用x-datadateTimePickerFormComponent({...})传入displayFormat、firstDayOfWeek、locale、shouldCloseOnDateSelection等配置并用$wire.$entangle()双向绑定状态面板内部分别渲染月份/年份选择器、星期表头、日期网格与时分秒数字输入框。文档同样给出了一个使用提示JavaScript 日期选择器无法像原生选择器那样支持完整的键盘输入如果用户依赖全键盘操作应保留原生模式。自定义显示格式displayFormat()显示格式与存储格式可以完全独立。displayFormat()用于控制字段在界面上展示的格式同样接受 PHP 日期格式令牌use Filament\Forms\Components\DatePicker; DatePicker::make(date_of_birth) -native(false) -displayFormat(d/m/Y)若未显式指定getDisplayFormat()会按默认规则返回L561-L582即下文表格中的默认显示格式场景默认显示格式仅日期M j, Y如Jan 5, 2026日期 时间无秒M j, Y H:i日期 时间含秒M j, Y H:i:s仅时间无秒H:i仅时间含秒H:i:s这些默认值本身也开放了定制入口defaultDateDisplayFormat()、defaultDateTimeDisplayFormat()、defaultDateTimeWithSecondsDisplayFormat()、defaultTimeDisplayFormat()、defaultTimeWithSecondsDisplayFormat()可分别覆盖。渲染语言locale()当需要与应用默认config(app.locale)不同的语言渲染时可使用locale()指定典型场景是月份名与星期名需要本地化use Filament\Forms\Components\DatePicker; DatePicker::make(date_of_birth) -native(false) -displayFormat(d F Y) -locale(fr)从源码看getLocale()在未显式设置时回退到config(app.locale)L737-L740。仓库测试中也覆盖了locale(fr)与闭包形式locale(fn () ja)见 DateTimePickerTest.php。时间输入步进hoursStep() / minutesStep() / secondsStep()可分别定制时、分、秒输入框的增减步长例如每 2 小时、每 15 分钟、每 10 秒use Filament\Forms\Components\DateTimePicker; DateTimePicker::make(published_at) -native(false) -hoursStep(2) -minutesStep(15) -secondsStep(10)在原生模式下getStep()会把这些步长换算成 HTMLstep属性对应的秒数hoursStep * 3600、minutesStep * 60未设置时默认步长为 1L777-L812。仓库测试对静态值与闭包形式均有断言L976-L1039。自定义一周起始日firstDayOfWeek()不同国家/地区一周的第一天并不相同。firstDayOfWeek()可定制日历面板的周起始日接受 0~7 的整数值其中 1 代表周一7 或 0 代表周日use Filament\Forms\Components\DateTimePicker; DateTimePicker::make(published_at) -native(false) -firstDayOfWeek(7)同时提供了两个更语义化的便捷方法DateTimePicker::make(published_at) -native(false) -weekStartsOnMonday() DateTimePicker::make(published_at) -native(false) -weekStartsOnSunday()源码细节firstDayOfWeek()会校验取值范围超出 0~7 的非法值如10、-1会被置为nullL378-L387而getFirstDayOfWeek()在未设置时默认返回 1周一L663-L666。这些边界行为在 DateTimePickerTest.php 中有明确测试。禁用指定日期disabledDates()可通过日期数组禁止用户选择特定日期例如节假日、已占用的档期use Filament\Forms\Components\DateTimePicker; DateTimePicker::make(date) -native(false) -disabledDates([2000-01-03, 2000-01-15, 2000-01-20])在 JavaScript 模式下禁用日期列表会通过隐藏输入传给 Alpine 组件渲染时对禁用日添加fi-disabled类并阻止点击选择DateTimePicker.php 与 L268。测试中同样验证了闭包形式disabledDates(fn () [2025-12-25])L335。选择后自动关闭面板closeOnDateSelection()默认选择日期后面板保持打开便于继续选时间可通过closeOnDateSelection()改为选择即关闭use Filament\Forms\Components\DateTimePicker; DateTimePicker::make(date) -native(false) -closeOnDateSelection()也可传入布尔值做条件控制例如与功能开关联动DateTimePicker::make(date) -native(false) -closeOnDateSelection(FeatureFlag::active())基于 datalist 的自动补全若仍使用原生选择器可通过datalist()为输入提供浏览器原生的自动补全候选值对应 HTML 的datalist元素。典型场景是为时间选择器提供预约时段列表use Filament\Forms\Components\TimePicker; TimePicker::make(appointment_at) -datalist([ 09:00, 09:30, 10:00, 10:30, 11:00, 11:30, 12:00, ])注意datalist 中的选项只是建议用户仍可输入任意值。若需要严格限制用户只能从预定义集合中选择应改用下拉选择字段 Select。从源码看datalist 选项会被渲染为datalist id{id}-list并以list属性关联到输入框DateTimePicker.php。聚焦默认日历日期defaultFocusedDate()当字段为空时打开日历面板默认聚焦今天。若希望打开时聚焦到某个特定日期例如与placeholder提示一致的本月第一天可用defaultFocusedDate()use Filament\Forms\Components\DatePicker; DatePicker::make(custom_starts_at) -native(false) -placeholder(now()-startOfMonth()) -defaultFocusedDate(now()-startOfMonth())该日期同时支持CarbonInterface与字符串字符串会优先按存储格式解析、解析失败再回退到Carbon::parse()L701-L722。添加前后缀文本与图标文本前后缀prefix() / suffix()可在输入框前后放置说明性文本例如开始时间于午夜结束use Filament\Forms\Components\DatePicker; DatePicker::make(date) -prefix(Starts) -suffix(at midnight)图标前后缀prefixIcon() / suffixIcon()也可以用图标作为前后缀图标枚举来自Filament\Support\Icons\Heroicon图标体系详见图标文档use Filament\Forms\Components\TimePicker; use Filament\Support\Icons\Heroicon; TimePicker::make(at) -prefixIcon(Heroicon::Play)定制前后缀图标颜色前后缀图标默认为灰色可通过prefixIconColor()/suffixIconColor()设置颜色use Filament\Forms\Components\TimePicker; use Filament\Support\Icons\Heroicon; TimePicker::make(at) -prefixIcon(Heroicon::CheckCircle) -prefixIconColor(success)与prefix()、suffix()一样这些方法也都支持传入闭包动态求值。需要说明的是icon()旧方法已标记为deprecated官方建议改用suffixIcon(Heroicon::Calendar)L396-L406。只读模式readonly()readonly()可让字段只读它与禁用字段disabled()是两种不同的能力use Filament\Forms\Components\DatePicker; DatePicker::make(date_of_birth) -readonly()请特别注意readonly()只对原生日期选择器生效若使用 JavaScript 选择器需要改用disabled()相关概念可参考表单字段总览中的禁用字段与防止字段被保存章节。与disabled()相比readonly()存在三点差异提交表单时字段值仍会发送到服务器且可被浏览器控制台或 JavaScript 篡改如需阻止可配合saved(false)使用不会产生降低透明度之类的样式变化字段仍可被聚焦。同样支持传入布尔值做条件控制DatePicker::make(date_of_birth) -readOnly(FeatureFlag::active())日期时间校验minDate() 与 maxDate()除表单校验通用规则外日期时间选择器还提供两条专属校验规则。minDate()与maxDate()可限制可选日期的最小/最大范围接受DateTime实例如Carbon或字符串use Filament\Forms\Components\DatePicker; DatePicker::make(date_of_birth) -native(false) -minDate(now()-subYears(150)) -maxDate(now())从源码可以确认其底层校验实现minDate()注册after_or_equal:{date}规则maxDate()注册before_or_equal:{date}规则且只有当对应日期非空时才生效L408-L428。当传入闭包且闭包返回null时该校验规则不会应用。此外组件在setUp()中还会根据是否包含日期部分自动注册date规则L87-L95。在原生模式下minDate/maxDate还会直接映射为input的min/maxHTML 属性纯日期字段会被转成Y-m-d字符串让浏览器端与服务器端双重把关L170-L171。结语何时用哪种配置至此Filament 日期时间选择器的核心能力已经全部覆盖。结合本文内容可以形成一套实用的选型思路默认优先使用原生模式零依赖、支持完整键盘输入适合绝大多数后台表单需要更精致的日历界面或本地化能力时切换到native(false)配合displayFormat()、locale()、firstDayOfWeek()、disabledDates()、closeOnDateSelection()即可定制出符合业务与地区习惯的选择器跨国多时区场景为字段设置timezone()或在服务提供者中全局配置FilamentTimezone::set()并牢记纯日期字段不应用默认时区的约束约束输入范围minDate()/maxDate()同时作用于服务端校验与原生输入属性是数据完整性的第一道防线。文中所有方法format、seconds、timezone、native、displayFormat、locale、hoursStep、minutesStep、secondsStep、firstDayOfWeek、disabledDates、closeOnDateSelection、datalist、defaultFocusedDate、prefix、suffix、readonly、minDate、maxDate等均支持静态值或闭包动态求值两种形式闭包中可注入组件实例、Livewire 组件、当前记录等实用工具这一设计让日期时间选择器可以随操作场景、用户权限或功能开关动态变化。仓库中的测试套件DateTimePickerTest.php、DatePickerTest.php对这些行为均有系统性覆盖可作为进一步研究实现细节的入口。【免费下载链接】filamentA powerful open-source UI framework for Laravel • Build and ship apps admin panels fast with Livewire项目地址: https://gitcode.com/GitHub_Trending/fi/filament创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考