用 Codex 做一个倒计时小工具,放在电脑上随时打开
教程目录
生成一个无需安装开发工具的本地倒计时,填日期就能用,检查空时间、过去时间和本机时区。
想在电脑上看一眼离聚会还有几天,不一定要装一个大软件。可以让 Codex 做成单个 HTML 文件:填日期、点开始,页面就显示剩余天数、小时、分钟和秒。

准备一个空文件夹就够了
电脑上登录 Codex,准备 Chrome 或 Edge。新建“倒计时”文件夹,在 Codex 里选择它。这份小工具按电脑当前时间计算,不做账号、云同步或关页后的闹钟提醒。
复制这段话,让它生成文件
制作本地倒计时,保存为countdown.html,样式和脚本都放这一个文件。可填活动名称、选择日期和时间,按本机时间显示剩余天、小时、分、秒,每秒更新。空时间要提示先选择;已过时间显示“时间到了”,不能出现负数。不要依赖外部库,不做网络请求或后台提醒。完成后告诉我怎样打开。
找到生成的文件,双击打开。填“周末聚会”,选择未来的日期和时间,点“开始倒计时”。看到秒数变化,说明页面正在更新;改完日期要再点一次开始,别只改输入框就以为倒计时目标也换了。
做三次小检查
先选一个未来时间,看秒数是否往下走;再选过去时间,应显示“时间到了”;最后清空日期点开始,应看到明确提示,不是“NaN”或一串负数。
本例已在 Windows/Chrome 实际打开,并检查了空时间、过去时间和时间拆分:90061秒对应1天1小时1分1秒。下方是同款完整代码,可复制保存后对照。
常见的两个误会
差了几个小时,先看电脑时间、时区和选中的日期;不要一上来让 Codex乱改计算公式。这版按本机时间运行,不适合直接拿来做跨时区会议排期。
关掉页面以后,它不会继续提醒你,电脑休眠时画面也不持续更新。重新打开后会按当前时间重新算。若你需要到点响铃或系统通知,那是另一个需求;先把这个随开随看的小工具用明白。
完整示例代码
复制下面全部代码,用记事本保存为 59-countdown.html,保存类型选“所有文件”,编码选 UTF-8,确认不是 .html.txt,再用浏览器打开。也可以让 Codex 将代码原样保存到工作文件夹。
59-countdown.html
<!doctype html>
<html lang="zh-CN">
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>聚会倒计时</title>
<style>
* {
box-sizing: border-box
}
body {
margin: 0;
background: #f4f6f8;
color: #203344;
font: 17px/1.7 "Microsoft YaHei", sans-serif
}
main {
max-width: 940px;
margin: 40px auto;
padding: 40px;
background: white;
border: 1px solid #e1e7ec;
border-radius: 20px
}
h1 {
font-size: 34px;
line-height: 1.4;
margin: 0 0 18px
}
h2 {
font-size: 22px;
margin: 26px 0 12px
}
p {
margin: 12px 0
}
.muted {
color: #5b7080
}
.hero {
font-size: 21px
}
.grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 18px
}
.card {
padding: 22px;
background: #eef5f4;
border-radius: 12px
}
label {
display: block;
margin: 18px 0 6px;
font-weight: 600
}
input,
select,
textarea {
font: inherit;
padding: 12px;
border: 1px solid #9aacbb;
border-radius: 8px;
max-width: 100%
}
textarea {
width: 100%;
min-height: 64px
}
button,
.button {
font: inherit;
cursor: pointer;
border: 0;
border-radius: 9px;
padding: 12px 22px;
background: #176b5b;
color: white;
display: inline-block;
text-decoration: none
}
button:focus-visible,
input:focus-visible,
a:focus-visible {
outline: 3px solid #f2b35d;
outline-offset: 3px
}
.result {
padding: 22px;
margin-top: 24px;
background: #eef5f4;
border-radius: 12px;
font-size: 21px
}
.error {
color: #a02f2f
}
.numbers {
display: flex;
gap: 15px;
flex-wrap: wrap
}
.number {
padding: 20px;
min-width: 125px;
text-align: center;
background: #eef5f4;
border-radius: 12px
}
.number strong {
display: block;
font-size: 36px
}
table {
width: 100%;
border-collapse: collapse;
margin: 20px 0;
font-size: 15px
}
th,
td {
padding: 11px;
border: 1px solid #d2dce4;
text-align: left
}
th {
background: #eaf0f5
}
code {
background: #edf2f6;
padding: 2px 5px;
border-radius: 4px
}
.money {
font-size: 29px;
font-weight: 700;
color: #176b5b
}
ul {
padding-left: 22px
}
@media(max-width:650px) {
main {
margin: 0;
border-radius: 0;
padding: 26px 20px
}
h1 {
font-size: 27px
}
.grid {
grid-template-columns: 1fr
}
.number {
min-width: 90px;
padding: 12px
}
table {
font-size: 13px
}
th,
td {
padding: 7px
}
}
</style>
<main>
<p class="muted">本地倒计时小工具</p>
<h1>离下一次聚会,还有多久</h1>
<label for="event">给活动起个名字</label>
<input id="event" value="周末桌游小聚">
<label for="target">活动时间 按本机时间计算</label>
<input id="target" type="datetime-local" value="2026-11-07T14:00">
<p>
<button id="start" type="button">开始倒计时</button>
</p>
<p id="error" class="error" role="alert">
</p>
<h2 id="event-title">周末桌游小聚</h2>
<div class="numbers">
<div class="number">
<strong id="days">0</strong>天</div>
<div class="number">
<strong id="hours">0</strong>小时</div>
<div class="number">
<strong id="minutes">0</strong>分钟</div>
<div class="number">
<strong id="seconds">0</strong>秒</div>
</div>
<p id="status" role="status">
</p>
<p class="muted">页面保持打开时更新;关掉页面后不会弹出提醒。</p>
</main>
<script>
let target = null;
function splitTime(ms) {
let n = Math.max(0, Math.ceil(ms / 1000));
return [Math.floor(n / 86400), Math.floor(n % 86400 / 3600), Math.floor(n % 3600 / 60), n % 60];
}
function tick() {
if (target === null) return;
const diff = target - Date.now();
const a = splitTime(diff);
['days', 'hours', 'minutes', 'seconds'].forEach((id, i) => document.getElementById(id).textContent = a[i]);
document.getElementById('status').textContent = diff <= 0 ? '时间到了' : '正在倒计时';
}
function start() {
let v = document.getElementById('target').value;
const d = Date.parse(v);
if (!v || !Number.isFinite(d)) {
document.getElementById('error').textContent = '先选一个有效的活动时间';
return;
}
document.getElementById('error').textContent = '';
target = d;
document.getElementById('event-title').textContent = document.getElementById('event').value.trim() || '我的活动';
tick();
}
document.getElementById('start').onclick = start;
setInterval(tick, 1000);
start();
</script>
</html>