Files
i-tools/app/timestamp/page.tsx
yfan 3d175d75af
Some checks failed
Build and Push Docker Image / build (push) Has been cancelled
Sync to CNB / sync (push) Has been cancelled
Delete old workflow runs / del_runs (push) Has been cancelled
Upstream Sync / Sync latest commits from upstream repo (push) Has been cancelled
first commit
2026-01-30 16:57:44 +08:00

259 lines
9.0 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.
"use client";
import { useState, useEffect } from "react";
import { Clock, ArrowLeftRight, Copy, RefreshCw } from "lucide-react";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { Tabs, TabsList, TabsTrigger } from "@/components/ui/tabs";
import { toast } from "sonner";
import dayjs from "dayjs";
export default function TimestampPage() {
const [timestamp, setTimestamp] = useState("");
const [dateTime, setDateTime] = useState<string>("");
const [unit, setUnit] = useState<"seconds" | "milliseconds">("seconds");
const [currentTimestamp, setCurrentTimestamp] = useState("");
useEffect(() => {
// Initialize date time with current time
setDateTime(dayjs().format("YYYY-MM-DDTHH:mm:ss"));
}, []);
useEffect(() => {
const updateCurrent = () => {
const now = Date.now();
setCurrentTimestamp(
unit === "seconds" ? Math.floor(now / 1000).toString() : now.toString()
);
};
updateCurrent();
const timer = setInterval(updateCurrent, 1000);
return () => clearInterval(timer);
}, [unit]);
const handleUnitChange = (newUnit: "seconds" | "milliseconds") => {
if (timestamp && !isNaN(Number(timestamp))) {
const ts = Number(timestamp);
if (unit === "seconds" && newUnit === "milliseconds") {
setTimestamp((ts * 1000).toString());
} else if (unit === "milliseconds" && newUnit === "seconds") {
setTimestamp(Math.floor(ts / 1000).toString());
}
}
setUnit(newUnit);
};
const timestampToDate = () => {
if (!timestamp) {
toast.warning("请输入时间戳");
return;
}
const ts = parseInt(timestamp);
if (isNaN(ts)) {
toast.error("无效的时间戳");
return;
}
const date = unit === "seconds" ? dayjs.unix(ts) : dayjs(ts);
if (!date.isValid()) {
toast.error("无效的时间戳");
return;
}
setDateTime(date.format("YYYY-MM-DDTHH:mm:ss"));
toast.success("转换成功");
};
const dateToTimestamp = () => {
if (!dateTime) {
toast.warning("请选择日期时间");
return;
}
const date = dayjs(dateTime);
const ts = unit === "seconds" ? date.unix() : date.valueOf();
setTimestamp(ts.toString());
toast.success("转换成功");
};
const copyToClipboard = async (text: string) => {
try {
await navigator.clipboard.writeText(text);
toast.success("已复制到剪贴板");
} catch {
toast.error("复制失败");
}
};
const setNow = () => {
const now = dayjs();
setDateTime(now.format("YYYY-MM-DDTHH:mm:ss"));
const ts = unit === "seconds" ? now.unix() : now.valueOf();
setTimestamp(ts.toString());
};
return (
<div className="space-y-6 animate-in fade-in slide-in-from-bottom-4 duration-500">
{/* Page Header */}
<div className="flex items-center space-x-4 border-b pb-4">
<div className="flex h-12 w-12 items-center justify-center rounded-xl bg-linear-to-br from-amber-500 to-orange-600 shadow-lg">
<Clock className="h-6 w-6 text-white" />
</div>
<div>
<h1 className="text-2xl font-bold tracking-tight"></h1>
<p className="text-muted-foreground">
Unix
</p>
</div>
</div>
{/* Current Timestamp */}
<Card>
<CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
<CardTitle className="flex items-center gap-2 text-base font-medium">
<Clock className="h-4 w-4" />
</CardTitle>
<Tabs
value={unit}
onValueChange={(v) => handleUnitChange(v as "seconds" | "milliseconds")}
className="w-45"
>
<TabsList className="grid w-full grid-cols-2 h-8">
<TabsTrigger value="seconds" className="text-xs">(s)</TabsTrigger>
<TabsTrigger value="milliseconds" className="text-xs">(ms)</TabsTrigger>
</TabsList>
</Tabs>
</CardHeader>
<CardContent>
<div className="flex items-center gap-4">
<div className="font-mono text-3xl font-bold text-primary tracking-wider">
{currentTimestamp}
</div>
<Button
variant="outline"
size="icon"
onClick={() => copyToClipboard(currentTimestamp)}
>
<Copy className="h-4 w-4" />
</Button>
</div>
</CardContent>
</Card>
<div className="grid gap-6 lg:grid-cols-2">
{/* Timestamp to Date */}
<Card>
<CardHeader>
<CardTitle className="text-base font-medium"> </CardTitle>
</CardHeader>
<CardContent className="space-y-4">
<div className="space-y-2">
<div className="relative">
<Input
placeholder={`输入时间戳 (${unit === "seconds" ? "秒" : "毫秒"})`}
value={timestamp}
onChange={(e) => setTimestamp(e.target.value)}
className="pr-20 font-mono"
/>
<Button
variant="ghost"
size="sm"
className="absolute right-1 top-1 h-7 text-xs text-muted-foreground hover:text-primary"
onClick={() => setTimestamp(currentTimestamp)}
>
使
</Button>
</div>
</div>
<Button onClick={timestampToDate} className="w-full gap-2">
<ArrowLeftRight className="h-4 w-4" />
</Button>
</CardContent>
</Card>
{/* Date to Timestamp */}
<Card>
<CardHeader>
<CardTitle className="text-base font-medium"> </CardTitle>
</CardHeader>
<CardContent className="space-y-4">
<div className="space-y-2">
<div className="relative">
<Input
type="datetime-local"
step="1"
value={dateTime}
onChange={(e) => setDateTime(e.target.value)}
className="font-mono"
/>
</div>
</div>
<Button onClick={dateToTimestamp} className="w-full gap-2">
<ArrowLeftRight className="h-4 w-4" />
</Button>
</CardContent>
</Card>
</div>
{/* Result Display */}
<Card>
<CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
<CardTitle className="text-base font-medium"></CardTitle>
<Button variant="ghost" size="sm" onClick={setNow} className="gap-2 h-8">
<RefreshCw className="h-3.5 w-3.5" />
</Button>
</CardHeader>
<CardContent>
<div className="grid gap-4 md:grid-cols-2">
<div className="rounded-lg bg-muted p-4 space-y-1">
<p className="text-xs text-muted-foreground">
({unit === "seconds" ? "秒" : "毫秒"})
</p>
<div className="font-mono text-lg font-semibold truncate">
{timestamp || "-"}
</div>
</div>
<div className="rounded-lg bg-muted p-4 space-y-1">
<p className="text-xs text-muted-foreground">
</p>
<div className="font-mono text-lg font-semibold truncate">
{dateTime ? dayjs(dateTime).format("YYYY-MM-DD HH:mm:ss") : "-"}
</div>
</div>
</div>
</CardContent>
</Card>
{/* Info Card */}
<Card>
<CardHeader>
<CardTitle className="flex items-center gap-2 text-base">
<span className="text-xl">💡</span> 使
</CardTitle>
</CardHeader>
<CardContent>
<div className="grid gap-6 md:grid-cols-2">
<div className="space-y-2">
<ul className="list-disc pl-4 text-sm text-muted-foreground space-y-1">
<li>Unix 1970-01-01 00:00:00 UTC </li>
<li></li>
<li>JavaScript 使</li>
</ul>
</div>
<div className="space-y-2">
<ul className="list-disc pl-4 text-sm text-muted-foreground space-y-1">
<li> PHPPython使</li>
<li>"使用当前"</li>
<li></li>
</ul>
</div>
</div>
</CardContent>
</Card>
</div>
);
}