前言
你还记不记得,之前我们花了一整个晚上,用 Date 对象和 setInterval 定时器,亲手写了一个数字翻页时钟?那玩意儿每秒都要手动更新 @State 变量,格式化日期字符串,还得操心定时器的启停和内存泄漏。写完之后我就在想:显示时间这种刚需,难道每次都要从头造轮子吗?有没有一个组件,直接往页面上一扔,它自己就知道现在是几点,自己会一秒一秒地走,我连 setInterval 都不用写?
还真有。它叫 TextClock。

那天我翻 HarmonyOS 的组件文档,无意中看到了它。试了一下,发现这东西简直就是为“懒人”设计的——不需要 Date,不需要 setInterval,不需要 @State 变量,只需要一行 <TextClock>,时间就在屏幕上自己跑起来了。更妙的是,它还能一键切换 24 小时制和 12 小时制,上午下午自动标注,时区也能调。这篇文章,就想跟你聊聊这个被很多人忽略的小组件。我们不写复杂的逻辑,只用一个 TextClock 和一个按钮,体验一下“框架替你干活”的快感。
一、TextClock 到底干了什么——它把定时器和格式化全吃了

在之前的翻页时钟里,我们做的事情可以拆成三步:获取当前时间、格式化成字符串、显示在 Text 组件里。为了保证时间每秒更新,还得用 setInterval 反复执行第一步和第二步。但 TextClock 把这三步全部内置了。它本质上就是一个会自动更新的 Text,你只需要告诉它“用哪种格式显示”,它就会自己在后台维护一个定时器,每秒刷新显示内容。你完全不用管定时器的创建和销毁,也不用管 @State 的更新,它自己就是一个自驱动的时间显示器。
这对开发者来说意味着什么?意味着显示时间的代码从十几行变成了两三行,而且更稳定、更不容易出错。框架级别的组件通常比我们手写的逻辑更健壮,因为它经过了更严格的测试和优化,也更好地利用了系统资源。比如 TextClock 的更新机制是和系统时钟同步的,不会出现我们手写的 setInterval 因为主线程繁忙而延迟的问题。
TextClock 的核心属性是 format,它接受一个格式字符串,和 Java 的 SimpleDateFormat 规则一样。比如 "HH:mm:ss" 就是 24 小时制的时间,"hh:mm:ss a" 就是 12 小时制带上午/下午标注。"yyyy-MM-dd" 就是日期。你可以任意组合这些字符,让时钟显示成你想要的样子。甚至可以把日期和时间拼在一起,一行显示完整的时间戳。这个灵活性是手写的格式化函数很难比拟的,因为你不需要自己写 padStart,不需要自己拼字符串——所有脏活累活都交给组件了。
二、12小时制 vs 24小时制——不只是数字游戏
全世界大概有两种人:一种习惯说“下午三点”,另一种习惯说“15点”。这两种习惯对应了 12 小时制和 24 小时制。在 TextClock 里,切换这两种显示方式只需要改一下 format 属性:
format="HH:mm:ss"→ 显示 14:25:03format="hh:mm:ss a"→ 显示 02:25:03 下午
这里的 HH 是 24 小时制的小时(00-23),hh 是 12 小时制的小时(01-12),a 是上午/下午标记。注意大小写,写错了时间就不对了。
为了让用户能够手动切换这两种格式,我们在页面上加一个按钮。点击按钮时,改变一个 @State 变量 is24Hour,然后动态更换 format 的值。因为 TextClock 会自动响应属性的变化,当 format 改变时,显示的时间会立刻从“14:25”变成“02:25 下午”,或者反过来。这种切换是瞬间完成的,不需要重启任何定时器,也不需要重新初始化组件。框架自己处理了所有内部状态。

除了时间,我们还可以在页面上显示日期和星期。用 format="yyyy年MM月dd日 EEEE" 就能显示类似“2026年6月11日 星期四”的完整日期。这个日期也是自动更新的——到了午夜 0 点,日期会自动跳到下一天,星期也会自动变化。你完全不用操心跨天逻辑,TextClock 内部已经处理好了。
所以我们的页面可以有两行:一行显示日期(字号小一些,灰色),一行显示时间(字号巨大,黑色或白色)。两行都是 TextClock 组件,分别设置不同的 format。上面再加一个按钮,控制时间行是 12 小时制还是 24 小时制。这就是整个应用的全部逻辑。
三、小时制偏好可以记住——Preferences 再次出场
既然有切换,就最好能记住用户的选择。和之前的夜间模式开关一样,我们可以用 Preferences 把 is24Hour 这个布尔值存到本地。应用启动时读取,退出时或切换时保存。这个逻辑非常轻量,总共不到 10 行代码。
在 aboutToAppear 里,用 getSync('is24Hour', true) 读取出上次的选择,默认值是 true(24 小时制)。在按钮的 onClick 里,除了更新 @State 变量,还调用 putSync 和 flush 把新值写入 Preferences。这样用户下次打开应用时,会看到他上次选择的格式,不需要重新切换。
这个设计让小小的时钟多了一点“个性”。它不只是机械地显示时间,而是记住了你的偏好。这种细节,正是让一个工具从“能用”变成“好用”的关键。
不过要注意,TextClock 本身不会自动读取 Preferences。它只负责显示,存储逻辑需要我们自己写。但因为它对 format 属性的变化响应非常快,我们只需要在初始化时根据 Preferences 的值设置好 format,它就会自动按用户偏好显示。
四、完整代码——这一次,时间自己会走
以下代码适配 DevEco Studio 6.1.1 Beta1、SDK22 语法,Pura X Max 模拟器。新建 Empty Ability 项目,替换 entry/src/main/ets/pages/Index.ets。无需任何权限。

/*
* TextClock 组件 — 24/12小时制切换
* 环境:DevEco Studio 6.1.1 Beta1,Pura X Max 模拟器,SDK22
*/
import preferences from '@ohos.data.preferences';
@Entry
@Component
struct Index {
@State is24Hour: boolean = true;
private pref: preferences.Preferences | null = null;
async aboutToAppear(): Promise<void> {
let context = getContext(this);
this.pref = preferences.getPreferencesSync(context, { name: 'clock_settings' });
try {
this.is24Hour = this.pref.getSync('is24Hour', true) as boolean;
} catch (e) {
this.is24Hour = true;
}
}
// 切换时间制式
private toggleFormat(): void {
this.is24Hour = !this.is24Hour;
if (this.pref) {
this.pref.putSync('is24Hour', this.is24Hour);
this.pref.flush();
}
}
build() {
Column() {
// 标题
Text('系统时钟')
.fontSize(26)
.fontWeight(FontWeight.Bold)
.margin({ top: 20, bottom: 10 })
Text('使用 TextClock 组件,无需定时器')
.fontSize(15)
.fontColor('#888')
.margin({ bottom: 30 })
// 日期显示
TextClock({
format: 'yyyy年MM月dd日 EEEE'
})
.fontSize(20)
.fontColor('#555555')
.margin({ bottom: 25 })
// 时间显示(根据格式切换)
TextClock({
format: this.is24Hour ? 'HH:mm:ss' : 'hh:mm:ss a'
})
.fontSize(64)
.fontWeight(FontWeight.Bold)
.fontColor('#E0E0E0')
.fontFamily('monospace')
.margin({ bottom: 30 })
// 切换按钮
Button(this.is24Hour ? '切换为 12 小时制' : '切换为 24 小时制')
.type(ButtonType.Capsule)
.fontSize(16)
.backgroundColor('#1976D2')
.fontColor(Color.White)
.onClick(() => { this.toggleFormat(); })
Text('💡 TextClock 自动更新,支持多种时间格式')
.fontSize(12)
.fontColor('#555555')
.margin({ top: 30 })
}
.width('100%')
.height('100%')
.backgroundColor('#000000')
.justifyContent(FlexAlign.Center)
}
}
这份代码比我们之前写的任何时钟都要简洁。没有 setInterval,没有 @State 时间变量,没有 updateTime 函数。所有的更新逻辑都被 TextClock 吃掉了,我们只需要关心 format 和那个控制 24 小时制的开关。Preferences 的加入,让用户的格式偏好得以持久化,细节体验更完整。
五、运行效果
把代码粘贴进 DevEco Studio,Run 到 Pura X Max 模拟器。纯黑的屏幕上浮现出两行文字:上方是“2026年6月11日 星期四”,下方是巨大的“14:25:03”,等宽粗体,秒数在跳动。这些数字不需要任何代码驱动,它们自己就知道该显示什么,自己就知道该什么时候变。点击下方按钮“切换为 12 小时制”,时间瞬间变成“02:25:03 下午”。再点一下,又切回 24 小时制。日期在午夜会自动跳到下一天,星期也会自动更新。整个过程你找不到任何 setInterval 的痕迹,却拥有一个完美的数字时钟。退出应用再重新打开,时间格式依然是上次选择的 12 小时制。时钟不卡、不慢、不耗电,像一个训练有素的内置管家。


总结
这个简单的小工具,让我们看到了一种更高级的开发方式:使用框架提供的高级组件,替代手写的定时器和格式化逻辑。通过它,你可以学到:
- TextClock 组件的用法:
format属性控制显示格式,支持 Java 兼容的日期时间模式,组件内部自动更新,无需手动维护定时器。 - 12/24 小时制的切换:通过
HH和hh的区别,以及a标记,一键改变显示风格。 - Preferences 持久化偏好:记住用户的格式选择,让应用有“记忆”。
- 声明式 UI 的便利性:属性变化时组件自动响应,我们只需要操作状态变量,其余交给框架。
所以,下次如果你需要在 HarmonyOS 应用里显示时间,别急着写 setInterval。先想一想:有没有现成的组件?翻一翻文档,你会发现 TextClock 就像一颗被埋没的宝石,不起眼,但很闪亮。把时间的交给框架,把省下来的精力留给更有趣的事情——这大概就是一个成熟开发者应该具备的“偷懒”智慧吧。
774

被折叠的 条评论
为什么被折叠?



