给卡帕多奇亚民宿做的多语言小站,踩了时区和字体的坑

上个月接了个小单:卡帕多奇亚格雷梅一家民宿的官网页,要求土耳其语、英语、中文三语切换,能看房型、查空房、跳转WhatsApp预订。甲方给的原始素材是一堆手机拍的房间图和一份Word文档,里面写着「旺季」「淡季」两套价格,但没写具体日期。我用的环境是 Vite + 原生 JS,没上框架,想着这种单页用不着,结果后面全在补窟窿。

先说空房查询。民宿老板的意思是「客人选日期,我们看有没有房」,但他没有PMS系统,只有一个手写的Excel。我做了个折中:把Excel导出成JSON,前端按日期区间过滤。核心逻辑就几行:

const nights = (a, b) =>
  Math.round((Date.parse(b) - Date.parse(a)) / 86400000);

function available(rooms, from, to) {
  return rooms.filter(r =>
    r.booked.every(([s, e]) =>
      Date.parse(to) <= Date.parse(s) || Date.parse(from) >= Date.parse(e)
    )
  );
}

注意这里我一开始用了 new Date('2024-09-01'),在伊斯坦布尔的机器上没事,部署到欧洲节点后日期整体偏移了一天。原因是纯日期字符串被当成UTC午夜解析,而本地时区是UTC+3。后来统一改成 Date.parse 加显式 T00:00:00+03:00,因为土耳其2016年后全年UTC+3,没有夏令时,这个常量可以写死。代价是如果以后政策变了,得回来改这一处。

字体是第二个坑。土耳其语有 ğ、ş、ı、İ 这几个字符,我图省事用了系统默认的 system-ui,在Windows上 ı 和 i 的大写映射直接错乱,「Istanbul」显示成「İstanbul」还算好的,表单里用户输入的小写 ı 转大写变成了 I,后端比对失败。后来换了带拉丁扩展的 Inter 子集,用 unicode-range 只加载 U+011E-011F, U+015E-015F, U+0130-0131 这几段,体积多了不到8KB。

会失效的地方:一是Excel里老板用「9月1日」这种中文写法,导出JSON时直接变成空字符串,我加了个手工映射表,但每次他改价格我都得重新对一遍;二是WhatsApp跳转链接里带土耳其语模板消息时,encodeURIComponent 之后 ğ 会变成 %C4%9F,部分安卓机打开WhatsApp不认,最后改成只传房型ID,消息模板放服务端拼。

你们接这种小语种静态站的时候,日期和字符集是分开处理还是统一在构建时转一道?我现在是前者,但每次加语言都心虚。

0
赞同度 100% · 0 条评论 · 1 阅读

0 条评论

支持 Markdown · 回复会实时推送给对方

还没有评论,写下第一条。