Getting started
Install the package:
dotnet add package Cavok
Parse a METAR
Metar.Parse returns a Metar record. Every group is a typed property; groups that occur more than once, such
as clouds or runway visual ranges, are lists.
Metar metar = Metar.Parse("METAR EHAM 211125Z 24012G25KT 200V280 9999 -SHRA FEW012 BKN030CB 12/09 Q1013 TEMPO 4000 SHRA");
Console.WriteLine(metar.Station); // EHAM
Console.WriteLine(metar.Wind?.Direction); // 240
Console.WriteLine(metar.Wind?.Gust?.Value); // 25
Console.WriteLine(metar.Visibility?.Meters); // 10000 (9999 means 10 km or more)
Console.WriteLine(metar.Clouds[1].Type); // Cumulonimbus
Console.WriteLine(metar.Pressure?.Hectopascals); // 1013
Console.WriteLine(metar.FlightCategory); // Mvfr
Console.WriteLine(metar.Trends[0].Kind); // Temporary
Describe it
Console.WriteLine(metar.Describe(Language.English));
Console.WriteLine(metar.Describe(Language.Dutch));
Parse a TAF
Taf.Parse returns the base forecast and a list of change groups, each with its own ForecastConditions.
Taf taf = Taf.Parse("TAF EHAM 210440Z 2106/2212 27005KT 9999 FEW035 BECMG 2106/2109 31011KT PROB30 TEMPO 2114/2118 TSRA");
foreach (TafChange change in taf.Changes)
{
Console.WriteLine($"{change.Kind} {change.Probability} {change.Period?.From} {change.Conditions.Wind?.Direction}");
}
Console.WriteLine(taf.Describe(Language.English));
Lenient and strict parsing
Parse never throws for bad content. Whatever can be understood is returned and every problem is listed in
Diagnostics. ParseStrict throws a CavokParseException when there is at least one error; warnings are allowed.
try
{
Metar.ParseStrict("METAR EHAM 211125Z 24012KT 2400O Q1013");
}
catch (CavokParseException exception)
{
Console.WriteLine(exception.Diagnostics[0].Describe(Language.Dutch));
// ongeldige zichtgroep "2400O"; verwacht 4 cijfers (bijv. 0800, 9999)
}
Day and time
Reports only contain the day of the month. DayTime.ToDateTimeOffset picks the month and year closest to a
reference moment, typically when the report was received:
// Reports only contain the day of the month; resolve it against the moment the report was received.
DateTimeOffset observed = metar.Time!.Value.ToDateTimeOffset(new DateTimeOffset(2026, 9, 21, 11, 40, 0, TimeSpan.Zero));
Console.WriteLine(observed.ToString("u", System.Globalization.CultureInfo.InvariantCulture)); // 2026-09-21 11:25:00Z