本篇详细讲解鸿蒙 ArkUI 中日期选择器组件的使用方法,结合日记应用中的实际场景进行分析。

在这里插入图片描述

一、DatePicker 概述

在日记应用中,用户需要为每条日记选择日期。鸿蒙提供了 DatePicker 组件和 DatePickerDialog 弹窗两种方式来选择日期。

二、DatePicker 组件

2.1 基本用法

DatePicker({
  start: new Date('2020-01-01'),
  end: new Date('2030-12-31'),
  selected: new Date()
})
  .width('100%')
  .height(180)
  .onDateChange((value: Date) => {
    console.log(`选中的日期: ${value}`)
  })

2.2 参数说明

参数 类型 说明
start Date 可选范围的起始日期
end Date 可选范围的结束日期
selected Date 默认选中的日期

2.3 事件回调

DatePicker({
  start: new Date('2020-01-01'),
  end: new Date(),
  selected: this.selectedDate
})
.onDateChange((value: Date) => {
  this.selectedDate = value
  this.diary.date = this.formatDate(value)
})

三、DatePickerDialog 弹窗

3.1 基本用法

在日记应用中,使用弹窗形式更加友好:

private showDatePickerDialog() {
  DatePickerDialog.show({
    start: new Date('2020-01-01'),
    end: new Date(),
    selected: this.selectedDate,
    onAccept: (value: DatePickerResult) => {
      const date = new Date(value.year, value.month, value.day)
      this.selectedDate = date
      this.diary.date = this.formatDate(date)
    },
    onCancel: () => {
      console.log('用户取消了日期选择')
    },
    onChange: (value: DatePickerResult) => {
      console.log(`当前选中: ${value.year}-${value.month + 1}-${value.day}`)
    }
  })
}

3.2 回调函数说明

回调 触发时机 参数类型
onAccept 用户点击确认 DatePickerResult
onCancel 用户点击取消
onChange 滚动选择变化 DatePickerResult

3.3 DatePickerResult 结构

interface DatePickerResult {
  year: number    // 选中的年份
  month: number   // 选中的月份(0-11)
  day: number     // 选中的日期
}

重要提醒: month 字段的范围是 0-11,1月为0,12月为11。使用时需要 +1 转换。

四、日记应用中的日期选择

4.1 日期选择行 UI

@Builder
DateRow() {
  Row({ space: 8 }) {
    Image($r('app.media.calendar'))
      .width(20)
      .height(20)
      .fillColor('#666')

    Text(this.formatDisplayDate(this.selectedDate))
      .fontSize(16)
      .layoutWeight(1)

    Image($r('app.media.arrow_right'))
      .width(16)
      .height(16)
      .fillColor('#CCC')
  }
  .width('100%')
  .padding(16)
  .backgroundColor('#FFFFFF')
  .borderRadius(12)
  .onClick(() => {
    this.showDatePickerDialog()
  })
}

4.2 日期格式化

// 存储格式:YYYY-MM-DD
private formatDate(date: Date): string {
  const year = date.getFullYear()
  const month = (date.getMonth() + 1).toString().padStart(2, '0')
  const day = date.getDate().toString().padStart(2, '0')
  return `${year}-${month}-${day}`
}

// 展示格式:YYYY年MM月DD日
private formatDisplayDate(date: Date): string {
  return `${date.getFullYear()}${date.getMonth() + 1}${date.getDate()}`
}

4.3 解析存储的日期字符串

private parseDate(dateStr: string): Date {
  const parts = dateStr.split('-')
  const year = parseInt(parts[0])
  const month = parseInt(parts[1]) - 1  // 月份减1
  const day = parseInt(parts[2])
  return new Date(year, month, day)
}

五、日期范围限制

5.1 限制未来日期

DatePickerDialog.show({
  start: new Date('2020-01-01'),
  end: new Date(),           // 不能选择未来日期
  selected: this.selectedDate
})

5.2 限制特定范围

// 只能选择最近30天
const start = new Date()
start.setDate(start.getDate() - 30)

DatePickerDialog.show({
  start: start,
  end: new Date(),
  selected: this.selectedDate
})

六、TextPickerDialog 时间选择

除了日期,有时也需要选择时间:

TextPickerDialog.show({
  range: ['上午', '下午', '晚上'],
  selected: 0,
  onAccept: (value: TextPickerResult) => {
    console.log(`选中: ${value.value}`)
  }
})

七、日期计算工具

7.1 获取星期几

private getWeekday(date: Date): string {
  const weekdays = ['周日', '周一', '周二', '周三', '周四', '周五', '周六']
  return weekdays[date.getDay()]
}

7.2 计算日期差

private daysBetween(date1: Date, date2: Date): number {
  const msPerDay = 24 * 60 * 60 * 1000
  const diff = Math.abs(date1.getTime() - date2.getTime())
  return Math.floor(diff / msPerDay)
}

7.3 获取当月天数

private getDaysInMonth(year: number, month: number): number {
  return new Date(year, month + 1, 0).getDate()
}

八、日期验证

8.1 验证日期有效性

private isValidDate(dateStr: string): boolean {
  const date = new Date(dateStr)
  return !isNaN(date.getTime())
}

8.2 验证日期范围

private isDateInRange(date: Date, start: Date, end: Date): boolean {
  return date >= start && date <= end
}

九、国际化日期

9.1 使用系统格式

const date = new Date()
const formatted = date.toLocaleDateString('zh-CN', {
  year: 'numeric',
  month: 'long',
  day: 'numeric'
})
// 输出:2026年7月24日

9.2 相对时间

private getRelativeTime(date: Date): string {
  const now = new Date()
  const diff = now.getTime() - date.getTime()
  const days = Math.floor(diff / (24 * 60 * 60 * 1000))

  if (days === 0) return '今天'
  if (days === 1) return '昨天'
  if (days === 2) return '前天'
  if (days < 7) return `${days}天前`
  if (days < 30) return `${Math.floor(days / 7)}周前`
  return this.formatDisplayDate(date)
}

十、总结

DatePicker 在日记应用中的使用要点:

  1. 弹窗形式DatePickerDialog.show() 是最常用的方式
  2. 月份处理month 范围是 0-11,必须注意 +1/-1 转换
  3. 日期格式化:存储用 YYYY-MM-DD,展示用本地化格式
  4. 范围限制:通过 startend 控制可选范围
  5. 回调处理onAccept 获取确认结果,onCancel 处理取消
  6. 日期工具:封装日期计算和验证方法提高复用性

正确处理日期是应用开发的基础技能,特别是在涉及日期选择、格式化和存储时,需要特别注意月份从0开始这一常见陷阱。

Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐