From 8ac09288c20532907159cfa27125c9d88405d34a Mon Sep 17 00:00:00 2001 From: Mark Crossley Date: Mon, 5 Feb 2024 23:07:46 +0000 Subject: [PATCH 01/12] Converted to .Net 8.0 --- CreateMissing.csproj | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/CreateMissing.csproj b/CreateMissing.csproj index ef5819a..3990c33 100644 --- a/CreateMissing.csproj +++ b/CreateMissing.csproj @@ -1,23 +1,19 @@ - Exe $(PackageVersion) $(PackageVersion) 1.4.3 CreateMissing.Program - net48 + net8.0 Mark Crossley Cumulus MX AnyCPU - DEBUG;TRACE - - - + \ No newline at end of file From 36245b6b05b654dee26be03ec3fe2e834c2f2f44 Mon Sep 17 00:00:00 2001 From: Mark Crossley Date: Mon, 5 Feb 2024 23:31:59 +0000 Subject: [PATCH 02/12] Initial conversion to CMX v4 --- CreateMissing.csproj | 2 +- Cumulus.cs | 28 ++++++ DayFile.cs | 216 +++++++++++++++++++++---------------------- Program.cs | 41 ++++---- Updates.txt | 6 ++ Utils.cs | 154 +++++++++--------------------- 6 files changed, 203 insertions(+), 244 deletions(-) diff --git a/CreateMissing.csproj b/CreateMissing.csproj index 3990c33..42233cc 100644 --- a/CreateMissing.csproj +++ b/CreateMissing.csproj @@ -3,7 +3,7 @@ Exe $(PackageVersion) $(PackageVersion) - 1.4.3 + 2.0.0 CreateMissing.Program net8.0 Mark Crossley diff --git a/Cumulus.cs b/Cumulus.cs index 2044c32..3c956f8 100644 --- a/Cumulus.cs +++ b/Cumulus.cs @@ -162,6 +162,34 @@ private void ReadIniFile() } } + public int GetHourInc(DateTime timestamp) + { + if (RolloverHour == 0) + { + return 0; + } + else + { + try + { + if (Use10amInSummer && TimeZoneInfo.Local.IsDaylightSavingTime(timestamp)) + { + // Locale is currently on Daylight time + return -10; + } + else + { + // Locale is currently on Standard time or unknown + return -9; + } + } + catch (Exception) + { + return -9; + } + } + } + } internal class StationUnits diff --git a/DayFile.cs b/DayFile.cs index bf12450..7085204 100644 --- a/DayFile.cs +++ b/DayFile.cs @@ -11,11 +11,9 @@ namespace CreateMissing class DayFile { - public List DayfileRecs = new List(); + public List DayfileRecs = []; public string LineEnding = string.Empty; - public string FieldSep = string.Empty; - public string DateSep = string.Empty; private readonly string dayFileName = Program.location + "data" + Path.DirectorySeparatorChar + "dayfile.txt"; @@ -52,8 +50,6 @@ public void LoadDayFile() { LineEnding = lineend; } - // determine the dayfile field and date separators - Utils.GetLogFileSeparators(dayFileName, CultureInfo.CurrentCulture.TextInfo.ListSeparator, out FieldSep, out DateSep); // Clear the existing list DayfileRecs.Clear(); @@ -185,7 +181,7 @@ public void WriteDayFile() } - private string RecToCsv(Dayfilerec rec) + private static string RecToCsv(Dayfilerec rec) { // Writes an entry to the daily extreme log file. Fields are comma-separated. // 0 Date in the form dd/mm/yy (the slash may be replaced by a dash in some cases) @@ -245,22 +241,23 @@ private string RecToCsv(Dayfilerec rec) // 53 High 24 hr rain // 54 Time of high 24 hr rain - + var inv = CultureInfo.InvariantCulture; + var sep = ","; // Write the date back using the same separator as the source file - string datestring = rec.Date.ToString($"dd{DateSep}MM{DateSep}yy"); + string datestring = rec.Date.ToString($"dd/MM/yy", inv); // NB this string is just for logging, the dayfile update code is further down var strb = new StringBuilder(300); - strb.Append(datestring + FieldSep); + strb.Append(datestring + sep); if (rec.HighGust == -9999) return null; //strb.Append("0.0" + listsep + "0" + listsep + "00:00" + listsep); else { - strb.Append(rec.HighGust.ToString(Program.cumulus.WindFormat) + FieldSep); - strb.Append(rec.HighGustBearing + FieldSep); - strb.Append(rec.HighGustTime.ToString("HH:mm") + FieldSep); + strb.Append(rec.HighGust.ToString(Program.cumulus.WindFormat, inv) + sep); + strb.Append(rec.HighGustBearing + sep); + strb.Append(rec.HighGustTime.ToString("HH:mm", inv) + sep); } if (rec.LowTemp == 9999) @@ -268,8 +265,8 @@ private string RecToCsv(Dayfilerec rec) //strb.Append("0.0" + listsep + "00:00" + listsep); else { - strb.Append(rec.LowTemp.ToString(Program.cumulus.TempFormat) + FieldSep); - strb.Append(rec.LowTempTime.ToString("HH:mm") + FieldSep); + strb.Append(rec.LowTemp.ToString(Program.cumulus.TempFormat, inv) + sep); + strb.Append(rec.LowTempTime.ToString("HH:mm", inv) + sep); } if (rec.HighTemp == -9999) @@ -277,8 +274,8 @@ private string RecToCsv(Dayfilerec rec) //strb.Append("0.0" + listsep + "00:00" + listsep); else { - strb.Append(rec.HighTemp.ToString(Program.cumulus.TempFormat) + FieldSep); - strb.Append(rec.HighTempTime.ToString("HH:mm") + FieldSep); + strb.Append(rec.HighTemp.ToString(Program.cumulus.TempFormat, inv) + sep); + strb.Append(rec.HighTempTime.ToString("HH:mm", inv) + sep); } if (rec.LowPress == 9999) @@ -286,8 +283,8 @@ private string RecToCsv(Dayfilerec rec) //strb.Append("0.0" + listsep + "00:00" + listsep); else { - strb.Append(rec.LowPress.ToString(Program.cumulus.PressFormat) + FieldSep); - strb.Append(rec.LowPressTime.ToString("HH:mm") + FieldSep); + strb.Append(rec.LowPress.ToString(Program.cumulus.PressFormat, inv) + sep); + strb.Append(rec.LowPressTime.ToString("HH:mm", inv) + sep); } if (rec.HighPress == -9999) @@ -295,8 +292,8 @@ private string RecToCsv(Dayfilerec rec) //strb.Append("0.0" + listsep + "00:00" + listsep); else { - strb.Append(rec.HighPress.ToString(Program.cumulus.PressFormat) + FieldSep); - strb.Append(rec.HighPressTime.ToString("HH:mm") + FieldSep); + strb.Append(rec.HighPress.ToString(Program.cumulus.PressFormat, inv) + sep); + strb.Append(rec.HighPressTime.ToString("HH:mm", inv) + sep); } if (rec.HighRainRate == -9999) @@ -304,158 +301,158 @@ private string RecToCsv(Dayfilerec rec) //strb.Append("0.0" + listsep + "00:00" + listsep); else { - strb.Append(rec.HighRainRate.ToString(Program.cumulus.RainFormat) + FieldSep); - strb.Append(rec.HighRainRateTime.ToString("HH:mm") + FieldSep); + strb.Append(rec.HighRainRate.ToString(Program.cumulus.RainFormat, inv) + sep); + strb.Append(rec.HighRainRateTime.ToString("HH:mm", inv) + sep); } if (rec.TotalRain == -9999) return null; //strb.Append("0.0" + listsep); else - strb.Append(rec.TotalRain.ToString(Program.cumulus.RainFormat) + FieldSep); + strb.Append(rec.TotalRain.ToString(Program.cumulus.RainFormat, inv) + sep); if (rec.AvgTemp == -9999) - strb.Append(FieldSep); + strb.Append(sep); else - strb.Append(rec.AvgTemp.ToString(Program.cumulus.TempFormat) + FieldSep); + strb.Append(rec.AvgTemp.ToString(Program.cumulus.TempFormat, inv) + sep); - strb.Append(rec.WindRun.ToString("F1") + FieldSep); + strb.Append(rec.WindRun.ToString("F1", inv) + sep); if (rec.HighAvgWind == -9999) - strb.Append(FieldSep + FieldSep); + strb.Append(sep + sep); else { - strb.Append(rec.HighAvgWind.ToString(Program.cumulus.WindAvgFormat) + FieldSep); - strb.Append(rec.HighAvgWindTime.ToString("HH:mm") + FieldSep); + strb.Append(rec.HighAvgWind.ToString(Program.cumulus.WindAvgFormat, inv) + sep); + strb.Append(rec.HighAvgWindTime.ToString("HH:mm", inv) + sep); } if (rec.LowHumidity == 9999) - strb.Append(FieldSep + FieldSep); + strb.Append(sep + sep); else { - strb.Append(rec.LowHumidity + FieldSep); - strb.Append(rec.LowHumidityTime.ToString("HH:mm") + FieldSep); + strb.Append(rec.LowHumidity + sep); + strb.Append(rec.LowHumidityTime.ToString("HH:mm", inv) + sep); } if (rec.HighHumidity == -9999) - strb.Append(FieldSep + FieldSep); + strb.Append(sep + sep); else { - strb.Append(rec.HighHumidity + FieldSep); - strb.Append(rec.HighHumidityTime.ToString("HH:mm") + FieldSep); + strb.Append(rec.HighHumidity + sep); + strb.Append(rec.HighHumidityTime.ToString("HH:mm", inv) + sep); } - strb.Append(rec.ET.ToString(Program.cumulus.ETFormat) + FieldSep); - strb.Append(rec.SunShineHours.ToString(Program.cumulus.SunFormat) + FieldSep); + strb.Append(rec.ET.ToString(Program.cumulus.ETFormat, inv) + sep); + strb.Append(rec.SunShineHours.ToString(Program.cumulus.SunFormat, inv) + sep); if (rec.HighHeatIndex == -9999) - strb.Append(FieldSep + FieldSep); + strb.Append(sep + sep); else { - strb.Append(rec.HighHeatIndex.ToString(Program.cumulus.TempFormat) + FieldSep); - strb.Append(rec.HighHeatIndexTime.ToString("HH:mm") + FieldSep); + strb.Append(rec.HighHeatIndex.ToString(Program.cumulus.TempFormat, inv) + sep); + strb.Append(rec.HighHeatIndexTime.ToString("HH:mm", inv) + sep); } if (rec.HighAppTemp == -9999) - strb.Append(FieldSep + FieldSep); + strb.Append(sep + sep); else { - strb.Append(rec.HighAppTemp.ToString(Program.cumulus.TempFormat) + FieldSep); - strb.Append(rec.HighAppTempTime.ToString("HH:mm") + FieldSep); + strb.Append(rec.HighAppTemp.ToString(Program.cumulus.TempFormat, inv) + sep); + strb.Append(rec.HighAppTempTime.ToString("HH:mm", inv) + sep); } if (rec.LowAppTemp == 9999) - strb.Append(FieldSep + FieldSep); + strb.Append(sep + sep); else { - strb.Append(rec.LowAppTemp.ToString(Program.cumulus.TempFormat) + FieldSep); - strb.Append(rec.LowAppTempTime.ToString("HH:mm") + FieldSep); + strb.Append(rec.LowAppTemp.ToString(Program.cumulus.TempFormat, inv) + sep); + strb.Append(rec.LowAppTempTime.ToString("HH:mm", inv) + sep); } if (rec.HighHourlyRain == -9999) - strb.Append(FieldSep + FieldSep); + strb.Append(sep + sep); else { - strb.Append(rec.HighHourlyRain.ToString(Program.cumulus.RainFormat) + FieldSep); - strb.Append(rec.HighHourlyRainTime.ToString("HH:mm") + FieldSep); + strb.Append(rec.HighHourlyRain.ToString(Program.cumulus.RainFormat, inv) + sep); + strb.Append(rec.HighHourlyRainTime.ToString("HH:mm", inv) + sep); } if (rec.LowWindChill == 9999) - strb.Append(FieldSep + FieldSep); + strb.Append(sep + sep); else { - strb.Append(rec.LowWindChill.ToString(Program.cumulus.TempFormat) + FieldSep); - strb.Append(rec.LowWindChillTime.ToString("HH:mm") + FieldSep); + strb.Append(rec.LowWindChill.ToString(Program.cumulus.TempFormat, inv) + sep); + strb.Append(rec.LowWindChillTime.ToString("HH:mm", inv) + sep); } if (rec.HighDewPoint == -9999) - strb.Append(FieldSep + FieldSep); + strb.Append(sep + sep); else { - strb.Append(rec.HighDewPoint.ToString(Program.cumulus.TempFormat) + FieldSep); - strb.Append(rec.HighDewPointTime.ToString("HH:mm") + FieldSep); + strb.Append(rec.HighDewPoint.ToString(Program.cumulus.TempFormat, inv) + sep); + strb.Append(rec.HighDewPointTime.ToString("HH:mm", inv) + sep); } if (rec.LowDewPoint == -9999) - strb.Append(FieldSep + FieldSep); + strb.Append(sep + sep); else { - strb.Append(rec.LowDewPoint.ToString(Program.cumulus.TempFormat) + FieldSep); - strb.Append(rec.LowDewPointTime.ToString("HH:mm") + FieldSep); + strb.Append(rec.LowDewPoint.ToString(Program.cumulus.TempFormat, inv) + sep); + strb.Append(rec.LowDewPointTime.ToString("HH:mm", inv) + sep); } if (rec.DominantWindBearing == 9999) - strb.Append(FieldSep); + strb.Append(sep); else - strb.Append(rec.DominantWindBearing + FieldSep); + strb.Append(rec.DominantWindBearing + sep); if (rec.HeatingDegreeDays == -9999) - strb.Append(FieldSep); + strb.Append(sep); else - strb.Append(rec.HeatingDegreeDays.ToString("F1") + FieldSep); + strb.Append(rec.HeatingDegreeDays.ToString("F1", inv) + sep); if (rec.CoolingDegreeDays == -9999) - strb.Append(FieldSep); + strb.Append(sep); else - strb.Append(rec.CoolingDegreeDays.ToString("F1") + FieldSep); + strb.Append(rec.CoolingDegreeDays.ToString("F1", inv) + sep); - strb.Append(rec.HighSolar + FieldSep); - strb.Append(rec.HighSolarTime.ToString("HH:mm") + FieldSep); - strb.Append(rec.HighUv.ToString(Program.cumulus.UVFormat) + FieldSep); - strb.Append(rec.HighUvTime.ToString("HH:mm") + FieldSep); + strb.Append(rec.HighSolar + sep); + strb.Append(rec.HighSolarTime.ToString("HH:mm", inv) + sep); + strb.Append(rec.HighUv.ToString(Program.cumulus.UVFormat, inv) + sep); + strb.Append(rec.HighUvTime.ToString("HH:mm", inv) + sep); if (rec.HighFeelsLike == -9999) - strb.Append(FieldSep + FieldSep); + strb.Append(sep + sep); else { - strb.Append(rec.HighFeelsLike.ToString(Program.cumulus.TempFormat) + FieldSep); - strb.Append(rec.HighFeelsLikeTime.ToString("HH:mm") + FieldSep); + strb.Append(rec.HighFeelsLike.ToString(Program.cumulus.TempFormat, inv) + sep); + strb.Append(rec.HighFeelsLikeTime.ToString("HH:mm", inv) + sep); } if (rec.LowFeelsLike == 9999) - strb.Append(FieldSep + FieldSep); + strb.Append(sep + sep); else { - strb.Append(rec.LowFeelsLike.ToString(Program.cumulus.TempFormat) + FieldSep); - strb.Append(rec.LowFeelsLikeTime.ToString("HH:mm") + FieldSep); + strb.Append(rec.LowFeelsLike.ToString(Program.cumulus.TempFormat, inv) + sep); + strb.Append(rec.LowFeelsLikeTime.ToString("HH:mm", inv) + sep); } if (rec.HighHumidex == -9999) - strb.Append(FieldSep + FieldSep); + strb.Append(sep + sep); else { - strb.Append(rec.HighHumidex.ToString(Program.cumulus.TempFormat) + FieldSep); - strb.Append(rec.HighHumidexTime.ToString("HH:mm") + FieldSep); + strb.Append(rec.HighHumidex.ToString(Program.cumulus.TempFormat, inv) + sep); + strb.Append(rec.HighHumidexTime.ToString("HH:mm", inv) + sep); } if (rec.ChillHours != -9999) - strb.Append(rec.ChillHours.ToString("F1") + FieldSep); + strb.Append(rec.ChillHours.ToString("F1", inv) + sep); if (rec.HighRain24h != -9999) { - strb.Append(rec.HighRain24h.ToString(Program.cumulus.TempFormat) + FieldSep); - strb.Append(rec.HighRain24hTime.ToString("HH:mm")); + strb.Append(rec.HighRain24h.ToString(Program.cumulus.TempFormat, inv) + sep); + strb.Append(rec.HighRain24hTime.ToString("HH:mm", inv)); } Program.LogMessage("Dayfile.txt Added: " + datestring); @@ -463,37 +460,38 @@ private string RecToCsv(Dayfilerec rec) return strb.ToString(); } - private Dayfilerec ParseDayFileRec(string data) + private static Dayfilerec ParseDayFileRec(string data) { - var st = new List(Regex.Split(data, FieldSep)); + var st = new List(data.Split(',')); double varDbl; int varInt; int idx = 0; + var inv = CultureInfo.InvariantCulture; var rec = new Dayfilerec(); try { rec.Date = Utils.DdmmyyStrToDate(st[idx++]); - rec.HighGust = Convert.ToDouble(st[idx++]); + rec.HighGust = Convert.ToDouble(st[idx++], inv); rec.HighGustBearing = Convert.ToInt32(st[idx++]); rec.HighGustTime = Utils.GetDateTime(rec.Date, st[idx++]); - rec.LowTemp = Convert.ToDouble(st[idx++]); + rec.LowTemp = Convert.ToDouble(st[idx++], inv); rec.LowTempTime = Utils.GetDateTime(rec.Date, st[idx++]); - rec.HighTemp = Convert.ToDouble(st[idx++]); + rec.HighTemp = Convert.ToDouble(st[idx++], inv); rec.HighTempTime = Utils.GetDateTime(rec.Date, st[idx++]); - rec.LowPress = Convert.ToDouble(st[idx++]); + rec.LowPress = Convert.ToDouble(st[idx++], inv); rec.LowPressTime = Utils.GetDateTime(rec.Date, st[idx++]); - rec.HighPress = Convert.ToDouble(st[idx++]); + rec.HighPress = Convert.ToDouble(st[idx++], inv); rec.HighPressTime = Utils.GetDateTime(rec.Date, st[idx++]); - rec.HighRainRate = Convert.ToDouble(st[idx++]); + rec.HighRainRate = Convert.ToDouble(st[idx++], inv); rec.HighRainRateTime = Utils.GetDateTime(rec.Date, st[idx++]); - rec.TotalRain = Convert.ToDouble(st[idx++]); - rec.AvgTemp = Convert.ToDouble(st[idx++]); + rec.TotalRain = Convert.ToDouble(st[idx++], inv); + rec.AvgTemp = Convert.ToDouble(st[idx++], inv); - if (st.Count > idx++ && double.TryParse(st[16], out varDbl)) + if (st.Count > idx++ && double.TryParse(st[16], inv, out varDbl)) rec.WindRun = varDbl; - if (st.Count > idx++ && double.TryParse(st[17], out varDbl)) + if (st.Count > idx++ && double.TryParse(st[17], inv, out varDbl)) rec.HighAvgWind = varDbl; if (st.Count > idx++ && st[18].Length == 5) @@ -511,49 +509,49 @@ private Dayfilerec ParseDayFileRec(string data) if (st.Count > idx++ && st[22].Length == 5) rec.HighHumidityTime = Utils.GetDateTime(rec.Date, st[22]); - if (st.Count > idx++ && double.TryParse(st[23], out varDbl)) + if (st.Count > idx++ && double.TryParse(st[23], inv, out varDbl)) rec.ET = varDbl; - if (st.Count > idx++ && double.TryParse(st[24], out varDbl)) + if (st.Count > idx++ && double.TryParse(st[24], inv, out varDbl)) rec.SunShineHours = varDbl; - if (st.Count > idx++ && double.TryParse(st[25], out varDbl)) + if (st.Count > idx++ && double.TryParse(st[25], inv, out varDbl)) rec.HighHeatIndex = varDbl; if (st.Count > idx++ && st[26].Length == 5) rec.HighHeatIndexTime = Utils.GetDateTime(rec.Date, st[26]); - if (st.Count > idx++ && double.TryParse(st[27], out varDbl)) + if (st.Count > idx++ && double.TryParse(st[27], inv, out varDbl)) rec.HighAppTemp = varDbl; if (st.Count > idx++ && st[28].Length == 5) rec.HighAppTempTime = Utils.GetDateTime(rec.Date, st[28]); - if (st.Count > idx++ && double.TryParse(st[29], out varDbl)) + if (st.Count > idx++ && double.TryParse(st[29], inv, out varDbl)) rec.LowAppTemp = varDbl; if (st.Count > idx++ && st[30].Length == 5) rec.LowAppTempTime = Utils.GetDateTime(rec.Date, st[30]); - if (st.Count > idx++ && double.TryParse(st[31], out varDbl)) + if (st.Count > idx++ && double.TryParse(st[31], inv, out varDbl)) rec.HighHourlyRain = varDbl; if (st.Count > idx++ && st[32].Length == 5) rec.HighHourlyRainTime = Utils.GetDateTime(rec.Date, st[32]); - if (st.Count > idx++ && double.TryParse(st[33], out varDbl)) + if (st.Count > idx++ && double.TryParse(st[33], inv, out varDbl)) rec.LowWindChill = varDbl; if (st.Count > idx++ && st[34].Length == 5) rec.LowWindChillTime = Utils.GetDateTime(rec.Date, st[34]); - if (st.Count > idx++ && double.TryParse(st[35], out varDbl)) + if (st.Count > idx++ && double.TryParse(st[35], inv, out varDbl)) rec.HighDewPoint = varDbl; if (st.Count > idx++ && st[36].Length == 5) rec.HighDewPointTime = Utils.GetDateTime(rec.Date, st[36]); - if (st.Count > idx++ && double.TryParse(st[37], out varDbl)) + if (st.Count > idx++ && double.TryParse(st[37], inv, out varDbl)) rec.LowDewPoint = varDbl; if (st.Count > idx++ && st[38].Length == 5) @@ -562,10 +560,10 @@ private Dayfilerec ParseDayFileRec(string data) if (st.Count > idx++ && int.TryParse(st[39], out varInt)) rec.DominantWindBearing = varInt; - if (st.Count > idx++ && double.TryParse(st[40], out varDbl)) + if (st.Count > idx++ && double.TryParse(st[40], inv, out varDbl)) rec.HeatingDegreeDays = varDbl; - if (st.Count > idx++ && double.TryParse(st[41], out varDbl)) + if (st.Count > idx++ && double.TryParse(st[41], inv, out varDbl)) rec.CoolingDegreeDays = varDbl; if (st.Count > idx++ && int.TryParse(st[42], out varInt)) @@ -574,34 +572,34 @@ private Dayfilerec ParseDayFileRec(string data) if (st.Count > idx++ && st[43].Length == 5) rec.HighSolarTime = Utils.GetDateTime(rec.Date, st[43]); - if (st.Count > idx++ && double.TryParse(st[44], out varDbl)) + if (st.Count > idx++ && double.TryParse(st[44], inv, out varDbl)) rec.HighUv = varDbl; if (st.Count > idx++ && st[45].Length == 5) rec.HighUvTime = Utils.GetDateTime(rec.Date, st[45]); - if (st.Count > idx++ && double.TryParse(st[46], out varDbl)) + if (st.Count > idx++ && double.TryParse(st[46], inv, out varDbl)) rec.HighFeelsLike = varDbl; if (st.Count > idx++ && st[47].Length == 5) rec.HighFeelsLikeTime = Utils.GetDateTime(rec.Date, st[47]); - if (st.Count > idx++ && double.TryParse(st[48], out varDbl)) + if (st.Count > idx++ && double.TryParse(st[48], inv, out varDbl)) rec.LowFeelsLike = varDbl; if (st.Count > idx++ && st[49].Length == 5) rec.LowFeelsLikeTime = Utils.GetDateTime(rec.Date, st[49]); - if (st.Count > idx++ && double.TryParse(st[50], out varDbl)) + if (st.Count > idx++ && double.TryParse(st[50], inv, out varDbl)) rec.HighHumidex = varDbl; if (st.Count > idx++ && st[51].Length == 5) rec.HighHumidexTime = Utils.GetDateTime(rec.Date, st[51]); - if (st.Count > idx++ && double.TryParse(st[52], out varDbl)) + if (st.Count > idx++ && double.TryParse(st[52], inv, out varDbl)) rec.ChillHours = varDbl; - if (st.Count > idx++ && double.TryParse(st[53], out varDbl)) + if (st.Count > idx++ && double.TryParse(st[53], inv, out varDbl)) rec.HighRain24h = varDbl; if (st.Count > idx++ && st[54].Length == 5) diff --git a/Program.cs b/Program.cs index 01b3992..cbdafc8 100644 --- a/Program.cs +++ b/Program.cs @@ -17,11 +17,11 @@ class Program private static ConsoleColor defConsoleColour; private static DayFile dayfile; - private static readonly List CurrentLogLines = new List(); + private static readonly List CurrentLogLines = []; private static string CurrentLogName; private static int CurrentLogLineNum = 0; - private static readonly List CurrentSolarLogLines = new List(); + private static readonly List CurrentSolarLogLines = []; private static string CurrentSolarLogName; private static int CurrentSolarLogLineNum = 0; @@ -199,7 +199,7 @@ static void Main() } } - currDate = IncrementMeteoDate(dayfile.DayfileRecs[dayfile.DayfileRecs.Count - 1].Date); + currDate = IncrementMeteoDate(dayfile.DayfileRecs[^1].Date); // We need the last total chill hours to increment if there are missing records at the end of the day file // check if total chill hours needs to be reset if (currDate.Month == cumulus.ChillHourSeasonStart && currDate.Day == 1) @@ -208,7 +208,7 @@ static void Main() } else { - TotalChillHours = dayfile.DayfileRecs[dayfile.DayfileRecs.Count - 1].ChillHours; + TotalChillHours = dayfile.DayfileRecs[^1].ChillHours; } // that is the dayfile processed, but what if it had missing records at the end? @@ -389,9 +389,6 @@ private static Dayfilerec GetDayRecFromMonthly(DateTime date) if (dayfile.LineEnding == string.Empty) { Utils.TryDetectNewLine(fileName, out dayfile.LineEnding); - - // determine the dayfile field and date separators - Utils.GetLogFileSeparators(fileName, CultureInfo.CurrentCulture.TextInfo.ListSeparator, out dayfile.FieldSep, out dayfile.DateSep); } @@ -424,7 +421,7 @@ private static Dayfilerec GetDayRecFromMonthly(DateTime date) //var st = new List(Regex.Split(line, CultureInfo.CurrentCulture.TextInfo.ListSeparator)); // Regex is very expensive, let's assume the separator is always a single character - var st = new List(CurrentLogLines[CurrentLogLineNum++].Split(dayfile.FieldSep[0])); + var st = new List(CurrentLogLines[CurrentLogLineNum++].Split(',')); var entrydate = Utils.DdmmyyhhmmStrToDate(st[0], st[1]); if (entrydate < startTimeMinus1) @@ -1009,9 +1006,6 @@ private static Dayfilerec GetSolarDayRecFromMonthly(DateTime date, Dayfilerec re if (dayfile.LineEnding == string.Empty) { Utils.TryDetectNewLine(fileName, out dayfile.LineEnding); - - // determine the dayfile field and date separators - Utils.GetLogFileSeparators(fileName, CultureInfo.CurrentCulture.TextInfo.ListSeparator, out dayfile.FieldSep, out dayfile.DateSep); } try @@ -1049,7 +1043,7 @@ private static Dayfilerec GetSolarDayRecFromMonthly(DateTime date, Dayfilerec re } // Regex is very expensive, let's assume the separator is always a single character - var ut = new List(CurrentSolarLogLines[CurrentSolarLogLineNum].Split(dayfile.FieldSep[0])); + var ut = new List(CurrentSolarLogLines[CurrentSolarLogLineNum].Split(',')); if (ut.Count < 10) { @@ -1313,9 +1307,16 @@ private static void AddMissingData(int idx, DateTime metDate) private static string GetLogFileName(DateTime thedate) { - var datestring = thedate.ToString("MMMyy").Replace(".", ""); + // First determine the date for the log file. + // If we're using 9am roll-over, the date should be 9 hours (10 in summer) + // before 'Now' + var logfiledate = thedate.AddHours(cumulus.GetHourInc(thedate)); + + + var datestring = logfiledate.ToString("yyyyMM"); return location + "data" + Path.DirectorySeparatorChar + datestring + "log.txt"; + } private static void ExtractSolarData(List st, ref Dayfilerec rec, DateTime entrydate) @@ -1438,17 +1439,9 @@ private static void AddLastHoursRainEntry(DateTime ts, double rain, ref Queue 70 ? 1900 : 2000; + return result; } - return new DateTime(Y, M, D); + return DateTime.MinValue; } public static DateTime DdmmyyhhmmStrToDate(string d, string t) { - // Horrible hack, but we have localised separators, but UK sequence, so localised parsing may fail - // Determine separators from the strings, allow for multi-byte! - var datSep = Regex.Match(d, @"[^0-9]+").Value; - var timSep = Regex.Match(t, @"[^0-9]+").Value; - - // Converts a date string in UK order to a DateTime - string[] date = d.Split(new string[] { datSep }, StringSplitOptions.None); - string[] time = t.Split(new string[] { timSep }, StringSplitOptions.None); - - int D = Convert.ToInt32(date[0]); - int M = Convert.ToInt32(date[1]); - int Y = Convert.ToInt32(date[2]); - - // Double check - just in case we get a four digit year! - if (Y < 1900) + if (DateTime.TryParseExact(d + ' ' + t, "dd/MM/yy HH:mm", CultureInfo.InvariantCulture, DateTimeStyles.AssumeLocal, out var result)) { - Y += Y > 70 ? 1900 : 2000; + return result; } - int h = Convert.ToInt32(time[0]); - int m = Convert.ToInt32(time[1]); - - return new DateTime(Y, M, D, h, m, 0); + return DateTime.MinValue; } public static DateTime GetDateTime(DateTime date, string time) { - var timSep = Regex.Match(time, @"[^0-9]+").Value; - - var tim = time.Split(new string[] { timSep }, StringSplitOptions.None); + var tim = time.Split(','); return new DateTime(date.Year, date.Month, date.Day, int.Parse(tim[0]), int.Parse(tim[1]), 0); } @@ -88,57 +60,42 @@ public static double TempCToUser(double value) public static double UserWindToKPH(double wind) // input is in Units.Wind units, convert to km/h { - switch (Program.cumulus.Units.Wind) + return Program.cumulus.Units.Wind switch { // m/s - case 0: - return wind * 3.6; + 0 => wind * 3.6, // mph - case 1: - return wind * 1.609344; + 1 => wind * 1.609344, // kph - case 2: - return wind; + 2 => wind, // knots - case 3: - return wind * 1.852; - default: - return wind; + 3 => wind * 1.852, + _ => wind, }; } public static double UserWindToMS(double value) { - switch (Program.cumulus.Units.Wind) + return Program.cumulus.Units.Wind switch { - case 0: - return value; - case 1: - return value / 2.23693629; - case 2: - return value / 3.6F; - case 3: - return value / 1.94384449; - default: - return 0; + 0 => value, + 1 => value / 2.23693629, + 2 => value / 3.6F, + 3 => value / 1.94384449, + _ => 0, }; } public static double WindMSToUser(double value) { - switch (Program.cumulus.Units.Wind) + return Program.cumulus.Units.Wind switch { - case 0: - return value; - case 1: - return value * 2.23693629; - case 2: - return value * 3.6; - case 3: - return value * 1.94384449; - default: - return 0; - } + 0 => value, + 1 => value * 2.23693629, + 2 => value * 3.6, + 3 => value * 1.94384449, + _ => 0, + }; } public static int CalcAvgBearing(double x, double y) @@ -154,53 +111,30 @@ public static int CalcAvgBearing(double x, double y) public static bool TryDetectNewLine(string path, out string newLine) { - using (var fs = File.OpenRead(path)) - { - char prevChar = '\0'; - - // read the first 1000 characters to try and find a newLine - for (var i = 0; i < 1000; i++) - { - int b; - if ((b = fs.ReadByte()) == -1) - break; + using var fs = File.OpenRead(path); + char prevChar = '\0'; - char curChar = (char)b; + // read the first 1000 characters to try and find a newLine + for (var i = 0; i < 1000; i++) + { + int b; + if ((b = fs.ReadByte()) == -1) + break; - if (curChar == '\n') - { - newLine = prevChar == '\r' ? "\r\n" : "\n"; - return true; - } + char curChar = (char)b; - prevChar = curChar; + if (curChar == '\n') + { + newLine = prevChar == '\r' ? "\r\n" : "\n"; + return true; } - // Returning false means could not determine linefeed convention - newLine = Environment.NewLine; - return false; + prevChar = curChar; } - } - public static void GetLogFileSeparators(string path, string defSep, out string fieldSep, out string dateSep) - { - // we know the dayfile and monthly log files start with - // dd/MM/yy,NN,... - // dd/MM/yy,hh:mm,N.N,.... - // so we just need to find the first separator after the date before a number - using (var sr = new StreamReader(path)) - { - string line = sr.ReadLine(); - var reg = Regex.Match(line, @"\d{2}[^\d]+\d{2}[^\d]+\d{2}([^\d])"); - if (reg.Success) - fieldSep = reg.Groups[1].Value; - else - fieldSep = defSep; - - var fields = line.Split(new string[] { fieldSep }, StringSplitOptions.None); - dateSep = Regex.Match(fields[0], @"[^0-9]+").Value; - } - Program.LogMessage($"File [{path}] found separators: field=[{fieldSep}] date=[{dateSep}]"); + // Returning false means could not determine linefeed convention + newLine = Environment.NewLine; + return false; } } } From 7800524fe7fcba836a72b29840e230b0e221c427 Mon Sep 17 00:00:00 2001 From: Mark Crossley Date: Tue, 6 Feb 2024 10:44:03 +0000 Subject: [PATCH 03/12] Code updates & post build task update --- CreateMissing.csproj | 2 +- DayFile.cs | 133 +++++++++++++++++++++---------------------- 2 files changed, 66 insertions(+), 69 deletions(-) diff --git a/CreateMissing.csproj b/CreateMissing.csproj index 42233cc..9e5bb51 100644 --- a/CreateMissing.csproj +++ b/CreateMissing.csproj @@ -14,6 +14,6 @@ DEBUG;TRACE - + \ No newline at end of file diff --git a/DayFile.cs b/DayFile.cs index 7085204..15012b2 100644 --- a/DayFile.cs +++ b/DayFile.cs @@ -37,6 +37,7 @@ public DayFile() public void LoadDayFile() { int addedEntries = 0; + var inv = CultureInfo.InvariantCulture; Program.LogMessage($"LoadDayFile: Attempting to load the day file"); Console.WriteLine("Attempting to load the day file"); @@ -56,67 +57,65 @@ public void LoadDayFile() try { - using (var sr = new StreamReader(dayFileName)) - { - var lastDate = DateTime.MinValue; + using var sr = new StreamReader(dayFileName); + var lastDate = DateTime.MinValue; - do + do + { + try { - try + // process each record in the file + + + linenum++; + string Line = sr.ReadLine(); + var newRec = ParseDayFileRec(Line); + + // sanity check if this date is in sequence + if (newRec.Date < lastDate) { - // process each record in the file - - - linenum++; - string Line = sr.ReadLine(); - var newRec = ParseDayFileRec(Line); - - // sanity check if this date is in sequence - if (newRec.Date < lastDate) - { - Program.LogMessage($"LoadDayFile: Error - Date is out of order at line {linenum} of {dayFileName}, '{newRec.Date.ToString("dd" + DateSep + "MM" + DateSep + "yy")}'"); - Console.WriteLine(); - Program.LogConsole($"Error, date is out of order at line {linenum} of {dayFileName}, '{newRec.Date.ToString("dd" + DateSep + "MM" + DateSep + "yy")}'", ConsoleColor.Red); - errorCount++; - } - - // sanity check if this date has already been added - //var matches = DayfileRecs.Where(p => p.Date == newRec.Date).ToList(); - // (matches.Count > 0) - //Since we now know the order is correct, we can do a simple date compare - if (newRec.Date == lastDate) - { - Program.LogMessage($"LoadDayFile: Error - Duplicate date at line {linenum} of {dayFileName}, '{newRec.Date.ToString("dd" + DateSep + "MM" + DateSep + "yy")}'"); - Console.WriteLine(); - Program.LogConsole($"Error, duplicate date at line {linenum} of {dayFileName}, '{newRec.Date.ToString("dd" + DateSep + "MM" + DateSep + "yy")}'", ConsoleColor.Red); - Environment.Exit(4); - } - - if (errorCount == 0) - { - DayfileRecs.Add(newRec); - } - - lastDate = newRec.Date; - - addedEntries++; + Program.LogMessage($"LoadDayFile: Error - Date is out of order at line {linenum} of {dayFileName}, '{newRec.Date.ToString("dd/MM/yy", inv)}'"); + Console.WriteLine(); + Program.LogConsole($"Error, date is out of order at line {linenum} of {dayFileName}, '{newRec.Date.ToString("dd/MM/yy", inv)}'", ConsoleColor.Red); + errorCount++; } - catch (Exception e) + + // sanity check if this date has already been added + //var matches = DayfileRecs.Where(p => p.Date == newRec.Date).ToList(); + // (matches.Count > 0) + //Since we now know the order is correct, we can do a simple date compare + if (newRec.Date == lastDate) { - Program.LogMessage($"LoadDayFile: Error at line {linenum} of {dayFileName} : {e.Message}"); - Program.LogMessage("Please edit the file to correct the error"); - errorCount++; - if (errorCount >= 20) - { - Program.LogMessage($"LoadDayFile: Too many errors reading {dayFileName} - aborting load of daily data"); - Console.WriteLine(); - Program.LogConsole($"Too many errors reading {dayFileName} - aborting load of daily data", ConsoleColor.Red); - Program.LogConsole("Please see the log file for more details", ConsoleColor.Red); - Environment.Exit(5); - } + Program.LogMessage($"LoadDayFile: Error - Duplicate date at line {linenum} of {dayFileName}, '{newRec.Date.ToString("dd/MM/yy", inv)}'"); + Console.WriteLine(); + Program.LogConsole($"Error, duplicate date at line {linenum} of {dayFileName}, '{newRec.Date.ToString("dd/MM/yy", inv)}'", ConsoleColor.Red); + Environment.Exit(4); + } + + if (errorCount == 0) + { + DayfileRecs.Add(newRec); + } + + lastDate = newRec.Date; + + addedEntries++; + } + catch (Exception e) + { + Program.LogMessage($"LoadDayFile: Error at line {linenum} of {dayFileName} : {e.Message}"); + Program.LogMessage("Please edit the file to correct the error"); + errorCount++; + if (errorCount >= 20) + { + Program.LogMessage($"LoadDayFile: Too many errors reading {dayFileName} - aborting load of daily data"); + Console.WriteLine(); + Program.LogConsole($"Too many errors reading {dayFileName} - aborting load of daily data", ConsoleColor.Red); + Program.LogConsole("Please see the log file for more details", ConsoleColor.Red); + Environment.Exit(5); } - } while (!sr.EndOfStream); - } + } + } while (!sr.EndOfStream); } catch (Exception e) { @@ -157,22 +156,20 @@ public void WriteDayFile() try { - using (FileStream fs = new FileStream(dayFileName, FileMode.Append, FileAccess.Write, FileShare.Read)) - using (StreamWriter file = new StreamWriter(fs)) - { - Program.LogMessage("Dayfile.txt opened for writing"); - - file.NewLine = LineEnding; + using FileStream fs = new FileStream(dayFileName, FileMode.Append, FileAccess.Write, FileShare.Read); + using StreamWriter file = new StreamWriter(fs); + Program.LogMessage("Dayfile.txt opened for writing"); - foreach (var rec in DayfileRecs) - { - var line = RecToCsv(rec); - if (null != line) - file.WriteLine(line); - } + file.NewLine = LineEnding; - file.Close(); + foreach (var rec in DayfileRecs) + { + var line = RecToCsv(rec); + if (null != line) + file.WriteLine(line); } + + file.Close(); } catch (Exception ex) { From c7e30ecff9a7dfc90ff88088e9a1b2812411245f Mon Sep 17 00:00:00 2001 From: Mark Crossley Date: Wed, 7 Feb 2024 10:06:45 +0000 Subject: [PATCH 04/12] build bump --- CreateMissing.csproj | 2 +- Program.cs | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/CreateMissing.csproj b/CreateMissing.csproj index 9e5bb51..ba45ecc 100644 --- a/CreateMissing.csproj +++ b/CreateMissing.csproj @@ -3,7 +3,7 @@ Exe $(PackageVersion) $(PackageVersion) - 2.0.0 + 2.0.0.0001 CreateMissing.Program net8.0 Mark Crossley diff --git a/Program.cs b/Program.cs index cbdafc8..0c27491 100644 --- a/Program.cs +++ b/Program.cs @@ -2,10 +2,8 @@ using System; using System.Collections.Generic; using System.Diagnostics; -using System.Globalization; using System.IO; using System.Linq; -using System.Threading; namespace CreateMissing { From 5614bb3018bc1d11049b3611b70add415435bc44 Mon Sep 17 00:00:00 2001 From: Mark Crossley Date: Mon, 11 Mar 2024 12:30:36 +0000 Subject: [PATCH 05/12] Fix day file parse error --- CreateMissing.csproj | 2 +- DayFile.cs | 126 +++++++++++++++++++++---------------------- Program.cs | 12 ++--- Utils.cs | 6 +-- 4 files changed, 72 insertions(+), 74 deletions(-) diff --git a/CreateMissing.csproj b/CreateMissing.csproj index ba45ecc..207f399 100644 --- a/CreateMissing.csproj +++ b/CreateMissing.csproj @@ -3,7 +3,7 @@ Exe $(PackageVersion) $(PackageVersion) - 2.0.0.0001 + 2.0.0.0002 CreateMissing.Program net8.0 Mark Crossley diff --git a/DayFile.cs b/DayFile.cs index 15012b2..a41e962 100644 --- a/DayFile.cs +++ b/DayFile.cs @@ -81,7 +81,7 @@ public void LoadDayFile() } // sanity check if this date has already been added - //var matches = DayfileRecs.Where(p => p.Date == newRec.Date).ToList(); + //var matches = DayfileRecs.Where(p => p.Date == newRec.Date).ToList() // (matches.Count > 0) //Since we now know the order is correct, we can do a simple date compare if (newRec.Date == lastDate) @@ -249,7 +249,7 @@ private static string RecToCsv(Dayfilerec rec) if (rec.HighGust == -9999) return null; - //strb.Append("0.0" + listsep + "0" + listsep + "00:00" + listsep); + //strb.Append("0.0" + listsep + "0" + listsep + "00:00" + listsep) else { strb.Append(rec.HighGust.ToString(Program.cumulus.WindFormat, inv) + sep); @@ -259,7 +259,7 @@ private static string RecToCsv(Dayfilerec rec) if (rec.LowTemp == 9999) return null; - //strb.Append("0.0" + listsep + "00:00" + listsep); + //strb.Append("0.0" + listsep + "00:00" + listsep) else { strb.Append(rec.LowTemp.ToString(Program.cumulus.TempFormat, inv) + sep); @@ -268,7 +268,7 @@ private static string RecToCsv(Dayfilerec rec) if (rec.HighTemp == -9999) return null; - //strb.Append("0.0" + listsep + "00:00" + listsep); + //strb.Append("0.0" + listsep + "00:00" + listsep) else { strb.Append(rec.HighTemp.ToString(Program.cumulus.TempFormat, inv) + sep); @@ -277,7 +277,7 @@ private static string RecToCsv(Dayfilerec rec) if (rec.LowPress == 9999) return null; - //strb.Append("0.0" + listsep + "00:00" + listsep); + //strb.Append("0.0" + listsep + "00:00" + listsep) else { strb.Append(rec.LowPress.ToString(Program.cumulus.PressFormat, inv) + sep); @@ -286,7 +286,7 @@ private static string RecToCsv(Dayfilerec rec) if (rec.HighPress == -9999) return null; - //strb.Append("0.0" + listsep + "00:00" + listsep); + //strb.Append("0.0" + listsep + "00:00" + listsep) else { strb.Append(rec.HighPress.ToString(Program.cumulus.PressFormat, inv) + sep); @@ -295,7 +295,7 @@ private static string RecToCsv(Dayfilerec rec) if (rec.HighRainRate == -9999) return null; - //strb.Append("0.0" + listsep + "00:00" + listsep); + //strb.Append("0.0" + listsep + "00:00" + listsep) else { strb.Append(rec.HighRainRate.ToString(Program.cumulus.RainFormat, inv) + sep); @@ -304,7 +304,7 @@ private static string RecToCsv(Dayfilerec rec) if (rec.TotalRain == -9999) return null; - //strb.Append("0.0" + listsep); + //strb.Append("0.0" + listsep) else strb.Append(rec.TotalRain.ToString(Program.cumulus.RainFormat, inv) + sep); @@ -615,61 +615,61 @@ private static Dayfilerec ParseDayFileRec(string data) public class Dayfilerec { - public DateTime Date; - public double HighGust; - public int HighGustBearing; - public DateTime HighGustTime; - public double LowTemp; - public DateTime LowTempTime; - public double HighTemp; - public DateTime HighTempTime; - public double LowPress; - public DateTime LowPressTime; - public double HighPress; - public DateTime HighPressTime; - public double HighRainRate; - public DateTime HighRainRateTime; - public double TotalRain; - public double AvgTemp; - public double WindRun; - public double HighAvgWind; - public DateTime HighAvgWindTime; - public int LowHumidity; - public DateTime LowHumidityTime; - public int HighHumidity; - public DateTime HighHumidityTime; - public double ET; - public double SunShineHours; - public double HighHeatIndex; - public DateTime HighHeatIndexTime; - public double HighAppTemp; - public DateTime HighAppTempTime; - public double LowAppTemp; - public DateTime LowAppTempTime; - public double HighHourlyRain; - public DateTime HighHourlyRainTime; - public double LowWindChill; - public DateTime LowWindChillTime; - public double HighDewPoint; - public DateTime HighDewPointTime; - public double LowDewPoint; - public DateTime LowDewPointTime; - public int DominantWindBearing; - public double HeatingDegreeDays; - public double CoolingDegreeDays; - public int HighSolar; - public DateTime HighSolarTime; - public double HighUv; - public DateTime HighUvTime; - public double HighFeelsLike; - public DateTime HighFeelsLikeTime; - public double LowFeelsLike; - public DateTime LowFeelsLikeTime; - public double HighHumidex; - public DateTime HighHumidexTime; - public double ChillHours; - public double HighRain24h; - public DateTime HighRain24hTime; + public DateTime Date { get; set; } + public double HighGust { get; set; } + public int HighGustBearing { get; set; } + public DateTime HighGustTime { get; set; } + public double LowTemp { get; set; } + public DateTime LowTempTime { get; set; } + public double HighTemp { get; set; } + public DateTime HighTempTime { get; set; } + public double LowPress { get; set; } + public DateTime LowPressTime { get; set; } + public double HighPress { get; set; } + public DateTime HighPressTime { get; set; } + public double HighRainRate { get; set; } + public DateTime HighRainRateTime { get; set; } + public double TotalRain { get; set; } + public double AvgTemp { get; set; } + public double WindRun { get; set; } + public double HighAvgWind { get; set; } + public DateTime HighAvgWindTime { get; set; } + public int LowHumidity { get; set; } + public DateTime LowHumidityTime { get; set; } + public int HighHumidity { get; set; } + public DateTime HighHumidityTime { get; set; } + public double ET { get; set; } + public double SunShineHours { get; set; } + public double HighHeatIndex { get; set; } + public DateTime HighHeatIndexTime { get; set; } + public double HighAppTemp { get; set; } + public DateTime HighAppTempTime { get; set; } + public double LowAppTemp { get; set; } + public DateTime LowAppTempTime { get; set; } + public double HighHourlyRain { get; set; } + public DateTime HighHourlyRainTime { get; set; } + public double LowWindChill { get; set; } + public DateTime LowWindChillTime { get; set; } + public double HighDewPoint { get; set; } + public DateTime HighDewPointTime { get; set; } + public double LowDewPoint { get; set; } + public DateTime LowDewPointTime { get; set; } + public int DominantWindBearing { get; set; } + public double HeatingDegreeDays { get; set; } + public double CoolingDegreeDays { get; set; } + public int HighSolar { get; set; } + public DateTime HighSolarTime { get; set; } + public double HighUv { get; set; } + public DateTime HighUvTime { get; set; } + public double HighFeelsLike { get; set; } + public DateTime HighFeelsLikeTime { get; set; } + public double LowFeelsLike { get; set; } + public DateTime LowFeelsLikeTime { get; set; } + public double HighHumidex { get; set; } + public DateTime HighHumidexTime { get; set; } + public double ChillHours { get; set; } + public double HighRain24h { get; set; } + public DateTime HighRain24hTime { get; set; } public Dayfilerec() { diff --git a/Program.cs b/Program.cs index 0c27491..e1bdd4f 100644 --- a/Program.cs +++ b/Program.cs @@ -7,7 +7,7 @@ namespace CreateMissing { - class Program + static class Program { public static Cumulus cumulus; public static string location; @@ -33,7 +33,7 @@ class Program static void Main() { #if DEBUG - //Thread.CurrentThread.CurrentCulture = new CultureInfo("nl-NL"); + //Thread.CurrentThread.CurrentCulture = new CultureInfo("nl-NL") #endif TextWriterTraceListener myTextListener = new TextWriterTraceListener($"MXdiags{Path.DirectorySeparatorChar}CreateMissing-{DateTime.Now:yyyyMMdd-HHmmss}.txt", "CMlog"); Trace.Listeners.Add(myTextListener); @@ -417,7 +417,7 @@ private static Dayfilerec GetDayRecFromMonthly(DateTime date) continue; } - //var st = new List(Regex.Split(line, CultureInfo.CurrentCulture.TextInfo.ListSeparator)); + //var st = new List(Regex.Split(line, CultureInfo.CurrentCulture.TextInfo.ListSeparator)) // Regex is very expensive, let's assume the separator is always a single character var st = new List(CurrentLogLines[CurrentLogLineNum++].Split(',')); var entrydate = Utils.DdmmyyhhmmStrToDate(st[0], st[1]); @@ -827,7 +827,7 @@ private static Dayfilerec GetDayRecFromMonthly(DateTime date) // after that build the total was reset to zero in the 00:00 entry // messy! // no final rainfall entry after this date (approx). The best we can do is add in the increase in rain counter during this preiod - var rolloverRain = double.Parse(st[9]); // 9 - rain so far today + //var rolloverRain = double.Parse(st[9]); // 9 - rain so far today var rolloverRaincounter = double.Parse(st[11]); // 11 - rain counter rec.TotalRain += (rolloverRaincounter - lastentrycounter) * cumulus.CalibRainMult; @@ -922,8 +922,6 @@ private static Dayfilerec GetDayRecFromMonthly(DateTime date) return rec; } - - //return null; } if (fileDate > date) { @@ -1371,7 +1369,7 @@ private static DateTime SetStartTime(DateTime thedate) TimeZoneInfo tz = TimeZoneInfo.Local; // Date without time - DateTime rawDate = new DateTime(thedate.Year, thedate.Month, thedate.Day); + DateTime rawDate = new DateTime(thedate.Year, thedate.Month, thedate.Day, 0, 0, 0, DateTimeKind.Local); if (cumulus.Use10amInSummer && tz.IsDaylightSavingTime(thedate)) { diff --git a/Utils.cs b/Utils.cs index de6f5fa..361cdc4 100644 --- a/Utils.cs +++ b/Utils.cs @@ -6,7 +6,7 @@ namespace CreateMissing { - class Utils + static class Utils { public static DateTime DdmmyyStrToDate(string d) { @@ -28,8 +28,8 @@ public static DateTime DdmmyyhhmmStrToDate(string d, string t) public static DateTime GetDateTime(DateTime date, string time) { - var tim = time.Split(','); - return new DateTime(date.Year, date.Month, date.Day, int.Parse(tim[0]), int.Parse(tim[1]), 0); + var tim = time.Split(':'); + return new DateTime(date.Year, date.Month, date.Day, int.Parse(tim[0]), int.Parse(tim[1]), 0, DateTimeKind.Local); } public static double UserTempToC(double value) From 0a7113d4ef5fd998ca0d4647ef651aaae1359320 Mon Sep 17 00:00:00 2001 From: Mark Crossley Date: Thu, 20 Jun 2024 20:32:34 +0100 Subject: [PATCH 06/12] Fix locale issues reading log files --- CreateMissing.csproj | 2 +- DayFile.cs | 24 +++++++++++++++++++++++ Program.cs | 46 ++++++++++++++++++++++++-------------------- 3 files changed, 50 insertions(+), 22 deletions(-) diff --git a/CreateMissing.csproj b/CreateMissing.csproj index 207f399..840daf8 100644 --- a/CreateMissing.csproj +++ b/CreateMissing.csproj @@ -3,7 +3,7 @@ Exe $(PackageVersion) $(PackageVersion) - 2.0.0.0002 + 2.0.1.0003 CreateMissing.Program net8.0 Mark Crossley diff --git a/DayFile.cs b/DayFile.cs index a41e962..114bdc4 100644 --- a/DayFile.cs +++ b/DayFile.cs @@ -248,8 +248,11 @@ private static string RecToCsv(Dayfilerec rec) strb.Append(datestring + sep); if (rec.HighGust == -9999) + { + Program.LogMessage("Mandatory value High Gust missing, skipping this day"); return null; //strb.Append("0.0" + listsep + "0" + listsep + "00:00" + listsep) + } else { strb.Append(rec.HighGust.ToString(Program.cumulus.WindFormat, inv) + sep); @@ -258,8 +261,11 @@ private static string RecToCsv(Dayfilerec rec) } if (rec.LowTemp == 9999) + { + Program.LogMessage("Mandatory value Low Temp missing, skipping this day"); return null; //strb.Append("0.0" + listsep + "00:00" + listsep) + } else { strb.Append(rec.LowTemp.ToString(Program.cumulus.TempFormat, inv) + sep); @@ -267,8 +273,11 @@ private static string RecToCsv(Dayfilerec rec) } if (rec.HighTemp == -9999) + { + Program.LogMessage("Mandatory value High Temp missing, skipping this day"); return null; //strb.Append("0.0" + listsep + "00:00" + listsep) + } else { strb.Append(rec.HighTemp.ToString(Program.cumulus.TempFormat, inv) + sep); @@ -276,8 +285,11 @@ private static string RecToCsv(Dayfilerec rec) } if (rec.LowPress == 9999) + { + Program.LogMessage("Mandatory value Low Press missing, skipping this day"); return null; //strb.Append("0.0" + listsep + "00:00" + listsep) + } else { strb.Append(rec.LowPress.ToString(Program.cumulus.PressFormat, inv) + sep); @@ -285,8 +297,11 @@ private static string RecToCsv(Dayfilerec rec) } if (rec.HighPress == -9999) + { + Program.LogMessage("Mandatory value High Press missing, skipping this day"); return null; //strb.Append("0.0" + listsep + "00:00" + listsep) + } else { strb.Append(rec.HighPress.ToString(Program.cumulus.PressFormat, inv) + sep); @@ -294,8 +309,11 @@ private static string RecToCsv(Dayfilerec rec) } if (rec.HighRainRate == -9999) + { + Program.LogMessage("Mandatory value High Rain Rate missing, skipping this day"); return null; //strb.Append("0.0" + listsep + "00:00" + listsep) + } else { strb.Append(rec.HighRainRate.ToString(Program.cumulus.RainFormat, inv) + sep); @@ -303,13 +321,19 @@ private static string RecToCsv(Dayfilerec rec) } if (rec.TotalRain == -9999) + { + Program.LogMessage("Mandatory value Total Rain missing, skipping this day"); return null; //strb.Append("0.0" + listsep) + } else strb.Append(rec.TotalRain.ToString(Program.cumulus.RainFormat, inv) + sep); if (rec.AvgTemp == -9999) + { + Program.LogMessage("Mandatory value Avg Temp missing, skipping this day"); strb.Append(sep); + } else strb.Append(rec.AvgTemp.ToString(Program.cumulus.TempFormat, inv) + sep); diff --git a/Program.cs b/Program.cs index e1bdd4f..377879e 100644 --- a/Program.cs +++ b/Program.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Generic; using System.Diagnostics; +using System.Globalization; using System.IO; using System.Linq; @@ -33,7 +34,7 @@ static class Program static void Main() { #if DEBUG - //Thread.CurrentThread.CurrentCulture = new CultureInfo("nl-NL") + //System.Threading.Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo("sl-SL") #endif TextWriterTraceListener myTextListener = new TextWriterTraceListener($"MXdiags{Path.DirectorySeparatorChar}CreateMissing-{DateTime.Now:yyyyMMdd-HHmmss}.txt", "CMlog"); Trace.Listeners.Add(myTextListener); @@ -83,6 +84,7 @@ static void Main() Console.WriteLine("Exiting..."); Environment.Exit(1); } + Console.WriteLine(); // Sanity check #2 @@ -313,6 +315,8 @@ private static Dayfilerec GetDayRecFromMonthly(DateTime date) ChillHours = 0 }; + var inv = CultureInfo.InvariantCulture; + var started = false; var finished = false; var recCount = 0; @@ -435,8 +439,8 @@ private static Dayfilerec GetDayRecFromMonthly(DateTime date) // after that build the total was reset to zero in the entry // messy! // no final rainfall entry after this date (approx). The best we can do is add in the increase in rain counter during this preiod - var rain = double.Parse(st[9]); // 9 - var raincounter = double.Parse(st[11]); // 11 + var rain = double.Parse(st[9], inv); // 9 + var raincounter = double.Parse(st[11], inv); // 11 // we need to initalise the rain counter on the first record if (rain1hLog.Count == 0) @@ -482,16 +486,16 @@ private static Dayfilerec GetDayRecFromMonthly(DateTime date) if (entrydate >= startTime && entrydate <= endTime) { recCount++; - var outsidetemp = double.Parse(st[++idx]); // 2 - var hum = int.Parse(st[++idx]); // 3 - var dewpoint = double.Parse(st[++idx]); // 4 - var speed = double.Parse(st[++idx]); // 5 - var gust = double.Parse(st[++idx]); // 6 - var avgbearing = int.Parse(st[++idx]); // 7 - var rainrate = double.Parse(st[++idx]); // 8 - var raintoday = double.Parse(st[++idx]); // 9 - var pressure = double.Parse(st[++idx]); // 10 - var raincounter = double.Parse(st[++idx]); // 11 + var outsidetemp = double.Parse(st[++idx], inv); // 2 + var hum = int.Parse(st[++idx]); // 3 + var dewpoint = double.Parse(st[++idx], inv); // 4 + var speed = double.Parse(st[++idx], inv); // 5 + var gust = double.Parse(st[++idx], inv); // 6 + var avgbearing = int.Parse(st[++idx], inv); // 7 + var rainrate = double.Parse(st[++idx], inv); // 8 + var raintoday = double.Parse(st[++idx], inv); // 9 + var pressure = double.Parse(st[++idx], inv); // 10 + var raincounter = double.Parse(st[++idx], inv); // 11 if (!started) { @@ -506,12 +510,12 @@ private static Dayfilerec GetDayRecFromMonthly(DateTime date) { // current gust idx = 14; - if (st.Count > idx && double.TryParse(st[idx], out valDbl) && valDbl > rec.HighGust) + if (st.Count > idx && double.TryParse(st[idx], inv, out valDbl) && valDbl > rec.HighGust) { rec.HighGust = valDbl; rec.HighGustTime = entrydate; idx = 24; - if (st.Count > idx && int.TryParse(st[idx], out valInt)) + if (st.Count > idx && int.TryParse(st[idx], inv, out valInt)) { rec.HighGustBearing = valInt; } @@ -522,7 +526,7 @@ private static Dayfilerec GetDayRecFromMonthly(DateTime date) } // low chill idx = 15; - if (st.Count > idx && double.TryParse(st[idx], out valDbl) && valDbl < rec.LowWindChill) + if (st.Count > idx && double.TryParse(st[idx], inv, out valDbl) && valDbl < rec.LowWindChill) { rec.LowWindChill = valDbl; rec.LowWindChillTime = entrydate; @@ -539,7 +543,7 @@ private static Dayfilerec GetDayRecFromMonthly(DateTime date) } // hi heat idx = 16; - if (st.Count > idx && double.TryParse(st[idx], out valDbl) && valDbl > rec.HighHeatIndex) + if (st.Count > idx && double.TryParse(st[idx], inv, out valDbl) && valDbl > rec.HighHeatIndex) { rec.HighHeatIndex = valDbl; rec.HighHeatIndexTime = entrydate; @@ -556,7 +560,7 @@ private static Dayfilerec GetDayRecFromMonthly(DateTime date) } // hi/low appt idx = 21; - if (st.Count > idx && double.TryParse(st[idx], out valDbl)) + if (st.Count > idx && double.TryParse(st[idx], inv, out valDbl)) { if (valDbl > rec.HighAppTemp) { @@ -588,7 +592,7 @@ private static Dayfilerec GetDayRecFromMonthly(DateTime date) // hi/low feels like idx = 27; - if (st.Count > idx && double.TryParse(st[idx], out valDbl)) + if (st.Count > idx && double.TryParse(st[idx], inv, out valDbl)) { if (valDbl > rec.HighFeelsLike) { @@ -619,7 +623,7 @@ private static Dayfilerec GetDayRecFromMonthly(DateTime date) // hi humidex idx = 28; - if (st.Count > idx && double.TryParse(st[idx], out valDbl)) + if (st.Count > idx && double.TryParse(st[idx], inv, out valDbl)) { if (valDbl > rec.HighHumidex) { @@ -828,7 +832,7 @@ private static Dayfilerec GetDayRecFromMonthly(DateTime date) // messy! // no final rainfall entry after this date (approx). The best we can do is add in the increase in rain counter during this preiod //var rolloverRain = double.Parse(st[9]); // 9 - rain so far today - var rolloverRaincounter = double.Parse(st[11]); // 11 - rain counter + var rolloverRaincounter = double.Parse(st[11], inv); // 11 - rain counter rec.TotalRain += (rolloverRaincounter - lastentrycounter) * cumulus.CalibRainMult; From 5d4b13b6d617e5b9abd4f116c34ee56d75ee6878 Mon Sep 17 00:00:00 2001 From: Mark Crossley Date: Mon, 5 Feb 2024 23:07:46 +0000 Subject: [PATCH 07/12] Converted to .Net 8.0 --- CreateMissing.csproj | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/CreateMissing.csproj b/CreateMissing.csproj index ef5819a..3990c33 100644 --- a/CreateMissing.csproj +++ b/CreateMissing.csproj @@ -1,23 +1,19 @@ - Exe $(PackageVersion) $(PackageVersion) 1.4.3 CreateMissing.Program - net48 + net8.0 Mark Crossley Cumulus MX AnyCPU - DEBUG;TRACE - - - + \ No newline at end of file From fb0593c9f5e662c3f8202c48c955e29da0a068a7 Mon Sep 17 00:00:00 2001 From: Mark Crossley Date: Mon, 5 Feb 2024 23:31:59 +0000 Subject: [PATCH 08/12] Initial conversion to CMX v4 --- CreateMissing.csproj | 2 +- Cumulus.cs | 28 ++++++ DayFile.cs | 216 +++++++++++++++++++++---------------------- Program.cs | 41 ++++---- Updates.txt | 6 ++ Utils.cs | 154 +++++++++--------------------- 6 files changed, 203 insertions(+), 244 deletions(-) diff --git a/CreateMissing.csproj b/CreateMissing.csproj index 3990c33..42233cc 100644 --- a/CreateMissing.csproj +++ b/CreateMissing.csproj @@ -3,7 +3,7 @@ Exe $(PackageVersion) $(PackageVersion) - 1.4.3 + 2.0.0 CreateMissing.Program net8.0 Mark Crossley diff --git a/Cumulus.cs b/Cumulus.cs index 2044c32..3c956f8 100644 --- a/Cumulus.cs +++ b/Cumulus.cs @@ -162,6 +162,34 @@ private void ReadIniFile() } } + public int GetHourInc(DateTime timestamp) + { + if (RolloverHour == 0) + { + return 0; + } + else + { + try + { + if (Use10amInSummer && TimeZoneInfo.Local.IsDaylightSavingTime(timestamp)) + { + // Locale is currently on Daylight time + return -10; + } + else + { + // Locale is currently on Standard time or unknown + return -9; + } + } + catch (Exception) + { + return -9; + } + } + } + } internal class StationUnits diff --git a/DayFile.cs b/DayFile.cs index bf12450..7085204 100644 --- a/DayFile.cs +++ b/DayFile.cs @@ -11,11 +11,9 @@ namespace CreateMissing class DayFile { - public List DayfileRecs = new List(); + public List DayfileRecs = []; public string LineEnding = string.Empty; - public string FieldSep = string.Empty; - public string DateSep = string.Empty; private readonly string dayFileName = Program.location + "data" + Path.DirectorySeparatorChar + "dayfile.txt"; @@ -52,8 +50,6 @@ public void LoadDayFile() { LineEnding = lineend; } - // determine the dayfile field and date separators - Utils.GetLogFileSeparators(dayFileName, CultureInfo.CurrentCulture.TextInfo.ListSeparator, out FieldSep, out DateSep); // Clear the existing list DayfileRecs.Clear(); @@ -185,7 +181,7 @@ public void WriteDayFile() } - private string RecToCsv(Dayfilerec rec) + private static string RecToCsv(Dayfilerec rec) { // Writes an entry to the daily extreme log file. Fields are comma-separated. // 0 Date in the form dd/mm/yy (the slash may be replaced by a dash in some cases) @@ -245,22 +241,23 @@ private string RecToCsv(Dayfilerec rec) // 53 High 24 hr rain // 54 Time of high 24 hr rain - + var inv = CultureInfo.InvariantCulture; + var sep = ","; // Write the date back using the same separator as the source file - string datestring = rec.Date.ToString($"dd{DateSep}MM{DateSep}yy"); + string datestring = rec.Date.ToString($"dd/MM/yy", inv); // NB this string is just for logging, the dayfile update code is further down var strb = new StringBuilder(300); - strb.Append(datestring + FieldSep); + strb.Append(datestring + sep); if (rec.HighGust == -9999) return null; //strb.Append("0.0" + listsep + "0" + listsep + "00:00" + listsep); else { - strb.Append(rec.HighGust.ToString(Program.cumulus.WindFormat) + FieldSep); - strb.Append(rec.HighGustBearing + FieldSep); - strb.Append(rec.HighGustTime.ToString("HH:mm") + FieldSep); + strb.Append(rec.HighGust.ToString(Program.cumulus.WindFormat, inv) + sep); + strb.Append(rec.HighGustBearing + sep); + strb.Append(rec.HighGustTime.ToString("HH:mm", inv) + sep); } if (rec.LowTemp == 9999) @@ -268,8 +265,8 @@ private string RecToCsv(Dayfilerec rec) //strb.Append("0.0" + listsep + "00:00" + listsep); else { - strb.Append(rec.LowTemp.ToString(Program.cumulus.TempFormat) + FieldSep); - strb.Append(rec.LowTempTime.ToString("HH:mm") + FieldSep); + strb.Append(rec.LowTemp.ToString(Program.cumulus.TempFormat, inv) + sep); + strb.Append(rec.LowTempTime.ToString("HH:mm", inv) + sep); } if (rec.HighTemp == -9999) @@ -277,8 +274,8 @@ private string RecToCsv(Dayfilerec rec) //strb.Append("0.0" + listsep + "00:00" + listsep); else { - strb.Append(rec.HighTemp.ToString(Program.cumulus.TempFormat) + FieldSep); - strb.Append(rec.HighTempTime.ToString("HH:mm") + FieldSep); + strb.Append(rec.HighTemp.ToString(Program.cumulus.TempFormat, inv) + sep); + strb.Append(rec.HighTempTime.ToString("HH:mm", inv) + sep); } if (rec.LowPress == 9999) @@ -286,8 +283,8 @@ private string RecToCsv(Dayfilerec rec) //strb.Append("0.0" + listsep + "00:00" + listsep); else { - strb.Append(rec.LowPress.ToString(Program.cumulus.PressFormat) + FieldSep); - strb.Append(rec.LowPressTime.ToString("HH:mm") + FieldSep); + strb.Append(rec.LowPress.ToString(Program.cumulus.PressFormat, inv) + sep); + strb.Append(rec.LowPressTime.ToString("HH:mm", inv) + sep); } if (rec.HighPress == -9999) @@ -295,8 +292,8 @@ private string RecToCsv(Dayfilerec rec) //strb.Append("0.0" + listsep + "00:00" + listsep); else { - strb.Append(rec.HighPress.ToString(Program.cumulus.PressFormat) + FieldSep); - strb.Append(rec.HighPressTime.ToString("HH:mm") + FieldSep); + strb.Append(rec.HighPress.ToString(Program.cumulus.PressFormat, inv) + sep); + strb.Append(rec.HighPressTime.ToString("HH:mm", inv) + sep); } if (rec.HighRainRate == -9999) @@ -304,158 +301,158 @@ private string RecToCsv(Dayfilerec rec) //strb.Append("0.0" + listsep + "00:00" + listsep); else { - strb.Append(rec.HighRainRate.ToString(Program.cumulus.RainFormat) + FieldSep); - strb.Append(rec.HighRainRateTime.ToString("HH:mm") + FieldSep); + strb.Append(rec.HighRainRate.ToString(Program.cumulus.RainFormat, inv) + sep); + strb.Append(rec.HighRainRateTime.ToString("HH:mm", inv) + sep); } if (rec.TotalRain == -9999) return null; //strb.Append("0.0" + listsep); else - strb.Append(rec.TotalRain.ToString(Program.cumulus.RainFormat) + FieldSep); + strb.Append(rec.TotalRain.ToString(Program.cumulus.RainFormat, inv) + sep); if (rec.AvgTemp == -9999) - strb.Append(FieldSep); + strb.Append(sep); else - strb.Append(rec.AvgTemp.ToString(Program.cumulus.TempFormat) + FieldSep); + strb.Append(rec.AvgTemp.ToString(Program.cumulus.TempFormat, inv) + sep); - strb.Append(rec.WindRun.ToString("F1") + FieldSep); + strb.Append(rec.WindRun.ToString("F1", inv) + sep); if (rec.HighAvgWind == -9999) - strb.Append(FieldSep + FieldSep); + strb.Append(sep + sep); else { - strb.Append(rec.HighAvgWind.ToString(Program.cumulus.WindAvgFormat) + FieldSep); - strb.Append(rec.HighAvgWindTime.ToString("HH:mm") + FieldSep); + strb.Append(rec.HighAvgWind.ToString(Program.cumulus.WindAvgFormat, inv) + sep); + strb.Append(rec.HighAvgWindTime.ToString("HH:mm", inv) + sep); } if (rec.LowHumidity == 9999) - strb.Append(FieldSep + FieldSep); + strb.Append(sep + sep); else { - strb.Append(rec.LowHumidity + FieldSep); - strb.Append(rec.LowHumidityTime.ToString("HH:mm") + FieldSep); + strb.Append(rec.LowHumidity + sep); + strb.Append(rec.LowHumidityTime.ToString("HH:mm", inv) + sep); } if (rec.HighHumidity == -9999) - strb.Append(FieldSep + FieldSep); + strb.Append(sep + sep); else { - strb.Append(rec.HighHumidity + FieldSep); - strb.Append(rec.HighHumidityTime.ToString("HH:mm") + FieldSep); + strb.Append(rec.HighHumidity + sep); + strb.Append(rec.HighHumidityTime.ToString("HH:mm", inv) + sep); } - strb.Append(rec.ET.ToString(Program.cumulus.ETFormat) + FieldSep); - strb.Append(rec.SunShineHours.ToString(Program.cumulus.SunFormat) + FieldSep); + strb.Append(rec.ET.ToString(Program.cumulus.ETFormat, inv) + sep); + strb.Append(rec.SunShineHours.ToString(Program.cumulus.SunFormat, inv) + sep); if (rec.HighHeatIndex == -9999) - strb.Append(FieldSep + FieldSep); + strb.Append(sep + sep); else { - strb.Append(rec.HighHeatIndex.ToString(Program.cumulus.TempFormat) + FieldSep); - strb.Append(rec.HighHeatIndexTime.ToString("HH:mm") + FieldSep); + strb.Append(rec.HighHeatIndex.ToString(Program.cumulus.TempFormat, inv) + sep); + strb.Append(rec.HighHeatIndexTime.ToString("HH:mm", inv) + sep); } if (rec.HighAppTemp == -9999) - strb.Append(FieldSep + FieldSep); + strb.Append(sep + sep); else { - strb.Append(rec.HighAppTemp.ToString(Program.cumulus.TempFormat) + FieldSep); - strb.Append(rec.HighAppTempTime.ToString("HH:mm") + FieldSep); + strb.Append(rec.HighAppTemp.ToString(Program.cumulus.TempFormat, inv) + sep); + strb.Append(rec.HighAppTempTime.ToString("HH:mm", inv) + sep); } if (rec.LowAppTemp == 9999) - strb.Append(FieldSep + FieldSep); + strb.Append(sep + sep); else { - strb.Append(rec.LowAppTemp.ToString(Program.cumulus.TempFormat) + FieldSep); - strb.Append(rec.LowAppTempTime.ToString("HH:mm") + FieldSep); + strb.Append(rec.LowAppTemp.ToString(Program.cumulus.TempFormat, inv) + sep); + strb.Append(rec.LowAppTempTime.ToString("HH:mm", inv) + sep); } if (rec.HighHourlyRain == -9999) - strb.Append(FieldSep + FieldSep); + strb.Append(sep + sep); else { - strb.Append(rec.HighHourlyRain.ToString(Program.cumulus.RainFormat) + FieldSep); - strb.Append(rec.HighHourlyRainTime.ToString("HH:mm") + FieldSep); + strb.Append(rec.HighHourlyRain.ToString(Program.cumulus.RainFormat, inv) + sep); + strb.Append(rec.HighHourlyRainTime.ToString("HH:mm", inv) + sep); } if (rec.LowWindChill == 9999) - strb.Append(FieldSep + FieldSep); + strb.Append(sep + sep); else { - strb.Append(rec.LowWindChill.ToString(Program.cumulus.TempFormat) + FieldSep); - strb.Append(rec.LowWindChillTime.ToString("HH:mm") + FieldSep); + strb.Append(rec.LowWindChill.ToString(Program.cumulus.TempFormat, inv) + sep); + strb.Append(rec.LowWindChillTime.ToString("HH:mm", inv) + sep); } if (rec.HighDewPoint == -9999) - strb.Append(FieldSep + FieldSep); + strb.Append(sep + sep); else { - strb.Append(rec.HighDewPoint.ToString(Program.cumulus.TempFormat) + FieldSep); - strb.Append(rec.HighDewPointTime.ToString("HH:mm") + FieldSep); + strb.Append(rec.HighDewPoint.ToString(Program.cumulus.TempFormat, inv) + sep); + strb.Append(rec.HighDewPointTime.ToString("HH:mm", inv) + sep); } if (rec.LowDewPoint == -9999) - strb.Append(FieldSep + FieldSep); + strb.Append(sep + sep); else { - strb.Append(rec.LowDewPoint.ToString(Program.cumulus.TempFormat) + FieldSep); - strb.Append(rec.LowDewPointTime.ToString("HH:mm") + FieldSep); + strb.Append(rec.LowDewPoint.ToString(Program.cumulus.TempFormat, inv) + sep); + strb.Append(rec.LowDewPointTime.ToString("HH:mm", inv) + sep); } if (rec.DominantWindBearing == 9999) - strb.Append(FieldSep); + strb.Append(sep); else - strb.Append(rec.DominantWindBearing + FieldSep); + strb.Append(rec.DominantWindBearing + sep); if (rec.HeatingDegreeDays == -9999) - strb.Append(FieldSep); + strb.Append(sep); else - strb.Append(rec.HeatingDegreeDays.ToString("F1") + FieldSep); + strb.Append(rec.HeatingDegreeDays.ToString("F1", inv) + sep); if (rec.CoolingDegreeDays == -9999) - strb.Append(FieldSep); + strb.Append(sep); else - strb.Append(rec.CoolingDegreeDays.ToString("F1") + FieldSep); + strb.Append(rec.CoolingDegreeDays.ToString("F1", inv) + sep); - strb.Append(rec.HighSolar + FieldSep); - strb.Append(rec.HighSolarTime.ToString("HH:mm") + FieldSep); - strb.Append(rec.HighUv.ToString(Program.cumulus.UVFormat) + FieldSep); - strb.Append(rec.HighUvTime.ToString("HH:mm") + FieldSep); + strb.Append(rec.HighSolar + sep); + strb.Append(rec.HighSolarTime.ToString("HH:mm", inv) + sep); + strb.Append(rec.HighUv.ToString(Program.cumulus.UVFormat, inv) + sep); + strb.Append(rec.HighUvTime.ToString("HH:mm", inv) + sep); if (rec.HighFeelsLike == -9999) - strb.Append(FieldSep + FieldSep); + strb.Append(sep + sep); else { - strb.Append(rec.HighFeelsLike.ToString(Program.cumulus.TempFormat) + FieldSep); - strb.Append(rec.HighFeelsLikeTime.ToString("HH:mm") + FieldSep); + strb.Append(rec.HighFeelsLike.ToString(Program.cumulus.TempFormat, inv) + sep); + strb.Append(rec.HighFeelsLikeTime.ToString("HH:mm", inv) + sep); } if (rec.LowFeelsLike == 9999) - strb.Append(FieldSep + FieldSep); + strb.Append(sep + sep); else { - strb.Append(rec.LowFeelsLike.ToString(Program.cumulus.TempFormat) + FieldSep); - strb.Append(rec.LowFeelsLikeTime.ToString("HH:mm") + FieldSep); + strb.Append(rec.LowFeelsLike.ToString(Program.cumulus.TempFormat, inv) + sep); + strb.Append(rec.LowFeelsLikeTime.ToString("HH:mm", inv) + sep); } if (rec.HighHumidex == -9999) - strb.Append(FieldSep + FieldSep); + strb.Append(sep + sep); else { - strb.Append(rec.HighHumidex.ToString(Program.cumulus.TempFormat) + FieldSep); - strb.Append(rec.HighHumidexTime.ToString("HH:mm") + FieldSep); + strb.Append(rec.HighHumidex.ToString(Program.cumulus.TempFormat, inv) + sep); + strb.Append(rec.HighHumidexTime.ToString("HH:mm", inv) + sep); } if (rec.ChillHours != -9999) - strb.Append(rec.ChillHours.ToString("F1") + FieldSep); + strb.Append(rec.ChillHours.ToString("F1", inv) + sep); if (rec.HighRain24h != -9999) { - strb.Append(rec.HighRain24h.ToString(Program.cumulus.TempFormat) + FieldSep); - strb.Append(rec.HighRain24hTime.ToString("HH:mm")); + strb.Append(rec.HighRain24h.ToString(Program.cumulus.TempFormat, inv) + sep); + strb.Append(rec.HighRain24hTime.ToString("HH:mm", inv)); } Program.LogMessage("Dayfile.txt Added: " + datestring); @@ -463,37 +460,38 @@ private string RecToCsv(Dayfilerec rec) return strb.ToString(); } - private Dayfilerec ParseDayFileRec(string data) + private static Dayfilerec ParseDayFileRec(string data) { - var st = new List(Regex.Split(data, FieldSep)); + var st = new List(data.Split(',')); double varDbl; int varInt; int idx = 0; + var inv = CultureInfo.InvariantCulture; var rec = new Dayfilerec(); try { rec.Date = Utils.DdmmyyStrToDate(st[idx++]); - rec.HighGust = Convert.ToDouble(st[idx++]); + rec.HighGust = Convert.ToDouble(st[idx++], inv); rec.HighGustBearing = Convert.ToInt32(st[idx++]); rec.HighGustTime = Utils.GetDateTime(rec.Date, st[idx++]); - rec.LowTemp = Convert.ToDouble(st[idx++]); + rec.LowTemp = Convert.ToDouble(st[idx++], inv); rec.LowTempTime = Utils.GetDateTime(rec.Date, st[idx++]); - rec.HighTemp = Convert.ToDouble(st[idx++]); + rec.HighTemp = Convert.ToDouble(st[idx++], inv); rec.HighTempTime = Utils.GetDateTime(rec.Date, st[idx++]); - rec.LowPress = Convert.ToDouble(st[idx++]); + rec.LowPress = Convert.ToDouble(st[idx++], inv); rec.LowPressTime = Utils.GetDateTime(rec.Date, st[idx++]); - rec.HighPress = Convert.ToDouble(st[idx++]); + rec.HighPress = Convert.ToDouble(st[idx++], inv); rec.HighPressTime = Utils.GetDateTime(rec.Date, st[idx++]); - rec.HighRainRate = Convert.ToDouble(st[idx++]); + rec.HighRainRate = Convert.ToDouble(st[idx++], inv); rec.HighRainRateTime = Utils.GetDateTime(rec.Date, st[idx++]); - rec.TotalRain = Convert.ToDouble(st[idx++]); - rec.AvgTemp = Convert.ToDouble(st[idx++]); + rec.TotalRain = Convert.ToDouble(st[idx++], inv); + rec.AvgTemp = Convert.ToDouble(st[idx++], inv); - if (st.Count > idx++ && double.TryParse(st[16], out varDbl)) + if (st.Count > idx++ && double.TryParse(st[16], inv, out varDbl)) rec.WindRun = varDbl; - if (st.Count > idx++ && double.TryParse(st[17], out varDbl)) + if (st.Count > idx++ && double.TryParse(st[17], inv, out varDbl)) rec.HighAvgWind = varDbl; if (st.Count > idx++ && st[18].Length == 5) @@ -511,49 +509,49 @@ private Dayfilerec ParseDayFileRec(string data) if (st.Count > idx++ && st[22].Length == 5) rec.HighHumidityTime = Utils.GetDateTime(rec.Date, st[22]); - if (st.Count > idx++ && double.TryParse(st[23], out varDbl)) + if (st.Count > idx++ && double.TryParse(st[23], inv, out varDbl)) rec.ET = varDbl; - if (st.Count > idx++ && double.TryParse(st[24], out varDbl)) + if (st.Count > idx++ && double.TryParse(st[24], inv, out varDbl)) rec.SunShineHours = varDbl; - if (st.Count > idx++ && double.TryParse(st[25], out varDbl)) + if (st.Count > idx++ && double.TryParse(st[25], inv, out varDbl)) rec.HighHeatIndex = varDbl; if (st.Count > idx++ && st[26].Length == 5) rec.HighHeatIndexTime = Utils.GetDateTime(rec.Date, st[26]); - if (st.Count > idx++ && double.TryParse(st[27], out varDbl)) + if (st.Count > idx++ && double.TryParse(st[27], inv, out varDbl)) rec.HighAppTemp = varDbl; if (st.Count > idx++ && st[28].Length == 5) rec.HighAppTempTime = Utils.GetDateTime(rec.Date, st[28]); - if (st.Count > idx++ && double.TryParse(st[29], out varDbl)) + if (st.Count > idx++ && double.TryParse(st[29], inv, out varDbl)) rec.LowAppTemp = varDbl; if (st.Count > idx++ && st[30].Length == 5) rec.LowAppTempTime = Utils.GetDateTime(rec.Date, st[30]); - if (st.Count > idx++ && double.TryParse(st[31], out varDbl)) + if (st.Count > idx++ && double.TryParse(st[31], inv, out varDbl)) rec.HighHourlyRain = varDbl; if (st.Count > idx++ && st[32].Length == 5) rec.HighHourlyRainTime = Utils.GetDateTime(rec.Date, st[32]); - if (st.Count > idx++ && double.TryParse(st[33], out varDbl)) + if (st.Count > idx++ && double.TryParse(st[33], inv, out varDbl)) rec.LowWindChill = varDbl; if (st.Count > idx++ && st[34].Length == 5) rec.LowWindChillTime = Utils.GetDateTime(rec.Date, st[34]); - if (st.Count > idx++ && double.TryParse(st[35], out varDbl)) + if (st.Count > idx++ && double.TryParse(st[35], inv, out varDbl)) rec.HighDewPoint = varDbl; if (st.Count > idx++ && st[36].Length == 5) rec.HighDewPointTime = Utils.GetDateTime(rec.Date, st[36]); - if (st.Count > idx++ && double.TryParse(st[37], out varDbl)) + if (st.Count > idx++ && double.TryParse(st[37], inv, out varDbl)) rec.LowDewPoint = varDbl; if (st.Count > idx++ && st[38].Length == 5) @@ -562,10 +560,10 @@ private Dayfilerec ParseDayFileRec(string data) if (st.Count > idx++ && int.TryParse(st[39], out varInt)) rec.DominantWindBearing = varInt; - if (st.Count > idx++ && double.TryParse(st[40], out varDbl)) + if (st.Count > idx++ && double.TryParse(st[40], inv, out varDbl)) rec.HeatingDegreeDays = varDbl; - if (st.Count > idx++ && double.TryParse(st[41], out varDbl)) + if (st.Count > idx++ && double.TryParse(st[41], inv, out varDbl)) rec.CoolingDegreeDays = varDbl; if (st.Count > idx++ && int.TryParse(st[42], out varInt)) @@ -574,34 +572,34 @@ private Dayfilerec ParseDayFileRec(string data) if (st.Count > idx++ && st[43].Length == 5) rec.HighSolarTime = Utils.GetDateTime(rec.Date, st[43]); - if (st.Count > idx++ && double.TryParse(st[44], out varDbl)) + if (st.Count > idx++ && double.TryParse(st[44], inv, out varDbl)) rec.HighUv = varDbl; if (st.Count > idx++ && st[45].Length == 5) rec.HighUvTime = Utils.GetDateTime(rec.Date, st[45]); - if (st.Count > idx++ && double.TryParse(st[46], out varDbl)) + if (st.Count > idx++ && double.TryParse(st[46], inv, out varDbl)) rec.HighFeelsLike = varDbl; if (st.Count > idx++ && st[47].Length == 5) rec.HighFeelsLikeTime = Utils.GetDateTime(rec.Date, st[47]); - if (st.Count > idx++ && double.TryParse(st[48], out varDbl)) + if (st.Count > idx++ && double.TryParse(st[48], inv, out varDbl)) rec.LowFeelsLike = varDbl; if (st.Count > idx++ && st[49].Length == 5) rec.LowFeelsLikeTime = Utils.GetDateTime(rec.Date, st[49]); - if (st.Count > idx++ && double.TryParse(st[50], out varDbl)) + if (st.Count > idx++ && double.TryParse(st[50], inv, out varDbl)) rec.HighHumidex = varDbl; if (st.Count > idx++ && st[51].Length == 5) rec.HighHumidexTime = Utils.GetDateTime(rec.Date, st[51]); - if (st.Count > idx++ && double.TryParse(st[52], out varDbl)) + if (st.Count > idx++ && double.TryParse(st[52], inv, out varDbl)) rec.ChillHours = varDbl; - if (st.Count > idx++ && double.TryParse(st[53], out varDbl)) + if (st.Count > idx++ && double.TryParse(st[53], inv, out varDbl)) rec.HighRain24h = varDbl; if (st.Count > idx++ && st[54].Length == 5) diff --git a/Program.cs b/Program.cs index 01b3992..cbdafc8 100644 --- a/Program.cs +++ b/Program.cs @@ -17,11 +17,11 @@ class Program private static ConsoleColor defConsoleColour; private static DayFile dayfile; - private static readonly List CurrentLogLines = new List(); + private static readonly List CurrentLogLines = []; private static string CurrentLogName; private static int CurrentLogLineNum = 0; - private static readonly List CurrentSolarLogLines = new List(); + private static readonly List CurrentSolarLogLines = []; private static string CurrentSolarLogName; private static int CurrentSolarLogLineNum = 0; @@ -199,7 +199,7 @@ static void Main() } } - currDate = IncrementMeteoDate(dayfile.DayfileRecs[dayfile.DayfileRecs.Count - 1].Date); + currDate = IncrementMeteoDate(dayfile.DayfileRecs[^1].Date); // We need the last total chill hours to increment if there are missing records at the end of the day file // check if total chill hours needs to be reset if (currDate.Month == cumulus.ChillHourSeasonStart && currDate.Day == 1) @@ -208,7 +208,7 @@ static void Main() } else { - TotalChillHours = dayfile.DayfileRecs[dayfile.DayfileRecs.Count - 1].ChillHours; + TotalChillHours = dayfile.DayfileRecs[^1].ChillHours; } // that is the dayfile processed, but what if it had missing records at the end? @@ -389,9 +389,6 @@ private static Dayfilerec GetDayRecFromMonthly(DateTime date) if (dayfile.LineEnding == string.Empty) { Utils.TryDetectNewLine(fileName, out dayfile.LineEnding); - - // determine the dayfile field and date separators - Utils.GetLogFileSeparators(fileName, CultureInfo.CurrentCulture.TextInfo.ListSeparator, out dayfile.FieldSep, out dayfile.DateSep); } @@ -424,7 +421,7 @@ private static Dayfilerec GetDayRecFromMonthly(DateTime date) //var st = new List(Regex.Split(line, CultureInfo.CurrentCulture.TextInfo.ListSeparator)); // Regex is very expensive, let's assume the separator is always a single character - var st = new List(CurrentLogLines[CurrentLogLineNum++].Split(dayfile.FieldSep[0])); + var st = new List(CurrentLogLines[CurrentLogLineNum++].Split(',')); var entrydate = Utils.DdmmyyhhmmStrToDate(st[0], st[1]); if (entrydate < startTimeMinus1) @@ -1009,9 +1006,6 @@ private static Dayfilerec GetSolarDayRecFromMonthly(DateTime date, Dayfilerec re if (dayfile.LineEnding == string.Empty) { Utils.TryDetectNewLine(fileName, out dayfile.LineEnding); - - // determine the dayfile field and date separators - Utils.GetLogFileSeparators(fileName, CultureInfo.CurrentCulture.TextInfo.ListSeparator, out dayfile.FieldSep, out dayfile.DateSep); } try @@ -1049,7 +1043,7 @@ private static Dayfilerec GetSolarDayRecFromMonthly(DateTime date, Dayfilerec re } // Regex is very expensive, let's assume the separator is always a single character - var ut = new List(CurrentSolarLogLines[CurrentSolarLogLineNum].Split(dayfile.FieldSep[0])); + var ut = new List(CurrentSolarLogLines[CurrentSolarLogLineNum].Split(',')); if (ut.Count < 10) { @@ -1313,9 +1307,16 @@ private static void AddMissingData(int idx, DateTime metDate) private static string GetLogFileName(DateTime thedate) { - var datestring = thedate.ToString("MMMyy").Replace(".", ""); + // First determine the date for the log file. + // If we're using 9am roll-over, the date should be 9 hours (10 in summer) + // before 'Now' + var logfiledate = thedate.AddHours(cumulus.GetHourInc(thedate)); + + + var datestring = logfiledate.ToString("yyyyMM"); return location + "data" + Path.DirectorySeparatorChar + datestring + "log.txt"; + } private static void ExtractSolarData(List st, ref Dayfilerec rec, DateTime entrydate) @@ -1438,17 +1439,9 @@ private static void AddLastHoursRainEntry(DateTime ts, double rain, ref Queue 70 ? 1900 : 2000; + return result; } - return new DateTime(Y, M, D); + return DateTime.MinValue; } public static DateTime DdmmyyhhmmStrToDate(string d, string t) { - // Horrible hack, but we have localised separators, but UK sequence, so localised parsing may fail - // Determine separators from the strings, allow for multi-byte! - var datSep = Regex.Match(d, @"[^0-9]+").Value; - var timSep = Regex.Match(t, @"[^0-9]+").Value; - - // Converts a date string in UK order to a DateTime - string[] date = d.Split(new string[] { datSep }, StringSplitOptions.None); - string[] time = t.Split(new string[] { timSep }, StringSplitOptions.None); - - int D = Convert.ToInt32(date[0]); - int M = Convert.ToInt32(date[1]); - int Y = Convert.ToInt32(date[2]); - - // Double check - just in case we get a four digit year! - if (Y < 1900) + if (DateTime.TryParseExact(d + ' ' + t, "dd/MM/yy HH:mm", CultureInfo.InvariantCulture, DateTimeStyles.AssumeLocal, out var result)) { - Y += Y > 70 ? 1900 : 2000; + return result; } - int h = Convert.ToInt32(time[0]); - int m = Convert.ToInt32(time[1]); - - return new DateTime(Y, M, D, h, m, 0); + return DateTime.MinValue; } public static DateTime GetDateTime(DateTime date, string time) { - var timSep = Regex.Match(time, @"[^0-9]+").Value; - - var tim = time.Split(new string[] { timSep }, StringSplitOptions.None); + var tim = time.Split(','); return new DateTime(date.Year, date.Month, date.Day, int.Parse(tim[0]), int.Parse(tim[1]), 0); } @@ -88,57 +60,42 @@ public static double TempCToUser(double value) public static double UserWindToKPH(double wind) // input is in Units.Wind units, convert to km/h { - switch (Program.cumulus.Units.Wind) + return Program.cumulus.Units.Wind switch { // m/s - case 0: - return wind * 3.6; + 0 => wind * 3.6, // mph - case 1: - return wind * 1.609344; + 1 => wind * 1.609344, // kph - case 2: - return wind; + 2 => wind, // knots - case 3: - return wind * 1.852; - default: - return wind; + 3 => wind * 1.852, + _ => wind, }; } public static double UserWindToMS(double value) { - switch (Program.cumulus.Units.Wind) + return Program.cumulus.Units.Wind switch { - case 0: - return value; - case 1: - return value / 2.23693629; - case 2: - return value / 3.6F; - case 3: - return value / 1.94384449; - default: - return 0; + 0 => value, + 1 => value / 2.23693629, + 2 => value / 3.6F, + 3 => value / 1.94384449, + _ => 0, }; } public static double WindMSToUser(double value) { - switch (Program.cumulus.Units.Wind) + return Program.cumulus.Units.Wind switch { - case 0: - return value; - case 1: - return value * 2.23693629; - case 2: - return value * 3.6; - case 3: - return value * 1.94384449; - default: - return 0; - } + 0 => value, + 1 => value * 2.23693629, + 2 => value * 3.6, + 3 => value * 1.94384449, + _ => 0, + }; } public static int CalcAvgBearing(double x, double y) @@ -154,53 +111,30 @@ public static int CalcAvgBearing(double x, double y) public static bool TryDetectNewLine(string path, out string newLine) { - using (var fs = File.OpenRead(path)) - { - char prevChar = '\0'; - - // read the first 1000 characters to try and find a newLine - for (var i = 0; i < 1000; i++) - { - int b; - if ((b = fs.ReadByte()) == -1) - break; + using var fs = File.OpenRead(path); + char prevChar = '\0'; - char curChar = (char)b; + // read the first 1000 characters to try and find a newLine + for (var i = 0; i < 1000; i++) + { + int b; + if ((b = fs.ReadByte()) == -1) + break; - if (curChar == '\n') - { - newLine = prevChar == '\r' ? "\r\n" : "\n"; - return true; - } + char curChar = (char)b; - prevChar = curChar; + if (curChar == '\n') + { + newLine = prevChar == '\r' ? "\r\n" : "\n"; + return true; } - // Returning false means could not determine linefeed convention - newLine = Environment.NewLine; - return false; + prevChar = curChar; } - } - public static void GetLogFileSeparators(string path, string defSep, out string fieldSep, out string dateSep) - { - // we know the dayfile and monthly log files start with - // dd/MM/yy,NN,... - // dd/MM/yy,hh:mm,N.N,.... - // so we just need to find the first separator after the date before a number - using (var sr = new StreamReader(path)) - { - string line = sr.ReadLine(); - var reg = Regex.Match(line, @"\d{2}[^\d]+\d{2}[^\d]+\d{2}([^\d])"); - if (reg.Success) - fieldSep = reg.Groups[1].Value; - else - fieldSep = defSep; - - var fields = line.Split(new string[] { fieldSep }, StringSplitOptions.None); - dateSep = Regex.Match(fields[0], @"[^0-9]+").Value; - } - Program.LogMessage($"File [{path}] found separators: field=[{fieldSep}] date=[{dateSep}]"); + // Returning false means could not determine linefeed convention + newLine = Environment.NewLine; + return false; } } } From e74f00704715ae4dd0391a059c8ed4812295829e Mon Sep 17 00:00:00 2001 From: Mark Crossley Date: Tue, 6 Feb 2024 10:44:03 +0000 Subject: [PATCH 09/12] Code updates & post build task update --- CreateMissing.csproj | 2 +- DayFile.cs | 133 +++++++++++++++++++++---------------------- 2 files changed, 66 insertions(+), 69 deletions(-) diff --git a/CreateMissing.csproj b/CreateMissing.csproj index 42233cc..9e5bb51 100644 --- a/CreateMissing.csproj +++ b/CreateMissing.csproj @@ -14,6 +14,6 @@ DEBUG;TRACE - + \ No newline at end of file diff --git a/DayFile.cs b/DayFile.cs index 7085204..15012b2 100644 --- a/DayFile.cs +++ b/DayFile.cs @@ -37,6 +37,7 @@ public DayFile() public void LoadDayFile() { int addedEntries = 0; + var inv = CultureInfo.InvariantCulture; Program.LogMessage($"LoadDayFile: Attempting to load the day file"); Console.WriteLine("Attempting to load the day file"); @@ -56,67 +57,65 @@ public void LoadDayFile() try { - using (var sr = new StreamReader(dayFileName)) - { - var lastDate = DateTime.MinValue; + using var sr = new StreamReader(dayFileName); + var lastDate = DateTime.MinValue; - do + do + { + try { - try + // process each record in the file + + + linenum++; + string Line = sr.ReadLine(); + var newRec = ParseDayFileRec(Line); + + // sanity check if this date is in sequence + if (newRec.Date < lastDate) { - // process each record in the file - - - linenum++; - string Line = sr.ReadLine(); - var newRec = ParseDayFileRec(Line); - - // sanity check if this date is in sequence - if (newRec.Date < lastDate) - { - Program.LogMessage($"LoadDayFile: Error - Date is out of order at line {linenum} of {dayFileName}, '{newRec.Date.ToString("dd" + DateSep + "MM" + DateSep + "yy")}'"); - Console.WriteLine(); - Program.LogConsole($"Error, date is out of order at line {linenum} of {dayFileName}, '{newRec.Date.ToString("dd" + DateSep + "MM" + DateSep + "yy")}'", ConsoleColor.Red); - errorCount++; - } - - // sanity check if this date has already been added - //var matches = DayfileRecs.Where(p => p.Date == newRec.Date).ToList(); - // (matches.Count > 0) - //Since we now know the order is correct, we can do a simple date compare - if (newRec.Date == lastDate) - { - Program.LogMessage($"LoadDayFile: Error - Duplicate date at line {linenum} of {dayFileName}, '{newRec.Date.ToString("dd" + DateSep + "MM" + DateSep + "yy")}'"); - Console.WriteLine(); - Program.LogConsole($"Error, duplicate date at line {linenum} of {dayFileName}, '{newRec.Date.ToString("dd" + DateSep + "MM" + DateSep + "yy")}'", ConsoleColor.Red); - Environment.Exit(4); - } - - if (errorCount == 0) - { - DayfileRecs.Add(newRec); - } - - lastDate = newRec.Date; - - addedEntries++; + Program.LogMessage($"LoadDayFile: Error - Date is out of order at line {linenum} of {dayFileName}, '{newRec.Date.ToString("dd/MM/yy", inv)}'"); + Console.WriteLine(); + Program.LogConsole($"Error, date is out of order at line {linenum} of {dayFileName}, '{newRec.Date.ToString("dd/MM/yy", inv)}'", ConsoleColor.Red); + errorCount++; } - catch (Exception e) + + // sanity check if this date has already been added + //var matches = DayfileRecs.Where(p => p.Date == newRec.Date).ToList(); + // (matches.Count > 0) + //Since we now know the order is correct, we can do a simple date compare + if (newRec.Date == lastDate) { - Program.LogMessage($"LoadDayFile: Error at line {linenum} of {dayFileName} : {e.Message}"); - Program.LogMessage("Please edit the file to correct the error"); - errorCount++; - if (errorCount >= 20) - { - Program.LogMessage($"LoadDayFile: Too many errors reading {dayFileName} - aborting load of daily data"); - Console.WriteLine(); - Program.LogConsole($"Too many errors reading {dayFileName} - aborting load of daily data", ConsoleColor.Red); - Program.LogConsole("Please see the log file for more details", ConsoleColor.Red); - Environment.Exit(5); - } + Program.LogMessage($"LoadDayFile: Error - Duplicate date at line {linenum} of {dayFileName}, '{newRec.Date.ToString("dd/MM/yy", inv)}'"); + Console.WriteLine(); + Program.LogConsole($"Error, duplicate date at line {linenum} of {dayFileName}, '{newRec.Date.ToString("dd/MM/yy", inv)}'", ConsoleColor.Red); + Environment.Exit(4); + } + + if (errorCount == 0) + { + DayfileRecs.Add(newRec); + } + + lastDate = newRec.Date; + + addedEntries++; + } + catch (Exception e) + { + Program.LogMessage($"LoadDayFile: Error at line {linenum} of {dayFileName} : {e.Message}"); + Program.LogMessage("Please edit the file to correct the error"); + errorCount++; + if (errorCount >= 20) + { + Program.LogMessage($"LoadDayFile: Too many errors reading {dayFileName} - aborting load of daily data"); + Console.WriteLine(); + Program.LogConsole($"Too many errors reading {dayFileName} - aborting load of daily data", ConsoleColor.Red); + Program.LogConsole("Please see the log file for more details", ConsoleColor.Red); + Environment.Exit(5); } - } while (!sr.EndOfStream); - } + } + } while (!sr.EndOfStream); } catch (Exception e) { @@ -157,22 +156,20 @@ public void WriteDayFile() try { - using (FileStream fs = new FileStream(dayFileName, FileMode.Append, FileAccess.Write, FileShare.Read)) - using (StreamWriter file = new StreamWriter(fs)) - { - Program.LogMessage("Dayfile.txt opened for writing"); - - file.NewLine = LineEnding; + using FileStream fs = new FileStream(dayFileName, FileMode.Append, FileAccess.Write, FileShare.Read); + using StreamWriter file = new StreamWriter(fs); + Program.LogMessage("Dayfile.txt opened for writing"); - foreach (var rec in DayfileRecs) - { - var line = RecToCsv(rec); - if (null != line) - file.WriteLine(line); - } + file.NewLine = LineEnding; - file.Close(); + foreach (var rec in DayfileRecs) + { + var line = RecToCsv(rec); + if (null != line) + file.WriteLine(line); } + + file.Close(); } catch (Exception ex) { From 2ea6d6c35fa8f47b279bd6e91dc1f4bcbc17049f Mon Sep 17 00:00:00 2001 From: Mark Crossley Date: Wed, 7 Feb 2024 10:06:45 +0000 Subject: [PATCH 10/12] build bump --- CreateMissing.csproj | 2 +- Program.cs | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/CreateMissing.csproj b/CreateMissing.csproj index 9e5bb51..ba45ecc 100644 --- a/CreateMissing.csproj +++ b/CreateMissing.csproj @@ -3,7 +3,7 @@ Exe $(PackageVersion) $(PackageVersion) - 2.0.0 + 2.0.0.0001 CreateMissing.Program net8.0 Mark Crossley diff --git a/Program.cs b/Program.cs index cbdafc8..0c27491 100644 --- a/Program.cs +++ b/Program.cs @@ -2,10 +2,8 @@ using System; using System.Collections.Generic; using System.Diagnostics; -using System.Globalization; using System.IO; using System.Linq; -using System.Threading; namespace CreateMissing { From 185fbd63f1f887ac05473a0105b37876f8070a1e Mon Sep 17 00:00:00 2001 From: Mark Crossley Date: Mon, 11 Mar 2024 12:30:36 +0000 Subject: [PATCH 11/12] Fix day file parse error --- CreateMissing.csproj | 2 +- DayFile.cs | 126 +++++++++++++++++++++---------------------- Program.cs | 12 ++--- Utils.cs | 6 +-- 4 files changed, 72 insertions(+), 74 deletions(-) diff --git a/CreateMissing.csproj b/CreateMissing.csproj index ba45ecc..207f399 100644 --- a/CreateMissing.csproj +++ b/CreateMissing.csproj @@ -3,7 +3,7 @@ Exe $(PackageVersion) $(PackageVersion) - 2.0.0.0001 + 2.0.0.0002 CreateMissing.Program net8.0 Mark Crossley diff --git a/DayFile.cs b/DayFile.cs index 15012b2..a41e962 100644 --- a/DayFile.cs +++ b/DayFile.cs @@ -81,7 +81,7 @@ public void LoadDayFile() } // sanity check if this date has already been added - //var matches = DayfileRecs.Where(p => p.Date == newRec.Date).ToList(); + //var matches = DayfileRecs.Where(p => p.Date == newRec.Date).ToList() // (matches.Count > 0) //Since we now know the order is correct, we can do a simple date compare if (newRec.Date == lastDate) @@ -249,7 +249,7 @@ private static string RecToCsv(Dayfilerec rec) if (rec.HighGust == -9999) return null; - //strb.Append("0.0" + listsep + "0" + listsep + "00:00" + listsep); + //strb.Append("0.0" + listsep + "0" + listsep + "00:00" + listsep) else { strb.Append(rec.HighGust.ToString(Program.cumulus.WindFormat, inv) + sep); @@ -259,7 +259,7 @@ private static string RecToCsv(Dayfilerec rec) if (rec.LowTemp == 9999) return null; - //strb.Append("0.0" + listsep + "00:00" + listsep); + //strb.Append("0.0" + listsep + "00:00" + listsep) else { strb.Append(rec.LowTemp.ToString(Program.cumulus.TempFormat, inv) + sep); @@ -268,7 +268,7 @@ private static string RecToCsv(Dayfilerec rec) if (rec.HighTemp == -9999) return null; - //strb.Append("0.0" + listsep + "00:00" + listsep); + //strb.Append("0.0" + listsep + "00:00" + listsep) else { strb.Append(rec.HighTemp.ToString(Program.cumulus.TempFormat, inv) + sep); @@ -277,7 +277,7 @@ private static string RecToCsv(Dayfilerec rec) if (rec.LowPress == 9999) return null; - //strb.Append("0.0" + listsep + "00:00" + listsep); + //strb.Append("0.0" + listsep + "00:00" + listsep) else { strb.Append(rec.LowPress.ToString(Program.cumulus.PressFormat, inv) + sep); @@ -286,7 +286,7 @@ private static string RecToCsv(Dayfilerec rec) if (rec.HighPress == -9999) return null; - //strb.Append("0.0" + listsep + "00:00" + listsep); + //strb.Append("0.0" + listsep + "00:00" + listsep) else { strb.Append(rec.HighPress.ToString(Program.cumulus.PressFormat, inv) + sep); @@ -295,7 +295,7 @@ private static string RecToCsv(Dayfilerec rec) if (rec.HighRainRate == -9999) return null; - //strb.Append("0.0" + listsep + "00:00" + listsep); + //strb.Append("0.0" + listsep + "00:00" + listsep) else { strb.Append(rec.HighRainRate.ToString(Program.cumulus.RainFormat, inv) + sep); @@ -304,7 +304,7 @@ private static string RecToCsv(Dayfilerec rec) if (rec.TotalRain == -9999) return null; - //strb.Append("0.0" + listsep); + //strb.Append("0.0" + listsep) else strb.Append(rec.TotalRain.ToString(Program.cumulus.RainFormat, inv) + sep); @@ -615,61 +615,61 @@ private static Dayfilerec ParseDayFileRec(string data) public class Dayfilerec { - public DateTime Date; - public double HighGust; - public int HighGustBearing; - public DateTime HighGustTime; - public double LowTemp; - public DateTime LowTempTime; - public double HighTemp; - public DateTime HighTempTime; - public double LowPress; - public DateTime LowPressTime; - public double HighPress; - public DateTime HighPressTime; - public double HighRainRate; - public DateTime HighRainRateTime; - public double TotalRain; - public double AvgTemp; - public double WindRun; - public double HighAvgWind; - public DateTime HighAvgWindTime; - public int LowHumidity; - public DateTime LowHumidityTime; - public int HighHumidity; - public DateTime HighHumidityTime; - public double ET; - public double SunShineHours; - public double HighHeatIndex; - public DateTime HighHeatIndexTime; - public double HighAppTemp; - public DateTime HighAppTempTime; - public double LowAppTemp; - public DateTime LowAppTempTime; - public double HighHourlyRain; - public DateTime HighHourlyRainTime; - public double LowWindChill; - public DateTime LowWindChillTime; - public double HighDewPoint; - public DateTime HighDewPointTime; - public double LowDewPoint; - public DateTime LowDewPointTime; - public int DominantWindBearing; - public double HeatingDegreeDays; - public double CoolingDegreeDays; - public int HighSolar; - public DateTime HighSolarTime; - public double HighUv; - public DateTime HighUvTime; - public double HighFeelsLike; - public DateTime HighFeelsLikeTime; - public double LowFeelsLike; - public DateTime LowFeelsLikeTime; - public double HighHumidex; - public DateTime HighHumidexTime; - public double ChillHours; - public double HighRain24h; - public DateTime HighRain24hTime; + public DateTime Date { get; set; } + public double HighGust { get; set; } + public int HighGustBearing { get; set; } + public DateTime HighGustTime { get; set; } + public double LowTemp { get; set; } + public DateTime LowTempTime { get; set; } + public double HighTemp { get; set; } + public DateTime HighTempTime { get; set; } + public double LowPress { get; set; } + public DateTime LowPressTime { get; set; } + public double HighPress { get; set; } + public DateTime HighPressTime { get; set; } + public double HighRainRate { get; set; } + public DateTime HighRainRateTime { get; set; } + public double TotalRain { get; set; } + public double AvgTemp { get; set; } + public double WindRun { get; set; } + public double HighAvgWind { get; set; } + public DateTime HighAvgWindTime { get; set; } + public int LowHumidity { get; set; } + public DateTime LowHumidityTime { get; set; } + public int HighHumidity { get; set; } + public DateTime HighHumidityTime { get; set; } + public double ET { get; set; } + public double SunShineHours { get; set; } + public double HighHeatIndex { get; set; } + public DateTime HighHeatIndexTime { get; set; } + public double HighAppTemp { get; set; } + public DateTime HighAppTempTime { get; set; } + public double LowAppTemp { get; set; } + public DateTime LowAppTempTime { get; set; } + public double HighHourlyRain { get; set; } + public DateTime HighHourlyRainTime { get; set; } + public double LowWindChill { get; set; } + public DateTime LowWindChillTime { get; set; } + public double HighDewPoint { get; set; } + public DateTime HighDewPointTime { get; set; } + public double LowDewPoint { get; set; } + public DateTime LowDewPointTime { get; set; } + public int DominantWindBearing { get; set; } + public double HeatingDegreeDays { get; set; } + public double CoolingDegreeDays { get; set; } + public int HighSolar { get; set; } + public DateTime HighSolarTime { get; set; } + public double HighUv { get; set; } + public DateTime HighUvTime { get; set; } + public double HighFeelsLike { get; set; } + public DateTime HighFeelsLikeTime { get; set; } + public double LowFeelsLike { get; set; } + public DateTime LowFeelsLikeTime { get; set; } + public double HighHumidex { get; set; } + public DateTime HighHumidexTime { get; set; } + public double ChillHours { get; set; } + public double HighRain24h { get; set; } + public DateTime HighRain24hTime { get; set; } public Dayfilerec() { diff --git a/Program.cs b/Program.cs index 0c27491..e1bdd4f 100644 --- a/Program.cs +++ b/Program.cs @@ -7,7 +7,7 @@ namespace CreateMissing { - class Program + static class Program { public static Cumulus cumulus; public static string location; @@ -33,7 +33,7 @@ class Program static void Main() { #if DEBUG - //Thread.CurrentThread.CurrentCulture = new CultureInfo("nl-NL"); + //Thread.CurrentThread.CurrentCulture = new CultureInfo("nl-NL") #endif TextWriterTraceListener myTextListener = new TextWriterTraceListener($"MXdiags{Path.DirectorySeparatorChar}CreateMissing-{DateTime.Now:yyyyMMdd-HHmmss}.txt", "CMlog"); Trace.Listeners.Add(myTextListener); @@ -417,7 +417,7 @@ private static Dayfilerec GetDayRecFromMonthly(DateTime date) continue; } - //var st = new List(Regex.Split(line, CultureInfo.CurrentCulture.TextInfo.ListSeparator)); + //var st = new List(Regex.Split(line, CultureInfo.CurrentCulture.TextInfo.ListSeparator)) // Regex is very expensive, let's assume the separator is always a single character var st = new List(CurrentLogLines[CurrentLogLineNum++].Split(',')); var entrydate = Utils.DdmmyyhhmmStrToDate(st[0], st[1]); @@ -827,7 +827,7 @@ private static Dayfilerec GetDayRecFromMonthly(DateTime date) // after that build the total was reset to zero in the 00:00 entry // messy! // no final rainfall entry after this date (approx). The best we can do is add in the increase in rain counter during this preiod - var rolloverRain = double.Parse(st[9]); // 9 - rain so far today + //var rolloverRain = double.Parse(st[9]); // 9 - rain so far today var rolloverRaincounter = double.Parse(st[11]); // 11 - rain counter rec.TotalRain += (rolloverRaincounter - lastentrycounter) * cumulus.CalibRainMult; @@ -922,8 +922,6 @@ private static Dayfilerec GetDayRecFromMonthly(DateTime date) return rec; } - - //return null; } if (fileDate > date) { @@ -1371,7 +1369,7 @@ private static DateTime SetStartTime(DateTime thedate) TimeZoneInfo tz = TimeZoneInfo.Local; // Date without time - DateTime rawDate = new DateTime(thedate.Year, thedate.Month, thedate.Day); + DateTime rawDate = new DateTime(thedate.Year, thedate.Month, thedate.Day, 0, 0, 0, DateTimeKind.Local); if (cumulus.Use10amInSummer && tz.IsDaylightSavingTime(thedate)) { diff --git a/Utils.cs b/Utils.cs index de6f5fa..361cdc4 100644 --- a/Utils.cs +++ b/Utils.cs @@ -6,7 +6,7 @@ namespace CreateMissing { - class Utils + static class Utils { public static DateTime DdmmyyStrToDate(string d) { @@ -28,8 +28,8 @@ public static DateTime DdmmyyhhmmStrToDate(string d, string t) public static DateTime GetDateTime(DateTime date, string time) { - var tim = time.Split(','); - return new DateTime(date.Year, date.Month, date.Day, int.Parse(tim[0]), int.Parse(tim[1]), 0); + var tim = time.Split(':'); + return new DateTime(date.Year, date.Month, date.Day, int.Parse(tim[0]), int.Parse(tim[1]), 0, DateTimeKind.Local); } public static double UserTempToC(double value) From 934b8e961eb08c35089771edc6f93560af221dfa Mon Sep 17 00:00:00 2001 From: Mark Crossley Date: Thu, 20 Jun 2024 20:32:34 +0100 Subject: [PATCH 12/12] Fix locale issues reading log files --- CreateMissing.csproj | 2 +- DayFile.cs | 24 +++++++++++++++++++++++ Program.cs | 46 ++++++++++++++++++++++++-------------------- 3 files changed, 50 insertions(+), 22 deletions(-) diff --git a/CreateMissing.csproj b/CreateMissing.csproj index 207f399..840daf8 100644 --- a/CreateMissing.csproj +++ b/CreateMissing.csproj @@ -3,7 +3,7 @@ Exe $(PackageVersion) $(PackageVersion) - 2.0.0.0002 + 2.0.1.0003 CreateMissing.Program net8.0 Mark Crossley diff --git a/DayFile.cs b/DayFile.cs index a41e962..114bdc4 100644 --- a/DayFile.cs +++ b/DayFile.cs @@ -248,8 +248,11 @@ private static string RecToCsv(Dayfilerec rec) strb.Append(datestring + sep); if (rec.HighGust == -9999) + { + Program.LogMessage("Mandatory value High Gust missing, skipping this day"); return null; //strb.Append("0.0" + listsep + "0" + listsep + "00:00" + listsep) + } else { strb.Append(rec.HighGust.ToString(Program.cumulus.WindFormat, inv) + sep); @@ -258,8 +261,11 @@ private static string RecToCsv(Dayfilerec rec) } if (rec.LowTemp == 9999) + { + Program.LogMessage("Mandatory value Low Temp missing, skipping this day"); return null; //strb.Append("0.0" + listsep + "00:00" + listsep) + } else { strb.Append(rec.LowTemp.ToString(Program.cumulus.TempFormat, inv) + sep); @@ -267,8 +273,11 @@ private static string RecToCsv(Dayfilerec rec) } if (rec.HighTemp == -9999) + { + Program.LogMessage("Mandatory value High Temp missing, skipping this day"); return null; //strb.Append("0.0" + listsep + "00:00" + listsep) + } else { strb.Append(rec.HighTemp.ToString(Program.cumulus.TempFormat, inv) + sep); @@ -276,8 +285,11 @@ private static string RecToCsv(Dayfilerec rec) } if (rec.LowPress == 9999) + { + Program.LogMessage("Mandatory value Low Press missing, skipping this day"); return null; //strb.Append("0.0" + listsep + "00:00" + listsep) + } else { strb.Append(rec.LowPress.ToString(Program.cumulus.PressFormat, inv) + sep); @@ -285,8 +297,11 @@ private static string RecToCsv(Dayfilerec rec) } if (rec.HighPress == -9999) + { + Program.LogMessage("Mandatory value High Press missing, skipping this day"); return null; //strb.Append("0.0" + listsep + "00:00" + listsep) + } else { strb.Append(rec.HighPress.ToString(Program.cumulus.PressFormat, inv) + sep); @@ -294,8 +309,11 @@ private static string RecToCsv(Dayfilerec rec) } if (rec.HighRainRate == -9999) + { + Program.LogMessage("Mandatory value High Rain Rate missing, skipping this day"); return null; //strb.Append("0.0" + listsep + "00:00" + listsep) + } else { strb.Append(rec.HighRainRate.ToString(Program.cumulus.RainFormat, inv) + sep); @@ -303,13 +321,19 @@ private static string RecToCsv(Dayfilerec rec) } if (rec.TotalRain == -9999) + { + Program.LogMessage("Mandatory value Total Rain missing, skipping this day"); return null; //strb.Append("0.0" + listsep) + } else strb.Append(rec.TotalRain.ToString(Program.cumulus.RainFormat, inv) + sep); if (rec.AvgTemp == -9999) + { + Program.LogMessage("Mandatory value Avg Temp missing, skipping this day"); strb.Append(sep); + } else strb.Append(rec.AvgTemp.ToString(Program.cumulus.TempFormat, inv) + sep); diff --git a/Program.cs b/Program.cs index e1bdd4f..377879e 100644 --- a/Program.cs +++ b/Program.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Generic; using System.Diagnostics; +using System.Globalization; using System.IO; using System.Linq; @@ -33,7 +34,7 @@ static class Program static void Main() { #if DEBUG - //Thread.CurrentThread.CurrentCulture = new CultureInfo("nl-NL") + //System.Threading.Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo("sl-SL") #endif TextWriterTraceListener myTextListener = new TextWriterTraceListener($"MXdiags{Path.DirectorySeparatorChar}CreateMissing-{DateTime.Now:yyyyMMdd-HHmmss}.txt", "CMlog"); Trace.Listeners.Add(myTextListener); @@ -83,6 +84,7 @@ static void Main() Console.WriteLine("Exiting..."); Environment.Exit(1); } + Console.WriteLine(); // Sanity check #2 @@ -313,6 +315,8 @@ private static Dayfilerec GetDayRecFromMonthly(DateTime date) ChillHours = 0 }; + var inv = CultureInfo.InvariantCulture; + var started = false; var finished = false; var recCount = 0; @@ -435,8 +439,8 @@ private static Dayfilerec GetDayRecFromMonthly(DateTime date) // after that build the total was reset to zero in the entry // messy! // no final rainfall entry after this date (approx). The best we can do is add in the increase in rain counter during this preiod - var rain = double.Parse(st[9]); // 9 - var raincounter = double.Parse(st[11]); // 11 + var rain = double.Parse(st[9], inv); // 9 + var raincounter = double.Parse(st[11], inv); // 11 // we need to initalise the rain counter on the first record if (rain1hLog.Count == 0) @@ -482,16 +486,16 @@ private static Dayfilerec GetDayRecFromMonthly(DateTime date) if (entrydate >= startTime && entrydate <= endTime) { recCount++; - var outsidetemp = double.Parse(st[++idx]); // 2 - var hum = int.Parse(st[++idx]); // 3 - var dewpoint = double.Parse(st[++idx]); // 4 - var speed = double.Parse(st[++idx]); // 5 - var gust = double.Parse(st[++idx]); // 6 - var avgbearing = int.Parse(st[++idx]); // 7 - var rainrate = double.Parse(st[++idx]); // 8 - var raintoday = double.Parse(st[++idx]); // 9 - var pressure = double.Parse(st[++idx]); // 10 - var raincounter = double.Parse(st[++idx]); // 11 + var outsidetemp = double.Parse(st[++idx], inv); // 2 + var hum = int.Parse(st[++idx]); // 3 + var dewpoint = double.Parse(st[++idx], inv); // 4 + var speed = double.Parse(st[++idx], inv); // 5 + var gust = double.Parse(st[++idx], inv); // 6 + var avgbearing = int.Parse(st[++idx], inv); // 7 + var rainrate = double.Parse(st[++idx], inv); // 8 + var raintoday = double.Parse(st[++idx], inv); // 9 + var pressure = double.Parse(st[++idx], inv); // 10 + var raincounter = double.Parse(st[++idx], inv); // 11 if (!started) { @@ -506,12 +510,12 @@ private static Dayfilerec GetDayRecFromMonthly(DateTime date) { // current gust idx = 14; - if (st.Count > idx && double.TryParse(st[idx], out valDbl) && valDbl > rec.HighGust) + if (st.Count > idx && double.TryParse(st[idx], inv, out valDbl) && valDbl > rec.HighGust) { rec.HighGust = valDbl; rec.HighGustTime = entrydate; idx = 24; - if (st.Count > idx && int.TryParse(st[idx], out valInt)) + if (st.Count > idx && int.TryParse(st[idx], inv, out valInt)) { rec.HighGustBearing = valInt; } @@ -522,7 +526,7 @@ private static Dayfilerec GetDayRecFromMonthly(DateTime date) } // low chill idx = 15; - if (st.Count > idx && double.TryParse(st[idx], out valDbl) && valDbl < rec.LowWindChill) + if (st.Count > idx && double.TryParse(st[idx], inv, out valDbl) && valDbl < rec.LowWindChill) { rec.LowWindChill = valDbl; rec.LowWindChillTime = entrydate; @@ -539,7 +543,7 @@ private static Dayfilerec GetDayRecFromMonthly(DateTime date) } // hi heat idx = 16; - if (st.Count > idx && double.TryParse(st[idx], out valDbl) && valDbl > rec.HighHeatIndex) + if (st.Count > idx && double.TryParse(st[idx], inv, out valDbl) && valDbl > rec.HighHeatIndex) { rec.HighHeatIndex = valDbl; rec.HighHeatIndexTime = entrydate; @@ -556,7 +560,7 @@ private static Dayfilerec GetDayRecFromMonthly(DateTime date) } // hi/low appt idx = 21; - if (st.Count > idx && double.TryParse(st[idx], out valDbl)) + if (st.Count > idx && double.TryParse(st[idx], inv, out valDbl)) { if (valDbl > rec.HighAppTemp) { @@ -588,7 +592,7 @@ private static Dayfilerec GetDayRecFromMonthly(DateTime date) // hi/low feels like idx = 27; - if (st.Count > idx && double.TryParse(st[idx], out valDbl)) + if (st.Count > idx && double.TryParse(st[idx], inv, out valDbl)) { if (valDbl > rec.HighFeelsLike) { @@ -619,7 +623,7 @@ private static Dayfilerec GetDayRecFromMonthly(DateTime date) // hi humidex idx = 28; - if (st.Count > idx && double.TryParse(st[idx], out valDbl)) + if (st.Count > idx && double.TryParse(st[idx], inv, out valDbl)) { if (valDbl > rec.HighHumidex) { @@ -828,7 +832,7 @@ private static Dayfilerec GetDayRecFromMonthly(DateTime date) // messy! // no final rainfall entry after this date (approx). The best we can do is add in the increase in rain counter during this preiod //var rolloverRain = double.Parse(st[9]); // 9 - rain so far today - var rolloverRaincounter = double.Parse(st[11]); // 11 - rain counter + var rolloverRaincounter = double.Parse(st[11], inv); // 11 - rain counter rec.TotalRain += (rolloverRaincounter - lastentrycounter) * cumulus.CalibRainMult;