feat(timestamp): 实现时间戳与日期时间转换功能

- 新增日期时间转时间戳组件 DatetimeToTimestamp
- 新增时间戳转日期时间组件 TimestampToDatetime
- 新增当前时间戳显示组件 TimestampExecution
- 重构 TimestampPage 页面,拆分功能到独立组件
- 扩展 timeUtils 工具函数,支持时区处理和格式化
- 添加时区选择器和时间单位切换功能
- 优化时间戳转换逻辑,支持毫秒和秒单位切换
- 改进 App.css 样式宽度设置
This commit is contained in:
雨霖铃
2025-12-19 22:25:27 +08:00
parent 4f1a78ebb5
commit d05a8a7065
6 changed files with 243 additions and 159 deletions
+60
View File
@@ -0,0 +1,60 @@
import {formatWithDate, formatWithZone, TimezoneOptions} from "../utils/timeUtils";
import {useMemo, useState} from "react";
export function DatetimeToTimestamp() {
const [dateValue, setDateValue] = useState(() => formatWithZone(Date.now()));
const [selectedZone, setSelectedZone] = useState('Asia/Shanghai');
const [result, setResult] = useState('');
const [unit, setUnit] = useState('milliseconds');
const timeZoneList = useMemo(() => ['America/New_York', 'America/Chicago', 'America/Denver', 'America/Los_Angeles', 'America/Anchorage', 'America/Honolulu', 'Europe/London', 'Europe/Paris', 'Europe/Berlin', 'Europe/Moscow', 'Asia/Tokyo', 'Asia/Shanghai', 'Asia/Hong_Kong', 'Asia/Singapore', 'Asia/Dubai', 'Asia/Kolkata', 'Australia/Sydney', 'Pacific/Auckland',], []);
const handleConvertDatetimeToTimestamp = () => {
const timestamp = unit === 'milliseconds' ? formatWithDate(dateValue, selectedZone) : Math.floor(formatWithDate(dateValue, selectedZone) / 1000);
setResult(timestamp);
};
return (<div>
<h2>日期时间转时间戳</h2>
<div>
<div>
<input
type="text"
placeholder="输入日期时间"
value={dateValue}
onChange={(e) => setDateValue(e.target.value)}/>
<select
value={selectedZone}
onChange={(e) => setSelectedZone(e.target.value)}
>
<TimezoneOptions zones={timeZoneList}/>
</select>
</div>
<div style={{marginBottom: '20px'}}>
<button
className={'action-btn'}
onClick={handleConvertDatetimeToTimestamp}
>
转换
</button>
</div>
<div>
<input
type="text"
placeholder="转换结果"
value={result}
readOnly
/>
<select
value={unit}
aria-label='选择时间戳单位'
onChange={(e) => setUnit(e.target.value)}
>
<option value="milliseconds">毫秒(ms)</option>
<option value="seconds">(s)</option>
</select>
</div>
</div>
</div>)
}
+45
View File
@@ -0,0 +1,45 @@
import {useEffect, useState} from "react";
import CopyButton from "./CopyButton";
export function TimestampExecution() {
const [currentTimestamp, setCurrentTimestamp] = useState(Math.floor(Date.now()));
const [showMilliseconds, setShowMilliseconds] = useState(true);
const [isRunningTimestamp, setIsRunningTimestamp] = useState(true);
// 定时更新时间戳
useEffect(() => {
const timerId = isRunningTimestamp ? setInterval(() => {
setCurrentTimestamp(Math.floor(Date.now()));
}, showMilliseconds ? 100 : 1000) : null;
return () => clearInterval(timerId);
}, [isRunningTimestamp, showMilliseconds]);
const toggleUnit = () => setShowMilliseconds(prev => !prev);
const toggleTimestamp = () => setIsRunningTimestamp(prev => !prev);
return (<div>
<h2>当前时间戳</h2>
<p>
<span>{Math.floor(currentTimestamp / (showMilliseconds ? 1 : 1000))}</span>
<span>{showMilliseconds ? '毫秒' : '秒'}</span>
</p>
<div>
<button type="button"
className="action-btn"
onClick={toggleUnit}
aria-label={showMilliseconds ? '切换为秒' : '切换为毫秒'}
>
切换单位
</button>
<CopyButton text={currentTimestamp.toString()} buttonText='复制'></CopyButton>
<button
type="button" // 明确指定类型,防止在 Form 中意外触发提交
className={`btn ${isRunningTimestamp ? 'stop-btn' : 'action-btn'}`}
onClick={toggleTimestamp}
aria-label={isRunningTimestamp ? '停止时间戳更新' : '开始时间戳更新'}
>
{isRunningTimestamp ? '停止' : '开始'}
</button>
</div>
</div>)
}
+69
View File
@@ -0,0 +1,69 @@
import {useMemo, useState} from "react";
import {formatWithZone, TimezoneOptions} from "../utils/timeUtils";
export function TimestampToDatetime() {
const [timestampValue, setTimestampValue] = useState(Date.now());
const [timestampResult, setTimestampResult] = useState('');
const [unit, setUnit] = useState('milliseconds');
const [selectedZone, setSelectedZone] = useState('Asia/Shanghai');
const timeZoneList = useMemo(() => ['America/New_York', 'America/Chicago', 'America/Denver', 'America/Los_Angeles', 'America/Anchorage', 'America/Honolulu', 'Europe/London', 'Europe/Paris', 'Europe/Berlin', 'Europe/Moscow', 'Asia/Tokyo', 'Asia/Shanghai', 'Asia/Hong_Kong', 'Asia/Singapore', 'Asia/Dubai', 'Asia/Kolkata', 'Australia/Sydney', 'Pacific/Auckland',], []);
function handleConvertTimestampToDate() {
if (!timestampValue) {
setTimestampResult('请输入时间戳');
return;
}
const result = formatWithZone(timestampValue, selectedZone, unit);
setTimestampResult(result);
}
const handleInputChange = (e) => setTimestampValue(e.target.value);
return (
<div>
<h2>时间戳转日期时间</h2>
<div>
<div style={{display: 'flex', gap: '8px', alignItems: 'center'}}>
<input
type="number"
placeholder="请输入时间戳"
value={timestampValue}
onChange={handleInputChange}
style={{minWidth: '200px'}}
/>
<select
value={unit}
aria-label='选择时间戳单位'
onChange={(e) => setUnit(e.target.value)}
>
<option value="milliseconds">毫秒(ms)</option>
<option value="seconds">(s)</option>
</select>
</div>
<div style={{marginBottom: '20px'}}>
<button className={'action-btn'} onClick={handleConvertTimestampToDate}>
转换
</button>
</div>
<div style={{display: 'flex', gap: '8px', alignItems: 'center'}}>
<input
type="text"
placeholder="转换结果"
value={timestampResult}
readOnly
style={{minWidth: '200px'}}
/>
<select
value={selectedZone}
onChange={(e) => setSelectedZone(e.target.value)}
>
<TimezoneOptions zones={timeZoneList}/>
</select>
</div>
</div>
</div>
)
}