Skip to content

Commit a844a77

Browse files
Add lunar_day_tz option and sky command
Introduce a configurable lunar-day timezone and a new 'sky' query. Key changes: - Add lunar_day_tz fields to CLI arg structs, core compute options, and result models; propagate canonical TZ parsing through conversion, at, day, monthview, and batch commands so lunar date mapping can use a selectable civil-day boundary. - Add config support: load/save default_lunar_day_tz, BOM stripping on read, resolve_lunar_day_tz() and default_lunar_day_tz_for_lang() helpers. - Update i18n: day_rule_note now accepts lunar_day_tz and strings updated in catalogs/prompts; interactive prompts and usage include sky and lunar_day_tz options. - Add Sky-related types and API (SkyMode, SkyPick, SkyPos, calc_sky_pos) and wire up a new cmd_sky (src/query/cmd_sky.cpp) and interactive sky UI (run_skyint), plus CLI dispatch and usage text. - Include lunar_day_tz in JSON/text metadata and notes; adjust date/time computations to use civil_midjd/utc2civil with lunar_day_tz where appropriate. This change enables selecting the civil-day timezone used to determine lunar-day boundaries and adds a sky-position query feature.
1 parent 4af99fa commit a844a77

27 files changed

+1222
-95
lines changed

include/lunar/cli_query.hpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ struct AtArgs{
1010
std::string time_raw;
1111
std::string input_tz="+08:00";
1212
std::string tz="+08:00";
13+
std::string lunar_day_tz="+08:00";
1314
std::string format="txt";
1415
std::string out;
1516
bool pretty=true;
@@ -40,6 +41,7 @@ struct ConvArgs{
4041

4142
std::string input_tz="+08:00";
4243
std::string tz="+08:00";
44+
std::string lunar_day_tz="+08:00";
4345
std::string format="txt";
4446
std::string out;
4547
bool pretty=true;
@@ -54,6 +56,7 @@ void cli_conv(const ConvArgs&args);
5456

5557
int cmd_at(const std::vector<std::string>&args);
5658
int cmd_conv(const std::vector<std::string>&args);
59+
int cmd_sky(const std::vector<std::string>&args);
5760
int cmd_day(const std::vector<std::string>&args);
5861
int cmd_mview(const std::vector<std::string>&args);
5962
int cmd_next(const std::vector<std::string>&args);
@@ -68,6 +71,7 @@ int cmd_comp(const std::vector<std::string>&args);
6871

6972
void use_at();
7073
void use_conv();
74+
void use_sky();
7175
void use_day();
7276
void use_mview();
7377
void use_next();

include/lunar/core.hpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ struct GanzhiComputeOptions{
1111
std::string date_text;
1212
std::string at_time="12:00:00";
1313
std::string tz="+08:00";
14+
std::string lunar_day_tz="+08:00";
1415
HliRuleSet hli_rules=make_hli_rule_set(HliProfileCode::Folk);
1516
};
1617

@@ -27,6 +28,7 @@ struct GanzhiMonthComputeOptions{
2728
int month=0;
2829
std::string at_time="12:00:00";
2930
std::string tz="+08:00";
31+
std::string lunar_day_tz="+08:00";
3032
HliRuleSet hli_rules=make_hli_rule_set(HliProfileCode::Folk);
3133
};
3234

@@ -46,6 +48,7 @@ struct DayComputeOptions{
4648
std::string date_text;
4749
std::string at_time="12:00:00";
4850
std::string tz="+08:00";
51+
std::string lunar_day_tz="+08:00";
4952
bool quiet=false;
5053
bool include_events=true;
5154
bool include_astro=false;

include/lunar/i18n.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ std::string to_zh_hant(const std::string&text);
3838

3939
std::string tz_note();
4040

41-
std::string day_rule_note();
41+
std::string day_rule_note(const std::string&lunar_day_tz="+08:00");
4242

4343
std::string tr_event_name(const std::string&kind,const std::string&code,
4444
const std::string&fallback="");

include/lunar/interact.hpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ struct InterCfg{
1414
std::vector<std::string> bsp_list;
1515
std::string default_tz="+08:00";
1616
std::string default_lang="zh";
17+
std::string default_lunar_day_tz;
1718
std::string def_fmt="txt";
1819
std::string hli_trad="folk";
1920
std::string hli_year_boundary;
@@ -31,6 +32,10 @@ bool load_cfg(InterCfg&cfg);
3132

3233
bool save_cfg(const InterCfg&cfg);
3334

35+
std::string default_lunar_day_tz_for_lang(const std::string&lang_code);
36+
37+
std::string resolve_lunar_day_tz(const InterCfg&cfg);
38+
3439
HliRuleSet hli_rules_from_cfg(const InterCfg&cfg);
3540

3641
bool file_ok(const std::string&path);

include/lunar/models.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ struct AtData{
4545
std::string time_raw;
4646
std::string tz_in;
4747
std::string display_tz;
48+
std::string lunar_day_tz="+08:00";
4849
double jd_utc=0.0;
4950
double jd_tdb=0.0;
5051
std::string utc_iso;
@@ -75,6 +76,7 @@ struct DayResult{
7576
std::string date_text;
7677
std::string at_time;
7778
std::string tz;
79+
std::string lunar_day_tz="+08:00";
7880
double hli_lon_deg=120.0;
7981
bool inc_astro=false;
8082
std::string astro_mode_text="less";

include/lunar/star.hpp

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#pragma once
22

33
#include<cstddef>
4+
#include<limits>
45
#include<string>
56
#include<vector>
67

@@ -84,15 +85,46 @@ struct AstroObs{
8485
double h_m=0.0;
8586
};
8687

88+
enum class SkyMode{
89+
All,
90+
Pick,
91+
};
92+
93+
struct SkyPick{
94+
SkyMode mode=SkyMode::All;
95+
std::vector<std::string> picks;
96+
};
97+
98+
struct SkyPos{
99+
std::string kind;
100+
std::string code;
101+
std::string name;
102+
std::string region;
103+
bool is_solar_system=false;
104+
bool is_juxing=false;
105+
double mag_v=std::numeric_limits<double>::quiet_NaN();
106+
double ra_deg=std::numeric_limits<double>::quiet_NaN();
107+
double dec_deg=std::numeric_limits<double>::quiet_NaN();
108+
double az_deg=std::numeric_limits<double>::quiet_NaN();
109+
double alt_deg=std::numeric_limits<double>::quiet_NaN();
110+
};
111+
87112
StarMode parse_star_mode(const std::string&text);
88113

89114
StarPick make_star_pick(StarMode mode,const std::string&pick_csv);
90115

116+
SkyMode parse_sky_mode(const std::string&text);
117+
118+
SkyPick make_sky_pick(SkyMode mode,const std::string&pick_csv);
119+
91120
std::vector<StarApp> calc_star_app(EphRead&eph,double jd_utc,
92121
const StarPick&pick);
93122

94123
MoonXg calc_moon_xg(EphRead&eph,double jd_utc);
95124

125+
std::vector<SkyPos> calc_sky_pos(EphRead&eph,double jd_utc,
126+
const AstroObs&obs,const SkyPick&pick);
127+
96128
std::vector<AstroEvt> calc_astro_evt(EphRead&eph,double jd_utc_start,
97129
double jd_utc_end,const StarPick&pick,
98130
const AstroObs&obs=AstroObs{});

src/cli/usage.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@ void use_main(){
101101
<<" lunar event ...\n"
102102
<<" lunar at ...\n"
103103
<<" lunar convert ...\n"
104+
<<" lunar sky ...\n"
104105
<<" lunar day ...\n"
105106
<<" lunar monthview...\n"
106107
<<" lunar next ...\n"
@@ -124,6 +125,7 @@ void use_main(){
124125
<<" lunar event --help\n"
125126
<<" lunar at --help\n"
126127
<<" lunar convert --help\n"
128+
<<" lunar sky --help\n"
127129
<<" lunar day --help\n"
128130
<<" lunar monthview --help\n"
129131
<<" lunar next --help\n"

src/entry.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,9 @@ int run_cli_args(const std::vector<std::string>&args){
136136
if(first=="convert"){
137137
return cmd_conv(tail_for(first));
138138
}
139+
if(first=="sky"){
140+
return cmd_sky(tail_for(first));
141+
}
139142
if(first=="day"){
140143
return cmd_day(tail_for(first));
141144
}

src/i18n/catalog_interact.cpp

Lines changed: 45 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@ const Item kItems[]={{"done_back",
9898
{"menu.almanac","黄历/宜忌","Almanac","黄暦","황력"},
9999
{"menu.config","配置查看/修改","Config show/set","設定表示/変更","설정 보기/수정"},
100100
{"menu.completion","补全脚本生成","Completion script","補完スクリプト生成","완성 스크립트"},
101+
{"menu.sky","观星位置查询","Sky positions","天体位置照会","천체 위치 조회"},
101102
{"menu.switch_bsp",
102103
"重新选择 / 下载 BSP 星历文件",
103104
"Select/Download BSP",
@@ -131,6 +132,46 @@ const Item kItems[]={{"done_back",
131132
"Output format: 1) json 2) txt 3) geojson (default json): ",
132133
"出力形式: 1) json 2) txt 3) geojson(既定 json): ",
133134
"출력 형식: 1) json 2) txt 3) geojson (기본 json): "},
135+
{"prompt.sky_time",
136+
"请输入观测时刻(例如 2025-06-01T20:00:00+08:00):",
137+
"Enter observation time (e.g. 2025-06-01T20:00:00+08:00): ",
138+
"観測時刻を入力(例: 2025-06-01T20:00:00+08:00): ",
139+
"관측 시각을 입력하세요(예: 2025-06-01T20:00:00+08:00): "},
140+
{"prompt.sky_input_tz",
141+
"若输入不带时区,解析时区(默认 +08:00):",
142+
"Input timezone when time has no TZ (default +08:00): ",
143+
"入力値にタイムゾーンが無い場合の解釈 TZ(既定 +08:00): ",
144+
"입력값에 시간대가 없을 때 해석할 TZ(기본 +08:00): "},
145+
{"prompt.sky_display_tz",
146+
"输出显示时区(默认 +08:00):",
147+
"Display timezone (default +08:00): ",
148+
"表示タイムゾーン(既定 +08:00): ",
149+
"표시 시간대(기본 +08:00): "},
150+
{"prompt.sky_lat",
151+
"请输入观测点纬度(度):",
152+
"Enter observer latitude in degrees: ",
153+
"観測地の緯度(度)を入力: ",
154+
"관측 지점 위도(도)를 입력하세요: "},
155+
{"prompt.sky_lon",
156+
"请输入观测点经度(度,东经为正):",
157+
"Enter observer longitude in degrees (east positive): ",
158+
"観測地の経度(度、東経正)を入力: ",
159+
"관측 지점 경도(도, 동경 양수)를 입력하세요: "},
160+
{"prompt.sky_height",
161+
"可选:观测点海拔米数(默认 0):",
162+
"Optional: observer height in meters (default 0): ",
163+
"任意: 観測地の標高メートル(既定 0): ",
164+
"선택: 관측 지점 해발(m, 기본 0): "},
165+
{"prompt.sky_mode",
166+
"查询模式:1) all 2) pick(默认 all):",
167+
"Query mode: 1) all 2) pick (default all): ",
168+
"照会モード: 1) all 2) pick(既定 all): ",
169+
"조회 모드: 1) all 2) pick (기본 all): "},
170+
{"prompt.sky_pick",
171+
"请输入目标列表(逗号分隔,例如 sun,moon,Spica):",
172+
"Enter targets (comma separated, e.g. sun,moon,Spica): ",
173+
"対象一覧を入力(カンマ区切り、例: sun,moon,Spica): ",
174+
"대상 목록을 입력하세요(쉼표 구분, 예: sun,moon,Spica): "},
134175
{"prompt.monthview_ym",
135176
"请输入年月 YYYY-MM:",
136177
"Enter year-month YYYY-MM: ",
@@ -197,10 +238,10 @@ const Item kItems[]={{"done_back",
197238
"設定操作: 1) show 2) set(既定 show): ",
198239
"설정 작업: 1) show 2) set (기본 show): "},
199240
{"prompt.config_key",
200-
"请输入配置键(def_bsp|bsp_dir|bsp_list|default_tz|default_lang|def_fmt|hli_trad|hli_year_boundary|hli_month_boundary|hli_leap_month_mode|hli_day_boundary|def_prety):",
201-
"Enter config key (def_bsp|bsp_dir|bsp_list|default_tz|default_lang|def_fmt|hli_trad|hli_year_boundary|hli_month_boundary|hli_leap_month_mode|hli_day_boundary|def_prety): ",
202-
"設定キーを入力(def_bsp|bsp_dir|bsp_list|default_tz|default_lang|def_fmt|hli_trad|hli_year_boundary|hli_month_boundary|hli_leap_month_mode|hli_day_boundary|def_prety): ",
203-
"설정 키 입력(def_bsp|bsp_dir|bsp_list|default_tz|default_lang|def_fmt|hli_trad|hli_year_boundary|hli_month_boundary|hli_leap_month_mode|hli_day_boundary|def_prety): "},
241+
"请输入配置键(def_bsp|bsp_dir|bsp_list|default_tz|default_lang|default_lunar_day_tz|def_fmt|hli_trad|hli_year_boundary|hli_month_boundary|hli_leap_month_mode|hli_day_boundary|def_prety):",
242+
"Enter config key (def_bsp|bsp_dir|bsp_list|default_tz|default_lang|default_lunar_day_tz|def_fmt|hli_trad|hli_year_boundary|hli_month_boundary|hli_leap_month_mode|hli_day_boundary|def_prety): ",
243+
"設定キーを入力(def_bsp|bsp_dir|bsp_list|default_tz|default_lang|default_lunar_day_tz|def_fmt|hli_trad|hli_year_boundary|hli_month_boundary|hli_leap_month_mode|hli_day_boundary|def_prety): ",
244+
"설정 키 입력(def_bsp|bsp_dir|bsp_list|default_tz|default_lang|default_lunar_day_tz|def_fmt|hli_trad|hli_year_boundary|hli_month_boundary|hli_leap_month_mode|hli_day_boundary|def_prety): "},
204245
{"prompt.config_value",
205246
"请输入配置值:",
206247
"Enter config value: ",

src/i18n/lang.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,15 @@ std::string day_rule_note(){
210210
"음력 날짜 판정은 UTC+8 민간 날짜 기준으로 고정됩니다.");
211211
}
212212

213+
std::string day_rule_note(const std::string&lunar_day_tz){
214+
return pick(("农历判日按 "+lunar_day_tz+" 民用日执行").c_str(),
215+
("Lunar day boundaries follow civil day "+lunar_day_tz+".")
216+
.c_str(),
217+
("旧暦の日付判定は "+lunar_day_tz+" の民用日で実行します。")
218+
.c_str(),
219+
("?? ?? ??? "+lunar_day_tz+" ?? ?? ???? ?????.").c_str());
220+
}
221+
213222
std::string tr_lunar_month(int month_no,bool is_leap,const std::string&fallback){
214223
if(month_no<1||month_no>12){
215224
return fallback.empty()?std::to_string(month_no):fallback;

0 commit comments

Comments
 (0)