Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Parse TZN timezone headers #657

Merged
merged 1 commit into from
Jan 6, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions __snapshots__/test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,7 @@ Object {
],
"taskNumber": 2,
},
"timezone": 0,
}
`;

Expand Down
216 changes: 216 additions & 0 deletions fixtures/20241007TZN.igc
Original file line number Diff line number Diff line change
@@ -0,0 +1,216 @@
AXSX004 SKYTRAXX
HFPLTPILOT:Stefan Walter
HFDTM100GPSDATUM:WGS-84
HFRFWFIRMWAREVERSION:202401301017
HFRHWHARDWAREVERSION:2.1
HFTZNTIMEZONE:+5.50
HFSITSITE:Bir_Billing_Golf Cour
HFDTE071024
B0626473205699N07642351EA0222802387
B0626483205699N07642351EA0222802387
B0626493205699N07642351EA0222802388
B0626503205699N07642351EA0222802388
B0626513205699N07642351EA0222802387
B0626523205699N07642351EA0222802387
B0626533205699N07642351EA0222802387
B0626543205699N07642351EA0222802388
B0626553205698N07642351EA0222802388
B0626563205698N07642351EA0222802388
B0626573205698N07642350EA0222702387
B0626583205697N07642350EA0222702386
B0626593205697N07642349EA0222602386
B0627003205697N07642348EA0222602386
B0627013205697N07642347EA0222602386
B0627023205696N07642345EA0222302383
B0627033205694N07642344EA0222102381
B0627043205691N07642342EA0222102380
B0627053205688N07642340EA0221902378
B0627063205685N07642336EA0221502375
B0627073205683N07642330EA0221302373
B0627083205679N07642326EA0221502374
B0627093205676N07642321EA0221402374
B0627103205673N07642318EA0221402374
B0627113205668N07642315EA0221402373
B0627123205665N07642312EA0221202372
B0627133205661N07642308EA0221102371
B0627143205657N07642305EA0221102371
B0627153205653N07642301EA0221002370
B0627163205649N07642297EA0221102371
B0627173205646N07642293EA0221102371
B0627183205642N07642289EA0221202372
B0627193205640N07642285EA0221102371
B0627203205636N07642282EA0221102371
B0627213205633N07642278EA0221002370
B0627223205629N07642274EA0220902369
B0627233205625N07642271EA0221002370
B0627243205622N07642267EA0221102371
B0627253205619N07642264EA0221202372
B0627263205615N07642262EA0221202372
B0627273205612N07642259EA0221202371
B0627283205609N07642255EA0221202372
B0627293205605N07642251EA0221302372
B0627303205601N07642247EA0221302373
B0627313205598N07642243EA0221502375
B0627323205594N07642242EA0221602375
B0627333205590N07642240EA0221702376
B0627343205586N07642239EA0221802378
B0627353205582N07642239EA0221902379
B0627363205578N07642241EA0222102381
B0627373205576N07642243EA0222202382
B0627383205574N07642247EA0222202382
B0627393205574N07642252EA0222302382
B0627403205574N07642257EA0222002380
B0627413205576N07642263EA0221902379
B0627423205580N07642269EA0221902379
B0627433205586N07642272EA0222002380
B0627443205592N07642273EA0222002380
B0627453205598N07642271EA0222202382
B0627463205604N07642269EA0222202381
B0627473205609N07642264EA0222302383
B0627483205614N07642259EA0222402384
B0627493205618N07642253EA0222602386
B0627503205621N07642248EA0222802388
B0627513205625N07642244EA0223002390
B0627523205628N07642239EA0223002390
B0627533205630N07642234EA0223102391
B0627543205634N07642230EA0223102390
B0627553205639N07642226EA0223102391
B0627563205644N07642223EA0223102390
B0627573205650N07642221EA0223202392
B0627583205655N07642220EA0223302392
B0627593205660N07642220EA0223202392
B0628003205665N07642219EA0223002390
B0628013205671N07642219EA0222802388
B0628023205677N07642219EA0222802388
B0628033205683N07642219EA0223002390
B0628043205688N07642220EA0223202391
B0628053205693N07642221EA0223202392
B0628063205697N07642224EA0223202392
B0628073205702N07642226EA0223102390
B0628083205707N07642230EA0222902388
B0628093205711N07642236EA0222602386
B0628103205714N07642242EA0222602385
B0628113205716N07642249EA0222702387
B0628123205717N07642256EA0222802388
B0628133205717N07642262EA0223002390
B0628143205717N07642267EA0222902389
B0628153205718N07642272EA0222902388
B0628163205720N07642278EA0222902389
B0628173205724N07642283EA0222802387
B0628183205728N07642287EA0222802387
B0628193205732N07642291EA0223002390
B0628203205734N07642295EA0223002390
B0628213205733N07642301EA0222902388
B0628223205731N07642307EA0222802388
B0628233205728N07642311EA0222802388
B0628243205725N07642314EA0223002390
B0628253205722N07642315EA0223202391
B0628263205720N07642319EA0223002390
B0628273205717N07642321EA0222802387
B0628283205713N07642326EA0222602386
B0628293205710N07642330EA0222702387
B0628303205709N07642334EA0222802387
B0628313205707N07642336EA0222602385
B0628323205705N07642338EA0222302383
B0628333205703N07642339EA0222402384
B0628343205703N07642340EA0222502385
B0628353205703N07642340EA0222502384
B0628363205703N07642340EA0222502385
B0628373205703N07642340EA0222502385
B0628383205703N07642340EA0222502385
B0628393205703N07642340EA0222502385
B0628403205703N07642340EA0222502385
B0628413205703N07642340EA0222502385
B0628423205703N07642340EA0222502385
B0628433205703N07642341EA0222502385
B0628443205703N07642341EA0222502385
B0628453205703N07642341EA0222602386
B0628463205703N07642341EA0222602386
B0628473205703N07642342EA0222602386
B0628483205703N07642342EA0222602386
B0628493205703N07642343EA0222602386
B0628503205704N07642343EA0222702387
B0628513205704N07642344EA0222702387
B0628523205704N07642344EA0222702387
B0628533205704N07642345EA0222702387
B0628543205704N07642344EA0222702387
B0628553205704N07642344EA0222702387
B0628563205704N07642345EA0222702387
B0628573205704N07642345EA0222702387
B0628583205704N07642345EA0222702387
B0628593205703N07642345EA0222702387
B0629003205703N07642345EA0222702387
B0629013205703N07642345EA0222702387
B0629023205703N07642345EA0222702387
B0629033205703N07642346EA0222802388
B0629043205703N07642347EA0222802388
B0629053205703N07642347EA0222802388
B0629063205703N07642348EA0222802388
B0629073205702N07642348EA0222802388
B0629083205702N07642349EA0222802388
B0629093205702N07642349EA0222802388
B0629103205702N07642350EA0222802388
B0629113205702N07642350EA0222802388
B0629123205702N07642351EA0222902389
B0629133205702N07642351EA0222902389
B0629143205702N07642352EA0222902389
B0629153205702N07642352EA0222902389
B0629163205702N07642353EA0222902389
B0629173205701N07642353EA0222902389
B0629183205701N07642354EA0222902389
B0629193205701N07642355EA0222902389
B0629203205701N07642355EA0222902389
B0629213205701N07642355EA0222902389
B0629223205701N07642356EA0223002390
B0629233205701N07642356EA0223002390
B0629243205702N07642357EA0223002390
B0629253205702N07642357EA0223002390
B0629263205702N07642358EA0223002390
B0629273205702N07642358EA0223002390
B0629283205702N07642358EA0223002390
B0629293205702N07642358EA0223002390
B0629303205702N07642357EA0223002390
B0629313205702N07642358EA0223002390
B0629323205702N07642358EA0223002390
B0629333205702N07642358EA0223002390
B0629343205702N07642359EA0223002390
B0629353205702N07642359EA0223002390
B0629363205702N07642359EA0223002390
B0629373205702N07642359EA0223002390
B0629383205702N07642358EA0223002390
B0629393205702N07642358EA0223002390
B0629403205702N07642358EA0223002390
B0629413205702N07642358EA0223002390
B0629423205702N07642357EA0223002390
B0629433205702N07642357EA0223002390
B0629443205702N07642357EA0223002390
B0629453205702N07642356EA0223002390
B0629463205703N07642356EA0223002390
B0629473205703N07642356EA0223002390
B0629483205703N07642356EA0223002390
B0629493205702N07642356EA0223002390
B0629503205702N07642356EA0223002390
B0629513205702N07642356EA0223002390
B0629523205701N07642356EA0223002390
B0629533205701N07642356EA0223002390
B0629543205701N07642356EA0223002390
B0629553205700N07642356EA0222902389
B0629563205700N07642356EA0222902389
B0629573205700N07642356EA0222902389
B0629583205700N07642356EA0222902389
B0629593205700N07642356EA0222902389
B0630003205700N07642356EA0222902389
B0630013205700N07642356EA0222902389
B0630023205700N07642356EA0222902389
B0630033205700N07642356EA0222902389
B0630043205700N07642356EA0222902389
B0630053205700N07642356EA0222902389
LXSX;S1;TS:1728282407;TL:1728282605;AS:2387;AL:2389;AT:2392;AB:2369
LXSX;S1;XS:2;XD:0.74;SP:40.5;MC:1.0;MS:-1.2;NB:200
LXSX;S1;FL:0.9;TG:0;TC:0.0
LXSX;S1;X0:32.09498,76.70585
LXSX;S1;X1:32.09293,76.70405
LXSX;S1;X2:32.09488,76.70367
LXSX;S1;X3:32.09500,76.70593
LXSX;S1;X4:32.09500,76.70593
GA36C26B28792C613E9BF3065DFB78ADF
12 changes: 12 additions & 0 deletions index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ const RE_SIT_HEADER = /^H(\w)SIT(?:.{0,}?:(.*)|(.*))$/;
const RE_FTY_HEADER = /^H(\w)FTY(?:.{0,}?:(.*)|(.*))$/;
const RE_RFW_HEADER = /^H(\w)RFW(?:.{0,}?:(.*)|(.*))$/;
const RE_RHW_HEADER = /^H(\w)RHW(?:.{0,}?:(.*)|(.*))$/;
const RE_TZN_HEADER = /^H(\w)TZN(?:.{0,}?:([-+]?[\d.]+))$/;
const RE_B = /^B(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})(\d{3})([NS])(\d{3})(\d{2})(\d{3})([EW])([AV])(-\d{4}|\d{5})(-\d{4}|\d{5})/;
const RE_K = /^K(\d{2})(\d{2})(\d{2})/;
const RE_IJ = /^[IJ](\d{2})(?:\d{2}\d{2}[A-Z]{3})+/;
Expand All @@ -34,6 +35,7 @@ declare namespace IGCParser {
/** UTC date of the flight in ISO 8601 format */
date: string;
numFlight: number | null;
timezone: number | null;

pilot: string | null;
copilot: string | null;
Expand Down Expand Up @@ -269,6 +271,8 @@ class IGCParser {
this._result.competitionClass = this.parseCompetitionClass(line);
} else if (headerType === 'SIT') {
this._result.site = this.parseSite(line);
} else if (headerType === 'TZN') {
this._result.timezone = this.parseTimezone(line);
} else if (headerType === 'FTY') {
this._result.loggerType = this.parseLoggerType(line);
} else if (headerType === 'RFW') {
Expand Down Expand Up @@ -354,6 +358,14 @@ class IGCParser {
return this.parseTextHeader('SIT', RE_SIT_HEADER, line);
}

private parseTimezone(line: string): number {
let result = this.parseTextHeader('TZN', RE_TZN_HEADER, line);
let hours = parseFloat(result);
if (isNaN(hours))
throw new Error(`Invalid TZN header at line ${this.lineNumber}: ${line}`);
return hours;
}

private parseLoggerType(line: string): string {
return this.parseTextHeader('FTY', RE_FTY_HEADER, line);
}
Expand Down
8 changes: 8 additions & 0 deletions test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,14 @@ describe('IGCParser', () => {
expect(result).toMatchSnapshot();
});

/* Test timezone parsing */
test('20241007TZN.igc', () => {
let content = fs.readFileSync(`${__dirname}/fixtures/20241007TZN.igc`, 'utf8');
let result = IGCParser.parse(content);

expect(result.timezone).toEqual(5.5);
});

test('MD_85ugkjj1.IGC', () => {
let content = fs.readFileSync(`${__dirname}/fixtures/MD_85ugkjj1.IGC`, 'utf8');
let result = IGCParser.parse(content, { lenient: true });
Expand Down
Loading