Files
utils/src/components/tools/TimestampConverter.vue
zguiy 8400dbfab9
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
工具完成
2025-06-28 22:38:49 +08:00

256 lines
7.4 KiB
Vue

<template>
<div class="space-y-6">
<!-- 当前时间戳 -->
<div class="card p-4">
<h3 class="text-lg font-semibold text-primary mb-3">{{ t('tools.timestamp_converter.current_timestamp') }}</h3>
<div class="space-y-3">
<div class="flex items-center space-x-4">
<span class="text-secondary">当前时间戳:</span>
<span class="text-primary font-mono text-lg">{{ currentTimestamp }}</span>
<button
@click="copyTimestamp"
class="btn-secondary px-3 py-1 text-sm"
>
<FontAwesomeIcon :icon="['fas', 'copy']" class="mr-1" />
{{ t('tools.timestamp_converter.copy_timestamp') }}
</button>
</div>
<div class="flex items-center space-x-4">
<span class="text-secondary">当前日期:</span>
<span class="text-primary">{{ currentDateTime }}</span>
<button
@click="copyDateTime"
class="btn-secondary px-3 py-1 text-sm"
>
<FontAwesomeIcon :icon="['fas', 'copy']" class="mr-1" />
{{ t('tools.timestamp_converter.copy_date') }}
</button>
</div>
</div>
</div>
<!-- 转换工具 -->
<div class="grid grid-cols-1 lg:grid-cols-2 gap-6">
<!-- 时间戳转日期 -->
<div class="card p-4">
<h3 class="text-lg font-semibold text-primary mb-3">{{ t('tools.timestamp_converter.timestamp_to_date') }}</h3>
<div class="space-y-3">
<input
v-model="timestampInput"
type="text"
:placeholder="t('tools.timestamp_converter.timestamp_placeholder')"
class="input-field"
@input="convertTimestampToDate"
>
<button
@click="useCurrentTimestamp"
class="btn-secondary"
>
使用当前时间戳
</button>
<div v-if="timestampResult" class="space-y-2">
<label class="block text-sm font-medium text-secondary">转换结果:</label>
<div class="bg-block p-3 rounded font-mono text-sm">
<div><strong>本地时间:</strong> {{ timestampResult.local }}</div>
<div><strong>UTC时间:</strong> {{ timestampResult.utc }}</div>
<div><strong>ISO格式:</strong> {{ timestampResult.iso }}</div>
</div>
</div>
</div>
</div>
<!-- 日期转时间戳 -->
<div class="card p-4">
<h3 class="text-lg font-semibold text-primary mb-3">{{ t('tools.timestamp_converter.date_to_timestamp') }}</h3>
<div class="space-y-3">
<input
v-model="dateInput"
type="datetime-local"
class="input-field"
@input="convertDateToTimestamp"
>
<button
@click="useCurrentDate"
class="btn-secondary"
>
使用当前时间
</button>
<div v-if="dateResult" class="space-y-2">
<label class="block text-sm font-medium text-secondary">转换结果:</label>
<div class="bg-block p-3 rounded font-mono text-sm">
<div><strong>时间戳():</strong> {{ dateResult.seconds }}</div>
<div><strong>时间戳(毫秒):</strong> {{ dateResult.milliseconds }}</div>
</div>
</div>
</div>
</div>
</div>
<!-- 快速转换 -->
<div class="card p-4">
<h3 class="text-lg font-semibold text-primary mb-3">快速转换</h3>
<div class="grid grid-cols-2 md:grid-cols-4 gap-3">
<button
v-for="quick in quickOptions"
:key="quick.label"
@click="() => applyQuickTimestamp(quick.timestamp)"
class="btn-secondary text-sm"
>
{{ quick.label }}
</button>
</div>
</div>
</div>
</template>
<script setup lang="ts">
import { ref, onMounted, onUnmounted } from 'vue'
import { useLanguage } from '@/composables/useLanguage'
const { t } = useLanguage()
// 响应式状态
const currentTimestamp = ref(0)
const currentDateTime = ref('')
const timestampInput = ref('')
const dateInput = ref('')
const timestampResult = ref<any>(null)
const dateResult = ref<any>(null)
// 更新当前时间戳
const updateCurrentTime = () => {
const now = new Date()
currentTimestamp.value = Math.floor(now.getTime() / 1000)
currentDateTime.value = now.toLocaleString('zh-CN', {
year: 'numeric',
month: '2-digit',
day: '2-digit',
hour: '2-digit',
minute: '2-digit',
second: '2-digit'
})
}
// 时间戳转日期
const convertTimestampToDate = () => {
const input = timestampInput.value.trim()
if (!input) {
timestampResult.value = null
return
}
try {
let timestamp = parseInt(input)
// 判断是秒还是毫秒
if (timestamp.toString().length === 10) {
timestamp *= 1000
}
const date = new Date(timestamp)
if (isNaN(date.getTime())) {
timestampResult.value = { error: '无效的时间戳' }
return
}
timestampResult.value = {
local: date.toLocaleString('zh-CN'),
utc: date.toUTCString(),
iso: date.toISOString()
}
} catch (error) {
timestampResult.value = { error: '转换失败' }
}
}
// 日期转时间戳
const convertDateToTimestamp = () => {
if (!dateInput.value) {
dateResult.value = null
return
}
try {
const date = new Date(dateInput.value)
const timestamp = date.getTime()
if (isNaN(timestamp)) {
dateResult.value = { error: '无效的日期' }
return
}
dateResult.value = {
seconds: Math.floor(timestamp / 1000),
milliseconds: timestamp
}
} catch (error) {
dateResult.value = { error: '转换失败' }
}
}
// 使用当前时间戳
const useCurrentTimestamp = () => {
timestampInput.value = currentTimestamp.value.toString()
convertTimestampToDate()
}
// 使用当前日期
const useCurrentDate = () => {
const now = new Date()
const year = now.getFullYear()
const month = String(now.getMonth() + 1).padStart(2, '0')
const day = String(now.getDate()).padStart(2, '0')
const hours = String(now.getHours()).padStart(2, '0')
const minutes = String(now.getMinutes()).padStart(2, '0')
dateInput.value = `${year}-${month}-${day}T${hours}:${minutes}`
convertDateToTimestamp()
}
// 复制时间戳
const copyTimestamp = async () => {
try {
await navigator.clipboard.writeText(currentTimestamp.value.toString())
} catch (error) {
console.error('复制失败:', error)
}
}
// 复制日期时间
const copyDateTime = async () => {
try {
await navigator.clipboard.writeText(currentDateTime.value)
} catch (error) {
console.error('复制失败:', error)
}
}
// 快速选项
const quickOptions = [
{ label: '1小时前', timestamp: () => Math.floor(Date.now() / 1000) - 3600 },
{ label: '1天前', timestamp: () => Math.floor(Date.now() / 1000) - 86400 },
{ label: '1周前', timestamp: () => Math.floor(Date.now() / 1000) - 604800 },
{ label: '1月前', timestamp: () => Math.floor(Date.now() / 1000) - 2592000 }
]
// 应用快速时间戳
const applyQuickTimestamp = (timestampFn: () => number) => {
timestampInput.value = timestampFn().toString()
convertTimestampToDate()
}
// 定时器
let timer: NodeJS.Timeout
onMounted(() => {
updateCurrentTime()
timer = setInterval(updateCurrentTime, 1000)
})
onUnmounted(() => {
if (timer) {
clearInterval(timer)
}
})
</script>