我的佳明手表什么都好,就是表盘上没农历。作为中国人,手表上看不到"今天初几",总觉得少了点什么。佳明官方表盘和大部分第三方表盘都是纯英文的,别说农历了,连星期都是 Mon、Tue。我很喜欢的开源表盘 Segment34 MkII 也不例外——34段数码管的风格非常惊艳、高度可定制的字段布局,几乎满足了我对表盘的全部审美,唯独它是全英文的。
于是就有了这个 Segment34 中文版:在原版的基础上做了完整汉化(设置菜单、天气、星期、摄氏度图标),并添加了农历和二十四节气显示。整个过程前后迭代了三个月、发布了二十多个版本,现在已经在佳明 Connect IQ 商店上架,完全免费。这篇文章记录一下整个汉化过程和农历模块的实现思路。

认识 Segment34 MkII
先介绍一下原版。Segment34 MkII 是开发者 ludw 做的一款开源表盘(Monkey C 编写),最大的特色是34段数码管(LED 段码)拟物风格:数字不是普通的字体,而是模拟老式 LED 显示屏的段码渲染,还带四种"笔刷"质感(点阵、混合、线条等)。表盘支持四套内置配色主题外加自定义主题(用作者提供的在线主题设计器生成),几乎每个字段都可以自定义显示内容,还支持点击字段直接跳转到对应的 widget。

原作者在 FAQ 里被问得最多的问题就是"能不能翻译成某某语言",他的回复是"工作量大,在我的待办清单上,但别 promises"。确实,等是等不来的,好在他把源码开源了——自己动手,丰衣足食。
汉化的第一层:字符串资源替换
Connect IQ 的应用是一个叫 Monkey C 的语言写的,资源管理机制和 Android 很像:默认资源放在 resources 目录,如果你针对特定语言建一个 resources-zhs(简体中文)目录,那么当手表系统语言是简体中文时,同名资源会自动覆盖默认资源。设置菜单里所有选项、天气描述、星期名称,在代码里都只是一个 string id 引用,所以第一层汉化非常朴素:把默认的 strings.xml 在 resources-zhs/strings/strings.xml 里翻译一遍。
<strings>
<string id="WEATHER_0">晴朗</string>
<string id="WEATHER_1">局部多云</string>
<string id="WEATHER_2">大部分多云</string>
<string id="WEATHER_3">雨</string>
<string id="WEATHER_4">雪</string>
<!-- ...共 30 多种天气描述 -->
</strings>这一步做完,手表系统语言设为简体中文的用户就能看到全中文的设置菜单了——包括表盘的全部三十多项设置:数据更新频率、顶部显示、各个字段显示什么、日期格式、农历选项等等。佳明手机 App 里的设置页面会直接用上这些翻译。

汉化的第二层:表盘上的字不是"文字",是"图"
如果只是设置菜单汉化,那这个项目半小时就能干完。真正的麻烦在于:表盘上显示的一切数字和文字,用的都不是系统字体,而是作者自制的位图字体(BMFont 格式的 .fnt + .png 图集)。段码风格的数字、英文星期、天气图标,全都是画在一张张图集里的字形贴图。这些字体里当然一个汉字都没有。
摆在面前的选择有两个:一是给点阵风格的字体做汉字字形,二是给"线条"风格的字体做汉字。点阵风格要保证和原版像素风一致,一个汉字至少 16×16 像素起步,而表盘用的字体有好几种尺寸,全部做下来工作量巨大;"线条"风格是把段码笔画用斜线画出来的,汉字用线条风格来画反而和数字部分很搭。所以我选择了后者:用位图字体工具往线条风格的字体图集里补汉字字形——天干地支、月名日名、节气名、星期名,一个个字符按原字体的基线、间距对齐画进去,然后手工微调了好几轮像素(git 历史里"细微修整了一下24px字体"提交了好几次)。
点阵风格的字体不做汉字,所以文档里专门写了一条 FAQ:请将设置中"小点阵字体变体"设为默认的"线条",以确保能正常显示汉字。
字体补完并不意味着一劳永逸,后面还陆续踩了一串"方框"坑——凡是被显示出来的字符在字体图集里没有字形,就会渲染成方框:
- 顶部和底部字段显示温度时,摄氏度
℃图标是方框——原版用一个特殊字形表示度数符号,我的字体里漏了它; - AOD(息屏常显)模式下时钟下方的星期是方框——AOD 用的是另一套小号字体,我给它补字形时忘了星期;
- 训练状态偶尔显示方框——Garmin 的训练状态文案里有个别生僻字,我又往字体里补了几个汉字。
这一轮下来我总结出一条经验:汉化一个表盘,"翻译文本"只占两成工作量,剩下八成都在和字体图集较劲——你得把所有可能被显示出来的字符都提前塞进字体,一个都漏不得。
重头戏:农历显示
汉化只是让表盘"说中文",农历才是这个项目的灵魂。表盘的显示行是可配置的,我把农历作为时钟上方第二行的默认内容,也可以设置到其他位置。
实现农历第一个绕不开的问题是:表盘应用的内存限制非常苛刻,老款设备只有 128KB 级别的内存给一块表盘用。常见的做法是引入一份完整的农历数据表(每一年用几个位掩码表示大小月和闰月)加上算法,但那样代码体积和运行时开销都偏大,v1.x 版本就是这么写的,在部分老设备上跑不动,后来我干脆重写了整个农历模块,改成了纯查表方案。
思路很简单:农历算法再复杂,落到"2026 到 2030 这五年"这个有限范围内,所有信息都可以预计算成三张整数表:
LUNAR_OFFSET_DAYS:60 个元素,每个农历月初一相对 2026-01-01 的天数偏移。有了它,任何公历日期算出相对天数后做一次线性查找,就能定位到它落在哪个农历月、是这个月的第几天;LEAP_MONTH_OFFSETS:这五年里哪几个月是闰月(2026—2030 年间有闰六月等两个闰月),顺便标记当前月是否就是闰月;SOLAR_TERMS_OFFSETS:五年里全部 120 个节气的相对天数,用来查"今天是哪个节气"或者"距离下一个节气还有几天"。
显示所需的文本也全部压成几个字符串常量:天干地支各一个字符串、"正月二月……冬月腊月"一个月名字符串、"初一初二……廿九三十"一个日名字符串、24 个节气一个字符串,需要哪个就按索引 substring 切两个字符出来,连数组都省了。

核心的月定位逻辑大概长这样:
// 返回值: [农历年份, 农历月份, 农历日期, 是否闰月]
private function getLunarDate(year, month, day) as Array<Number> {
var targetDays = getDayCount(year, month, day); // 相对 2026-01-01 的天数
// 在月首偏移表里找到 targetDays 所属的农历月
var baseMonthIdx = 0;
for (var i = 0; i < lunarSize; i++) {
if (LUNAR_OFFSET_DAYS[i] > targetDays) {
baseMonthIdx = i - 1;
break;
}
}
// 闰月修正:当前月之前有几个闰月、当前月本身是否闰月
var leapCount = 0;
var isLeap = 0;
// ...遍历 LEAP_MONTH_OFFSETS 统计...
var realMonthOffset = baseMonthIdx - leapCount;
var lunarYear = START_YEAR + Math.floor(realMonthOffset / 12);
var lunarMonth = realMonthOffset % 12 + 1;
var lunarDay = targetDays - LUNAR_OFFSET_DAYS[baseMonthIdx] + 1;
return [lunarYear, lunarMonth, lunarDay, isLeap];
}整个农历模块 217 行 Monkey C,覆盖 2026—2030 五年,支持闰月、干支纪年、二十四节气,运行时只需要一次线性查找加几次减法,内存占用相比完整农历库小了一个量级。后续版本又做了两轮针对性优化(v2.4"进一步优化农历模块以节省运行内存"),把老设备也照顾到了。代价是五年之后表盘上的农历会"过期",到时候发个新版本更新三张表就行——我给过期的情况留了个显眼的提示串,看到它就知道该升级了。
节气显示做了个小设计:如果今天是节气当天就直接显示节气名,否则显示"距离下一个节气还有几天",比如"+10清明"。这样一年里节气只有 24 天,剩下三百多天这一栏也有信息量。

最后呈现出来的表盘就是开头那张上手图的样子,从上到下依次是:日出日落和月相、汉化的天气状况和温度、农历行(丙午年 二月初八 +10清明)、七段管大时钟、中文星期和日期、底部自定义数据字段。中文星期和"周一"到"周日"也是字体图集里画出来的。
设备兼容:另一个大坑
表盘不同于手机 App,要面对佳明几十款屏幕形状、分辨率、内存各不相同的设备。这个项目的做法是在 manifest 里声明支持的设备列表,再用 Connector IQ 注解按分辨率分派排版资源(Round240/260/280/360/390/416/454/Square 等),编译时通过 excludeAnnotations 只保留目标设备对应的变体。为此踩过的坑包括:
- 有用户反馈 Forerunner 255S 无法安装:根因是 manifest 的设备列表只列了 255/255m(260×260 屏),没有 255S(218×218 屏),而 218 宽度下时钟字体的排版宽度是写死的,放不下,需要单独做一套字号。权衡之后我放弃了对它的支持,并向用户说明可以试试"Segment34 中文精简版";
- F6S、F6SP、245、945 等老设备内存太小,农历模块初版跑不动——这也是后来把农历重写成纯查表的直接原因,但最终这几款还是被移出了支持列表;
- Fenix 9 系列发布后,官方 SDK 更新了设备定义,编译环境里要先补齐 7 个 fenix9 设备描述文件才能出包(本机 SDK 目录缺这些定义时,编译任何设备都会报错,这个坑坑了我一整天)。
上架商店与持续迭代
2026 年 3 月 24 日第一次提交代码,3 月 26 日第一个完全汉化版,3 月 27 日农历上线,此后一边在佳明论坛和商店评论区收集反馈一边修修补补,一直迭代到现在的 v2.5.6:
| 时间 | 版本 | 内容 |
|---|---|---|
| 2026-03-24 | v1.x | 初版:中文星期、重写农历算法以适应老设备、AMOLED 大字体 |
| 2026-03-26 | v2.0 | 完全汉化:天气、星期、摄氏度图标全部中文化 |
| 2026-03-27 | v2.1 | 时钟上方两行和下方都可以设置为显示农历 |
| 2026-03-30 | v2.3 | 补训练状态汉字,修复 AOD 星期方框 |
| 2026-04-02 | v2.4 | 进一步优化农历模块节省内存,修复电量条形图显示异常 |
| 2026-09-08 | v2.5.0 | 新增 Fenix 9 系列支持,重绘更精细的月相图标 |
| 2026-09-15 | v2.5.6 | 设置菜单新增月相阴影显示开关 |
比较有意思的几个反馈驱动的小修复:有用户反映身体压力偶尔不显示,加了缓存;有用户反映湿度缓存过期后表盘崩溃,排查后发现是原版逻辑的空指针问题(顺手给原版 bug 也修了);还有用户希望默认底部布局不用自己调,就把默认值改成了大多数人不看文档也能正常显示的 334。
写在最后
这个项目技术上并不复杂,甚至可以说"土"——位图字体、查表算法、字符串覆盖,没有一处用到了炫技的东西。但它是那种"自己真的需要"的项目:现在我抬腕就能看到农历和节气,这一行的信息密度可能是整个表盘最高的。
再次感谢原作者 ludw 的开源精神,这个中文版完全免费上架在佳明 Connect IQ 商店:Segment34中文版,如果你的手表在支持列表里,欢迎安装试用。旧款设备(F6S、245、945 等)可以试试"Segment34 中文精简版"。
0 条评论 最新
暂无评论。