Skip to content

玛雅13月亮历新年开始日与七年锚点年份可配置(默认 07-26 新年 / 07-25 无时间日) #330

Description

@liujuanjuan1984

TL;DR

将玛雅 13 月亮历的「新年开始日」从硬编码的 07-26(无时间日 07-25)扩展为用户偏好:在 /config 设置页可把任意公历「月-日」(例如用户生日)设为新年开始日,前一天作为无时间日;七年周期锚点改为精确到年。所有消费新年 / 无时间日 / 七年周期的路径统一经由 calendar adapter 获取,避免各处重复实现。

背景

  • 现状:MayanCalendarAdapter.year_start() 硬编码 date(year, 7, 26);模块级 is_mayan_day_out_of_time() 硬编码 month == 7 and day == 25;七年锚点 preferences.calendar_seven_year_anchor_date 为完整日期(YYYY-MM-DD)。
  • 需求:新年开始日精确到公历「月-日」(默认 07-26),此日的前一天为无时间日;七年周期起始精确到「年」。
  • 现有设计已把历法视为用户偏好(calendar.system / calendar.first_day_of_week / calendar.seven_year_anchor_date),且已有 MayanCalendarAdapter 作为周期边界唯一实现,本需求是该方向的自然延伸,不引入新的架构模式。

方案评估(对照当前代码最佳实践)

需求合理且仍然有效。实施应以 MayanCalendarAdapter 为唯一事实来源,避免在 stats、task_queries、habit_support、web routers 各处重复推导:

  1. MayanCalendarAdapter 增加新年开始日参数(MM-DD,默认 07-26):year_start()day_offset()month_range()/week_range()/year_range()/seven_year_range() 均基于该参数。
  2. 将 DOOT 判定收敛为 adapter 方法(当前是硬编码的模块级函数,且不带历法参数语义),所有调用点(timelog_stats._week_month_excluded_local_dateget_timelog_stats_groupby_area_for_rangeiter_calendar_periods)改为从偏好取参。
  3. get_calendar_adapter / get_calendar_period_range / iter_calendar_periods 的参数从「完整锚点日期」演进为「新年开始日 + 七年锚点年」,并同步 config.py(新增字段/校验/默认值/序列化)、application/configuration.py(SUPPORTED_CONFIG_KEYS 与 set 分支)、lifeos_web/routers/preferences.py(_CONFIG_KEY_MAP/_META/取值分支)。
  4. 消费方统一由 get_preferences_settings() 取参:task_queries.py(3 处)、habit_support.py(4 处)、web routers/stats.pyrouters/tasks.py
  5. 前端 lifeos-web 同步:MayanCalendarAdapter.tscreateCalendarAdapter.tsuseCalendarAdapter.tssettingsConfig.tsxSettingsPage.tsx 与 en/zh 文案(现文案写明「07-26 为新年」需改为可配置描述)。
  6. CLI/Web 用户可见文案(如 cli_messages.json 中「无时间日(7 月 25 日)」)随行为变化同步更新。

关键设计点与风险

  • 闰日与无时间日的交互:现有实现把 2/29 视为不参与月亮/周序号的内插日(_leap_day 偏移修正)。新年开始日可配置后,2/29 可能落在年度边界附近(如新年 03-01 时,前一天恰为 2/29)。需要显式定义并文档化语义(建议:2/29 仍为内插日不改变月亮/周序号;与「新年前一天」重合时以无时间日为准,或把 02-29 设为非法新年开始日),并补充闰年边界测试。
  • 七年锚点兼容:现有 calendar_seven_year_anchor_date(YYYY-MM-DD)已可能被持久化。建议拆分为 calendar_mayan_new_year_start(MM-DD)+ calendar_seven_year_anchor_year(YYYY),并提供一次性迁移(取旧值年份;月-日部分仅作为旧语义留存)。公历七年周期本就只取年份,行为兼容。
  • 回归面:默认值必须保持 07-26 新年 / 07-25 无时间日,现有 tests/test_calendar_adapter.pytest_timelog_stats.pytest_web_cli.pytest_domain_services_tasks_and_habits.py 中大量 7/25、7/26 断言需改为参数化默认值用例 + 自定义新年用例。

相关 open 工作(建议协同)

验收标准

实施清单

  • 后端:config.pyapplication/configuration.pyapplication/calendar_adapter.pydb/services/timelog_stats.pydb/services/task_queries.pydb/services/habit_support.pylifeos_web/routers/preferences.pylifeos_web/routers/stats.pylifeos_web/routers/tasks.py、CLI help/locales。
  • 前端(lifeos-web 独立 PR):utils/calendar/MayanCalendarAdapter.tscreateCalendarAdapter.tshooks/useCalendarAdapter.tsconfig/settingsConfig.tsxpages/SettingsPage.tsx、en/zh locales、相关测试。

Related #192 #324 #329

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions