Initial commit

This commit is contained in:
tanxin
2026-10-29 10:08:39 +08:00
commit 4c6243a274
124 changed files with 17359 additions and 0 deletions
+2
View File
@@ -0,0 +1,2 @@
## 1.0.0(2026-04-30)
- 支持 uni-time-format 组件
@@ -0,0 +1,290 @@
<template>
<text class="time-text">{{ formattedTime }}</text>
</template>
<script setup lang="ts">
/**
* 时间格式化
* @description 时间格式化展示组件
* @uniPlatform {
* "app": {
* "android": {
* "uniVer": "x",
* "unixVer": "5.07",
* "unixVaporVer": "5.21"
* },
* "ios": {
* "uniVer": "x",
* "unixVer": "5.07",
* "unixVaporVer": "5.11"
* },
* "harmony": {
* "uniVer": "x",
* "unixVer": "5.07",
* "unixVaporVer": "5.07"
* }
* },
* "mp": {
* "weixin": {
* "uniVer": "x",
* "unixVer": "5.07"
* },
* "alipay": {
* "uniVer": "x",
* "unixVer": "5.31"
* }
* },
* "web": {
* "uniVer": "x",
* "unixVer": "5.07"
* }
* }
*/
type Props = {
/**
* @description 需要格式化的时间戳,支持秒级(10 位)或毫秒级(13 位),秒级会自动换算成毫秒
* @uniPlatform {
* "app": {
* "android": {
* "uniVer": "x",
* "unixVer": "5.07",
* "unixVaporVer": "5.21"
* },
* "ios": {
* "uniVer": "x",
* "unixVer": "5.07",
* "unixVaporVer": "5.11"
* },
* "harmony": {
* "uniVer": "x",
* "unixVer": "5.07",
* "unixVaporVer": "5.07"
* }
* },
* "mp": {
* "weixin": {
* "uniVer": "x",
* "unixVer": "5.07"
* },
* "alipay": {
* "uniVer": "x",
* "unixVer": "5.31"
* }
* },
* "web": {
* "uniVer": "x",
* "unixVer": "5.07"
* }
* }
*/
timestamp: number
/**
* @description 输出格式。"datetime" 输出 YYYY-MM-DD HH:mm;"date" 输出 YYYY-MM-DD;"time" 输出 HH:mm:ss;"relative" 输出相对时间(刚刚 / N 分钟前 / N 小时前 / 昨天 HH:mm / 完整日期)
* @default "datetime"
* @uniPlatform {
* "app": {
* "android": {
* "uniVer": "x",
* "unixVer": "5.07",
* "unixVaporVer": "5.21"
* },
* "ios": {
* "uniVer": "x",
* "unixVer": "5.07",
* "unixVaporVer": "5.11"
* },
* "harmony": {
* "uniVer": "x",
* "unixVer": "5.07",
* "unixVaporVer": "5.07"
* }
* },
* "mp": {
* "weixin": {
* "uniVer": "x",
* "unixVer": "5.07"
* },
* "alipay": {
* "uniVer": "x",
* "unixVer": "5.31"
* }
* },
* "web": {
* "uniVer": "x",
* "unixVer": "5.07"
* }
* }
*/
format?: string
}
const props = withDefaults(defineProps<Props>(), {
format: 'datetime'
})
const appLanguage = (uni.getAppBaseInfo().appLanguage ?? 'en').toLowerCase()
const formattedTime = ref<string>('')
function padZero(num : number) : string {
return num < 10 ? '0' + num.toString() : num.toString()
}
function normalizeTimestamp(timestamp : number) : number {
const absTimestamp = Math.abs(timestamp)
if (absTimestamp > 0 && absTimestamp < 100000000000) {
return timestamp * 1000
}
return timestamp
}
function isValidDate(date : Date) : boolean {
return !isNaN(date.getTime())
}
function getLocaleKey(language : string) : string {
if (language.indexOf('zh-hant') == 0 || language.indexOf('zh-tw') == 0 || language.indexOf('zh-hk') == 0 || language.indexOf('zh-mo') == 0) {
return 'zh-hant'
}
if (language.indexOf('zh') == 0) {
return 'zh-hans'
}
if (language.indexOf('fr') == 0) {
return 'fr'
}
if (language.indexOf('la') == 0) {
return 'la'
}
return 'en'
}
const localeKey = getLocaleKey(appLanguage)
function formatDateTime(date : Date) : string {
const year = date.getFullYear()
const month = padZero(date.getMonth() + 1)
const day = padZero(date.getDate())
const hours = padZero(date.getHours())
const minutes = padZero(date.getMinutes())
return `${year}-${month}-${day} ${hours}:${minutes}`
}
function formatTime(date : Date) : string {
return `${padZero(date.getHours())}:${padZero(date.getMinutes())}`
}
function getNowText(localeKey : string) : string {
if (localeKey == 'zh-hans') return '刚刚'
if (localeKey == 'zh-hant') return '刚刚'
if (localeKey == 'fr') return 'mnt.'
if (localeKey == 'la') return 'nunc'
return 'now'
}
function formatMinuteAgo(localeKey : string, minutes : number) : string {
if (localeKey == 'zh-hans') return `${minutes}分钟前`
if (localeKey == 'zh-hant') return `${minutes}分鐘前`
if (localeKey == 'fr') return `-${minutes}min`
if (localeKey == 'la') return `-${minutes}m`
return `${minutes}m ago`
}
function formatHourAgo(localeKey : string, hours : number) : string {
if (localeKey == 'zh-hans') return `${hours}小时前`
if (localeKey == 'zh-hant') return `${hours}小時前`
if (localeKey == 'fr') return `-${hours}h`
if (localeKey == 'la') return `-${hours}h`
return `${hours}h ago`
}
function formatYesterday(localeKey : string, timeText : string) : string {
if (localeKey == 'zh-hant' || localeKey == 'zh-hans') return `昨天 ${timeText}`
if (localeKey == 'fr') return `hier ${timeText}`
if (localeKey == 'la') return `heri ${timeText}`
return `yest ${timeText}`
}
function getDayStartTimestamp(date : Date) : number {
return new Date(date.getFullYear(), date.getMonth(), date.getDate()).getTime()
}
function getRelativeTime(targetDate : Date, currentTimestamp : number) : string {
const targetTimestamp = targetDate.getTime()
if (targetTimestamp > currentTimestamp) {
return formatDateTime(targetDate)
}
const nowDate = new Date(currentTimestamp)
const todayStart = getDayStartTimestamp(nowDate)
const yesterdayStart = todayStart - 24 * 60 * 60 * 1000
if (targetTimestamp >= todayStart) {
const diffMs = currentTimestamp - targetTimestamp
if (diffMs < 60 * 1000) {
return getNowText(localeKey)
}
const diffMinutes = Math.floor(diffMs / (60 * 1000))
if (diffMinutes < 60) {
return formatMinuteAgo(localeKey, diffMinutes)
}
const diffHours = Math.floor(diffMs / (60 * 60 * 1000))
return formatHourAgo(localeKey, diffHours)
}
if (targetTimestamp >= yesterdayStart) {
return formatYesterday(localeKey, formatTime(targetDate))
}
return formatDateTime(targetDate)
}
function refreshFormattedTime() {
const normalizedTimestamp = normalizeTimestamp(props.timestamp)
const targetDate = new Date(normalizedTimestamp)
if (!isValidDate(targetDate)) {
formattedTime.value = ''
return
}
const formatType = props.format
if (formatType == 'relative') {
formattedTime.value = getRelativeTime(targetDate, Date.now())
return
}
const hours = padZero(targetDate.getHours())
const minutes = padZero(targetDate.getMinutes())
if (formatType == 'time') {
const seconds = padZero(targetDate.getSeconds())
formattedTime.value = `${hours}:${minutes}:${seconds}`
return
}
const year = targetDate.getFullYear()
const month = padZero(targetDate.getMonth() + 1)
const day = padZero(targetDate.getDate())
if (formatType == 'date') {
formattedTime.value = `${year}-${month}-${day}`
return
}
formattedTime.value = `${year}-${month}-${day} ${hours}:${minutes}`
}
watch(() : string => props.format, () => {
refreshFormattedTime()
})
watch(() : number => props.timestamp, () => {
refreshFormattedTime()
})
onMounted(() => {
refreshFormattedTime()
})
</script>
<style>
.time-text {
font-size: 12px;
color: #999999;
}
</style>
+73
View File
@@ -0,0 +1,73 @@
{
"id": "uni-time-format",
"displayName": "uni-time-format 时间格式化",
"version": "1.0.0",
"description": "TimeFormat 时间格式化组件,可自定义时间格式化。",
"isExt": true,
"extUrl": "https://ext.dcloud.net.cn/plugin?id=27851",
"keywords": [
"uni-ui",
"uniui",
"time-format",
"uni-app-x"
],
"engines": {
"HBuilderX": "^5.07",
"uni-app-x": "^5.07",
"uni-app": ""
},
"repository": "https://gitcode.com/dcloud/uni-ui-x",
"directories": {
"example": "../../temps/example_temps"
},
"dcloudext": {
"sale": {
"regular": {
"price": "0.00"
},
"sourcecode": {
"price": "0.00"
}
},
"contact": {
"qq": ""
},
"declaration": {
"ads": "无",
"data": "无",
"permissions": "无"
},
"type": "component-vue",
"darkmode": "x",
"i18n": "x",
"widescreen": "x",
"npmurl": ""
},
"uni_modules": {
"encrypt": [],
"dependencies": [],
"platforms": {
"cloud": {
"tcb": "x",
"aliyun": "x",
"alipay": "x"
},
"client": {
"uni-app-x": {
"web": {
"safari": "√",
"chrome": "√"
},
"app": {
"android": "√",
"ios": "√",
"harmony": "√"
},
"mp": {
"weixin": "√"
}
}
}
}
}
}
+40
View File
@@ -0,0 +1,40 @@
时间格式化展示组件,支持绝对时间与相对时间。
### 基本用法
```html
<uni-time-format :timestamp="Date.now()" format="datetime"></uni-time-format>
```
### relative 规则
`format=relative` 按自然日输出:
- 今天内:
`< 1 分钟` 输出“刚刚”
`< 60 分钟` 输出“n分钟前”
`>= 60 分钟` 输出“n小时前”
- 昨天内:输出“昨天 HH:mm”
- 超过昨天:输出“YYYY-MM-DD HH:mm”
- 未来时间:直接输出“YYYY-MM-DD HH:mm”
### 相对时间国际化
根据 `uni.getAppBaseInfo().appLanguage` 自动匹配:
- 简体中文(`zh`)
- 繁体中文(`zh-hant` / `zh-tw` / `zh-hk` / `zh-mo`)
- 英文(默认)
- 法文(`fr`)
- 拉丁文(`la`)
法文、拉丁文使用短文案,避免长文本占位。
### 非法时间
当 `timestamp` 非法时,组件返回空字符串。
### 示例页面
`/pages/uni-ui/time-format/time-format`
示例页面包含两组相对时间演示:
- 输入框动态演示:输入 `yyyy-mm-dd hh:mm:ss`,实时展示对应相对时间
- 固定分支演示:展示“刚刚 / 分钟前 / 小时前 / 昨天 HH:mm / 超过昨天”五种分支,且不随输入变化