# Instructions for creating a Logger flights CSV

Use these instructions when you convert flight data (another logbook export, a spreadsheet, photos of a paper logbook, free text) into a CSV file that the Logger - Pilot Logbook app can import without any column mapping.

The result must be a plain CSV file. Reply with the CSV only (a code block or a file), no commentary inside the file.

## File structure

1. **Line 1 (required, exact text):** `DO NOT DELETE THIS ROW - LOGGER_FLIGHTS_TEMPLATE_V1`
   The app recognises the file by `LOGGER_FLIGHTS_TEMPLATE_V1` on the first line. Without it the file is treated as an ordinary custom CSV and the import fails or needs manual mapping.
2. **Line 2 (required):** header row. Use only the column names listed below, spelled exactly as shown (case does not matter). Columns can be in any order and unused columns can be left out. Unknown columns are ignored. The `date` column is required.
3. **Line 3 onwards:** one flight (or simulator session) per line. Do not add a description row.

Format rules:
- UTF-8, comma as the delimiter, one line per flight.
- Every line must have the same number of fields as the header row.
- A value containing a comma, a double quote or a line break must be wrapped in double quotes, and a double quote inside it is written twice: `"Crew said ""great"", smooth flight"`. Avoid line breaks in values.
- Leave a cell empty when the value is unknown or does not apply. Do not write `N/A`, `-`, `0:00` or `null`.

## Value formats

- **Date:** `yyyy-MM-dd`, for example `2026-03-02`. This is the only accepted date format. A row without a valid date is rejected.
- **Clock time** (departure, take-off, landing, arrival, scheduled times, session start/end, duty start/end): 24-hour `HH:mm` in the time zone the source data uses, for example `08:15`. `HHmm` also works. Do not use dots or am/pm.
- **Duration** (all totals, function times, custom times): `HH:mm` such as `02:30`, or decimal hours with a dot or comma such as `2.5` (= 2:30) or `1,25` (= 1:15).
  - A dot or comma always means decimal hours. `1.30` means 1.3 hours = 1:18, not 1:30. If the source says 1h30, write `1:30`.
  - Empty, `0` and `00:00` all mean no time.
- **Counts** (take-offs, landings, holds, pax, fuel burn, custom counts, navy fields): whole numbers (integers) only, for example `1`. Anything that is not a number becomes `0`.
- **Airports** (`departureAirport`, `arrivalAirport`): ICAO code preferred (`EDDF`), IATA also accepted (`FRA`). Only the airport code, never the airport name.
- **Approaches:** one approach is `number,type,airport,runway`, for example `1,ILS,LEMD,32L`. Several approaches are separated by `|`: `1,ILS,LEMD,32L|2,RNP,LEMD,32R`. The cell contains commas, so it must be wrapped in double quotes in the CSV. Each approach needs exactly these four parts or it is dropped.

## Behaviour you should know

- **Calculated values:** if left empty, `totalTime` is calculated from `departureTime` and `arrivalTime`, `flightTime` from `takeOffTime` and `landingTime`, `scheduledTotalTime` from the scheduled times, `sessionTotal` from the session start and end, `dutyTotal` from the duty start and end, and `nightTime` from the airports, date and times. Provide these only when the source has them, otherwise leave them empty.
- **Function times are not filled automatically.** `picTime`, `sicTime`, `multiEngineTime`, `ifrTime`, `crossCountryTime` and so on stay empty unless you provide them. Fill them only when the source data contains them or the user asked you to derive them.
- **Simulator sessions:** a row with `simTime` filled in is imported as a simulator entry. For these rows use `simType` and `simRegistration` (not `aircraftType` and `aircraftRegistration`) and leave the flight fields (arrival airport, `totalTime`, `picTime` and so on) empty, because they are ignored. Never put `simTime` on a real flight.
- **Pilots and aircraft are created or matched automatically.** A pilot is matched to an existing one by name (not case sensitive) or by crew code, otherwise a new pilot is created. Aircraft are matched by **registration** (exact spelling, so `D-AIZZ` and `DAIZZ` are different aircraft).
  - An aircraft is only created or linked when a registration is present. A row with `aircraftType` but no `aircraftRegistration` gets no aircraft at all. The same applies to simulators: `simType` is only used together with `simRegistration` (a simulator ID, for example `FFS-1`).
  - Write each registration the same way on every row.
  - Write the same person identically on every row (the same spelling and order of the name, for example always `John Smith`, never `J. Smith` or `Smith, John`).
  - Put the person's ID / crew code in the matching `...CrewCode` column when the source has it (`picName` goes with `picCrewCode`, `sicName` with `sicCrewCode`, and so on). A crew code without a name is allowed.
  - Do not invent names, codes, registrations or aircraft types.
- **Landings and pilot flying:** if `dayLandings` or `nightLandings` is greater than 0 the flight is marked as flown by the logbook owner (pilot flying). Fill the landing counts accordingly.
- **Duplicates:** the app compares date, times, airports and flight number with flights already stored and asks the user what to do, so do not try to de-duplicate against data you cannot see. Do remove duplicates within the data you are converting.

## Columns

Only the `date` column is required. Use the columns the source data supports and drop the rest. The "Value" column is the format to use.

### Basics

| Column | Value |
|---|---|
| `date` | yyyy-MM-dd |
| `flightNumber` | e.g. LH123 |
| `departureAirport` | ICAO or IATA |
| `arrivalAirport` | ICAO or IATA |
| `departureTime` | HH:mm |
| `takeOffTime` | HH:mm |
| `landingTime` | HH:mm |
| `arrivalTime` | HH:mm |
| `scheduledDepartureTime` | HH:mm |
| `scheduledArrivalTime` | HH:mm |
| `totalTime` | HH:mm or decimal hours (calculated if blank) |
| `flightTime` | HH:mm or decimal hours (calculated if blank) |
| `scheduledTotalTime` | HH:mm or decimal hours (calculated if blank) |

### Aircraft

| Column | Value |
|---|---|
| `aircraftType` | e.g. A320 |
| `aircraftRegistration` | e.g. D-AIZZ |
| `simType` | Simulator type |
| `simRegistration` | Simulator ID |

### Crew

| Column | Value |
|---|---|
| `picName` | Full name |
| `sicName` | Full name |
| `studentName` | Full name |
| `student2Name` | Full name |
| `soName` | Full name |
| `examinerName` | Full name |
| `instructorName` | Full name |
| `engineerName` | Full name |
| `observerName` | Full name |
| `observer2Name` | Full name |
| `reliefName` | Full name |
| `relief2Name` | Full name |
| `picCrewCode` | Crew code |
| `sicCrewCode` | Crew code |
| `studentCrewCode` | Crew code |
| `student2CrewCode` | Crew code |
| `soCrewCode` | Crew code |
| `examinerCrewCode` | Crew code |
| `instructorCrewCode` | Crew code |
| `engineerCrewCode` | Crew code |
| `observerCrewCode` | Crew code |
| `observer2CrewCode` | Crew code |
| `reliefCrewCode` | Crew code |
| `relief2CrewCode` | Crew code |

### Function time

| Column | Value |
|---|---|
| `picTime` | HH:mm or decimal hours (1.5) |
| `sicTime` | HH:mm or decimal hours (1.5) |
| `dualTime` | HH:mm or decimal hours (1.5) |
| `instructorTime` | HH:mm or decimal hours (1.5) |
| `ifrTime` | HH:mm or decimal hours (1.5) |
| `nightTime` | HH:mm or decimal hours (calculated if blank) |
| `crossCountryTime` | HH:mm or decimal hours (1.5) |
| `simTime` | HH:mm or decimal hours (1.5) |
| `singleEngineTime` | HH:mm or decimal hours (1.5) |
| `multiEngineTime` | HH:mm or decimal hours (1.5) |
| `multiCrewTime` | HH:mm or decimal hours (1.5) |
| `picusTime` | HH:mm or decimal hours (1.5) |
| `reliefTime` | HH:mm or decimal hours (1.5) |
| `actualInstrumentTime` | HH:mm or decimal hours (1.5) |
| `simulatedInstrumentTime` | HH:mm or decimal hours (1.5) |
| `simInstructorTime` | HH:mm or decimal hours (1.5) |
| `simExaminerTime` | HH:mm or decimal hours (1.5) |
| `lineTrainerTime` | HH:mm or decimal hours (1.5) |
| `lineCheckerTime` | HH:mm or decimal hours (1.5) |
| `rotorcraftTime` | HH:mm or decimal hours (1.5) |
| `nightVisionTime` | HH:mm or decimal hours (1.5) |
| `gliderTime` | HH:mm or decimal hours (1.5) |
| `pcatdTime` | HH:mm or decimal hours (1.5) |

### Session

| Column | Value |
|---|---|
| `sessionStart` | HH:mm |
| `sessionEnd` | HH:mm |
| `sessionTotal` | HH:mm or decimal hours (calculated if blank) |

### Take-offs and landings

| Column | Value |
|---|---|
| `dayTakeOffs` | Number (integer) |
| `nightTakeOffs` | Number (integer) |
| `dayLandings` | Number (integer) |
| `nightLandings` | Number (integer) |
| `waterTakeOffs` | Number (integer) |
| `waterLandings` | Number (integer) |
| `catapults` | Number (integer) |
| `arrests` | Number (integer) |
| `bolters` | Number (integer) |
| `fclLandings` | Number (integer) |

### Approaches

| Column | Value |
|---|---|
| `approaches` | 1,ILS,LPL,22R\|2,GCA,LPL,22R |
| `holds` | Number (integer) |
| `departureRunway` | e.g. 22R |

### Duty

| Column | Value |
|---|---|
| `dutyStart` | HH:mm |
| `dutyEnd` | HH:mm |
| `dutyTotal` | HH:mm or decimal hours (calculated if blank) |

### Other

| Column | Value |
|---|---|
| `remarks` | Text |
| `pax` | Number (integer) |
| `fuelBurn` | Number (integer) |

### Custom fields

| Column | Value |
|---|---|
| `customTime1` | HH:mm or decimal hours (1.5) |
| `customTime2` | HH:mm or decimal hours (1.5) |
| `customTime3` | HH:mm or decimal hours (1.5) |
| `customTime4` | HH:mm or decimal hours (1.5) |
| `customTime5` | HH:mm or decimal hours (1.5) |
| `customTime6` | HH:mm or decimal hours (1.5) |
| `customSessionTime1` | HH:mm or decimal hours (1.5) |
| `customSessionTime2` | HH:mm or decimal hours (1.5) |
| `customCount1` | Number (integer) |
| `customCount2` | Number (integer) |
| `customCount3` | Number (integer) |
| `customCount4` | Number (integer) |
| `customCount5` | Number (integer) |
| `customCount6` | Number (integer) |

## Minimal example

```csv
DO NOT DELETE THIS ROW - LOGGER_FLIGHTS_TEMPLATE_V1
date,flightNumber,departureAirport,arrivalAirport,departureTime,arrivalTime,aircraftType,aircraftRegistration,picName,picCrewCode,multiEngineTime,dayTakeOffs,dayLandings,approaches,remarks
2026-03-02,LH1130,EDDF,LEMD,08:15,10:45,A320,D-AIZZ,John Smith,JS01,2:30,1,1,"1,ILS,LEMD,32L",
2026-03-10,BA304,LHR,CDG,20:30,21:45,A319,G-EUPA,John Smith,JS01,1.25,0,0,,"Crew said ""great"", smooth flight"
```

Here `totalTime` is not provided, so it is calculated from the departure and arrival times.

## Checklist before you answer

1. The first line is exactly `DO NOT DELETE THIS ROW - LOGGER_FLIGHTS_TEMPLATE_V1`.
2. The second line is the header row, it contains `date`, and every column name is from the list above.
3. Every row has the same number of fields as the header.
4. Every date is `yyyy-MM-dd` and every clock time is 24-hour `HH:mm`.
5. Durations use `HH:mm`, or decimal hours with a dot or comma, and `1h30` is written `1:30`.
6. Counts are whole numbers.
7. Values with commas, quotes or line breaks are wrapped in double quotes, with inner quotes doubled.
8. Unknown values are empty, nothing is invented, and the same person and the same registration are spelled the same way on every row.
9. Every row that has an aircraft type also has its registration (and every simulator row has `simRegistration`).
