staff/uni_modules/wot-design-uni/components/wd-calendar-view/utils.ts

430 lines
10 KiB
TypeScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { computed } from 'vue'
import { dayjs } from '../common/dayjs'
import { isArray, isFunction, padZero } from '../common/util'
import { useTranslate } from '../composables/useTranslate'
import type { CalendarDayType, CalendarItem, CalendarTimeFilter, CalendarType } from './types'
const { translate } = useTranslate('calendar-view')
const weeks = computed(() => {
return [
translate('weeks.sun'),
translate('weeks.mon'),
translate('weeks.tue'),
translate('weeks.wed'),
translate('weeks.thu'),
translate('weeks.fri'),
translate('weeks.sat')
]
})
/**
* 比较两个时间的日期是否相等
* @param {timestamp} date1
* @param {timestamp} date2
*/
export function compareDate(date1: number, date2: number | null) {
const dateValue1 = new Date(date1)
const dateValue2 = new Date(date2 || '')
const year1 = dateValue1.getFullYear()
const year2 = dateValue2.getFullYear()
const month1 = dateValue1.getMonth()
const month2 = dateValue2.getMonth()
const day1 = dateValue1.getDate()
const day2 = dateValue2.getDate()
if (year1 === year2) {
if (month1 === month2) {
return day1 === day2 ? 0 : day1 > day2 ? 1 : -1
}
return month1 === month2 ? 0 : month1 > month2 ? 1 : -1
}
return year1 > year2 ? 1 : -1
}
/**
* 判断是否是范围选择
* @param {string} type
*/
export function isRange(type: CalendarType) {
return type.indexOf('range') > -1
}
/**
* 比较两个日期的月份是否相等
* @param {timestamp} date1
* @param {timestamp} date2
*/
export function compareMonth(date1: number, date2: number) {
const dateValue1 = new Date(date1)
const dateValue2 = new Date(date2)
const year1 = dateValue1.getFullYear()
const year2 = dateValue2.getFullYear()
const month1 = dateValue1.getMonth()
const month2 = dateValue2.getMonth()
if (year1 === year2) {
return month1 === month2 ? 0 : month1 > month2 ? 1 : -1
}
return year1 > year2 ? 1 : -1
}
/**
* 比较两个日期的年份是否一致
* @param {timestamp} date1
* @param {timestamp} date2
*/
export function compareYear(date1: number, date2: number) {
const dateValue1 = new Date(date1)
const dateValue2 = new Date(date2)
const year1 = dateValue1.getFullYear()
const year2 = dateValue2.getFullYear()
return year1 === year2 ? 0 : year1 > year2 ? 1 : -1
}
/**
* 获取一个月的最后一天
* @param {number} year
* @param {number} month
*/
export function getMonthEndDay(year: number, month: number) {
return 32 - new Date(year, month - 1, 32).getDate()
}
/**
* 格式化年月
* @param {timestamp} date
*/
export function formatMonthTitle(date: number) {
return dayjs(date).format(translate('monthTitle'))
}
/**
* 根据下标获取星期
* @param {number} index
*/
export function getWeekLabel(index: number) {
if (index >= 7) {
index = index % 7
}
return weeks.value[index]
}
/**
* 格式化年份
* @param {timestamp} date
*/
export function formatYearTitle(date: number) {
return dayjs(date).format(translate('yearTitle'))
}
/**
* 根据最小日期和最大日期获取这之间总共有几个月份
* @param {timestamp} minDate
* @param {timestamp} maxDate
*/
export function getMonths(minDate: number, maxDate: number) {
const months: number[] = []
const month = new Date(minDate)
month.setDate(1)
while (compareMonth(month.getTime(), maxDate) < 1) {
months.push(month.getTime())
month.setMonth(month.getMonth() + 1)
}
return months
}
/**
* 根据最小日期和最大日期获取这之间总共有几年
* @param {timestamp} minDate
* @param {timestamp} maxDate
*/
export function getYears(minDate: number, maxDate: number) {
const years: number[] = []
const year = new Date(minDate)
year.setMonth(0)
year.setDate(1)
while (compareYear(year.getTime(), maxDate) < 1) {
years.push(year.getTime())
year.setFullYear(year.getFullYear() + 1)
}
return years
}
/**
* 获取一个日期所在周的第一天和最后一天
* @param {timestamp} date
*/
export function getWeekRange(date: number, firstDayOfWeek: number) {
if (firstDayOfWeek >= 7) {
firstDayOfWeek = firstDayOfWeek % 7
}
const dateValue = new Date(date)
dateValue.setHours(0, 0, 0, 0)
const year = dateValue.getFullYear()
const month = dateValue.getMonth()
const day = dateValue.getDate()
const week = dateValue.getDay()
const weekStart = new Date(year, month, day - ((7 + week - firstDayOfWeek) % 7))
const weekEnd = new Date(year, month, day + 6 - ((7 + week - firstDayOfWeek) % 7))
return [weekStart.getTime(), weekEnd.getTime()]
}
/**
* 获取日期偏移量
* @param {timestamp} date1
* @param {timestamp} date2
*/
export function getDayOffset(date1: number, date2: number) {
return (date1 - date2) / (24 * 60 * 60 * 1000) + 1
}
/**
* 获取偏移日期
* @param {timestamp} date
* @param {number} offset
*/
export function getDayByOffset(date: number, offset: number) {
const dateValue = new Date(date)
dateValue.setDate(dateValue.getDate() + offset)
return dateValue.getTime()
}
export const getPrevDay = (date: number) => getDayByOffset(date, -1)
export const getNextDay = (date: number) => getDayByOffset(date, 1)
/**
* 获取月份偏移量
* @param {timestamp} date1
* @param {timestamp} date2
*/
export function getMonthOffset(date1: number, date2: number) {
const dateValue1 = new Date(date1)
const dateValue2 = new Date(date2)
const year1 = dateValue1.getFullYear()
const year2 = dateValue2.getFullYear()
let month1 = dateValue1.getMonth()
const month2 = dateValue2.getMonth()
month1 = (year1 - year2) * 12 + month1
return month1 - month2 + 1
}
/**
* 获取偏移月份
* @param {timestamp} date
* @param {number} offset
*/
export function getMonthByOffset(date: number, offset: number) {
const dateValue = new Date(date)
dateValue.setMonth(dateValue.getMonth() + offset)
return dateValue.getTime()
}
/**
* 获取默认时间,格式化为数组
* @param {array|string|null} defaultTime
*/
export function getDefaultTime(defaultTime: string[] | string | null) {
if (isArray(defaultTime)) {
const startTime = (defaultTime[0] || '00:00:00').split(':').map((item: string) => {
return parseInt(item)
})
const endTime = (defaultTime[1] || '00:00:00').split(':').map((item) => {
return parseInt(item)
})
return [startTime, endTime]
} else {
const time = (defaultTime || '00:00:00').split(':').map((item) => {
return parseInt(item)
})
return [time, time]
}
}
/**
* 根据默认时间获取日期
* @param {timestamp} date
* @param {array} defaultTime
*/
export function getDateByDefaultTime(date: number, defaultTime: number[]) {
const dateValue = new Date(date)
dateValue.setHours(defaultTime[0])
dateValue.setMinutes(defaultTime[1])
dateValue.setSeconds(defaultTime[2])
return dateValue.getTime()
}
/**
* 获取经过 iteratee 格式化后的长度为 n 的数组
* @param {number} n
* @param {function} iteratee
*/
const times = (n: number, iteratee: (index: number) => CalendarItem) => {
let index: number = -1
const result: CalendarItem[] = Array(n < 0 ? 0 : n)
while (++index < n) {
result[index] = iteratee(index)
}
return result
}
/**
* 获取时分秒
* @param {timestamp}} date
*/
const getTime = (date: number) => {
const dateValue = new Date(date)
return [dateValue.getHours(), dateValue.getMinutes(), dateValue.getSeconds()]
}
/**
* 根据最小最大日期获取时间数据用于填入picker
* @param {*} param0
*/
export function getTimeData({
date,
minDate,
maxDate,
isHideSecond,
filter
}: {
date: number
minDate: number
maxDate: number
isHideSecond: boolean
filter?: CalendarTimeFilter
}) {
const compareMin = compareDate(date, minDate)
const compareMax = compareDate(date, maxDate)
let minHour = 0
let maxHour = 23
let minMinute = 0
let maxMinute = 59
let minSecond = 0
let maxSecond = 59
if (compareMin === 0) {
const minTime = getTime(minDate)
const currentTime = getTime(date)
minHour = minTime[0]
if (minTime[0] === currentTime[0]) {
minMinute = minTime[1]
if (minTime[1] === currentTime[1]) {
minSecond = minTime[2]
}
}
}
if (compareMax === 0) {
const maxTime = getTime(maxDate)
const currentTime = getTime(date)
maxHour = maxTime[0]
if (maxTime[0] === currentTime[0]) {
maxMinute = maxTime[1]
if (maxTime[1] === currentTime[1]) {
maxSecond = maxTime[2]
}
}
}
let columns: CalendarItem[][] = []
let hours = times(24, (index) => {
return {
label: translate('hour', padZero(index)),
value: index,
disabled: index < minHour || index > maxHour
}
})
let minutes = times(60, (index) => {
return {
label: translate('minute', padZero(index)),
value: index,
disabled: index < minMinute || index > maxMinute
}
})
let seconds: CalendarItem[] = []
if (filter && isFunction(filter)) {
hours = filter({
type: 'hour',
values: hours
})
minutes = filter({
type: 'minute',
values: minutes
})
}
if (!isHideSecond) {
seconds = times(60, (index) => {
return {
label: translate('second', padZero(index)),
value: index,
disabled: index < minSecond || index > maxSecond
}
})
if (filter && isFunction(filter)) {
seconds = filter({
type: 'second',
values: seconds
})
}
}
columns = isHideSecond ? [hours, minutes] : [hours, minutes, seconds]
return columns
}
/**
* 获取当前是第几周
* @param {timestamp} date
*/
export function getWeekNumber(date: number | Date) {
date = new Date(date)
date.setHours(0, 0, 0, 0)
// Thursday in current week decides the year.
date.setDate(date.getDate() + 3 - ((date.getDay() + 6) % 7))
// January 4 is always in week 1.
const week = new Date(date.getFullYear(), 0, 4)
// Adjust to Thursday in week 1 and count number of weeks from date to week 1.
// Rounding should be fine for Daylight Saving Time. Its shift should never be more than 12 hours.
return 1 + Math.round(((date.getTime() - week.getTime()) / 86400000 - 3 + ((week.getDay() + 6) % 7)) / 7)
}
export function getItemClass(monthType: CalendarDayType, value: number | null | (number | null)[], type: CalendarType) {
const classList = ['is-' + monthType]
if (type.indexOf('range') > -1 && isArray(value)) {
if (!value || !value[1]) {
classList.push('is-without-end')
}
}
return classList.join(' ')
}