diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..a37f7d1 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,78 @@ +[*.cs] +csharp_indent_block_contents = true +csharp_indent_braces = false +csharp_indent_case_contents = true +csharp_indent_labels = one_less_than_current +csharp_indent_switch_labels = true + +csharp_new_line_before_catch = true +csharp_new_line_before_else = true +csharp_new_line_before_finally = true +csharp_new_line_before_members_in_anonymous_types = true +csharp_new_line_before_members_in_object_initializers = true +csharp_new_line_before_open_brace = all +# csharp_new_line_between_query_expression_clauses = false + +# csharp_prefer_braces = true:none +# csharp_prefer_simple_default_expression = true:none +csharp_preserve_single_line_blocks = true +# csharp_preserve_single_line_statements = false +# csharp_space_after_cast = false + +csharp_space_after_colon_in_inheritance_clause = true +csharp_space_after_comma = true +csharp_space_after_dot = false +csharp_space_after_keywords_in_control_flow_statements = true +csharp_space_after_semicolon_in_for_statement = true +csharp_space_around_binary_operators = before_and_after +csharp_space_around_declaration_statements = do_not_ignore +csharp_space_before_colon_in_inheritance_clause = true +csharp_space_before_comma = false +csharp_space_before_dot = false +csharp_space_before_open_square_brackets = false +csharp_space_before_semicolon_in_for_statement = false +csharp_space_between_empty_square_brackets = false +csharp_space_between_method_call_empty_parameter_list_parentheses = false +csharp_space_between_method_call_name_and_opening_parenthesis = false +csharp_space_between_method_call_parameter_list_parentheses = false +csharp_space_between_method_declaration_empty_parameter_list_parentheses = false +csharp_space_between_method_declaration_name_and_open_parenthesis = false +csharp_space_between_method_declaration_parameter_list_parentheses = false +csharp_space_between_parentheses = none +csharp_space_between_square_brackets = false + +csharp_style_conditional_delegate_call = false:none +# csharp_style_expression_bodied_accessors = false:error +# csharp_style_expression_bodied_constructors = false:error +csharp_style_expression_bodied_indexers = false:warning +csharp_style_expression_bodied_methods = false:warning +# csharp_style_expression_bodied_operators = false:error +csharp_style_expression_bodied_properties = false:warning +csharp_style_inlined_variable_declaration = false:warning +csharp_style_pattern_matching_over_as_with_null_check = false:none +csharp_style_pattern_matching_over_is_with_cast_check = false:none +csharp_style_throw_expression = false:none +csharp_style_var_elsewhere = true:none +csharp_style_var_for_built_in_types = true:none +csharp_style_var_for_locals = true:suggestion +csharp_style_var_when_type_is_apparent = true:none + +dotnet_sort_system_directives_first = true +dotnet_style_coalesce_expression = false:warning +dotnet_style_collection_initializer = true:suggestion +# dotnet_style_explicit_tuple_names = true:error +dotnet_style_null_propagation = false:warning +dotnet_style_object_initializer = true:suggestion +dotnet_style_predefined_type_for_locals_parameters_members = true:none +dotnet_style_predefined_type_for_member_access = true:none +dotnet_style_qualification_for_event = false:suggestion +dotnet_style_qualification_for_field = false:suggestion +dotnet_style_qualification_for_method = false:suggestion +dotnet_style_qualification_for_property = false:suggestion + +end_of_line = lf +indent_size = 4 +indent_style = tab +insert_final_newline = true +tab_width = 4 + diff --git a/CreateMissing.csproj b/CreateMissing.csproj index 9587986..ae676b5 100644 --- a/CreateMissing.csproj +++ b/CreateMissing.csproj @@ -3,9 +3,9 @@ Exe v4.5.2 - 1.0.2.0 - 1.0.2.0 - 1.0.2 + 1.1.0.0 + 1.1.0.0 + 1.1.0 CreateMissing.Program net452 Mark Crossley diff --git a/CreateMissing.sln b/CreateMissing.sln index d7106ed..38824bb 100644 --- a/CreateMissing.sln +++ b/CreateMissing.sln @@ -5,6 +5,11 @@ VisualStudioVersion = 16.0.31019.35 MinimumVisualStudioVersion = 10.0.40219.1 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CreateMissing", "CreateMissing.csproj", "{FE1382C9-ACC6-4DF3-B894-3AD411FAF076}" EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{19207AAE-C219-46BA-8521-7C0C6AD0765E}" + ProjectSection(SolutionItems) = preProject + .editorconfig = .editorconfig + EndProjectSection +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU diff --git a/Cumulus.cs b/Cumulus.cs index b830435..bafb4b7 100644 --- a/Cumulus.cs +++ b/Cumulus.cs @@ -25,6 +25,9 @@ class Cumulus public double NOAAheatingthreshold; public double NOAAcoolingthreshold; + public int ChillHourSeasonStart; + public double ChillHourThreshold; + private StationOptions StationOptions = new StationOptions(); internal StationUnits Units = new StationUnits(); private int[] WindDPlaceDefaults = { 1, 0, 0, 0 }; // m/s, mph, km/h, knots @@ -126,7 +129,14 @@ private void ReadIniFile() NOAAcoolingthreshold = Units.Temp == 0 ? 18.3 : 65; } - + ChillHourSeasonStart = ini.GetValue("Station", "ChillHourSeasonStart", 10); + if (ChillHourSeasonStart < 1 || ChillHourSeasonStart > 12) + ChillHourSeasonStart = 1; + ChillHourThreshold = ini.GetValue("Station", "ChillHourThreshold", -999.0); + if (ChillHourThreshold < -998) + { + ChillHourThreshold = Units.Temp == 0 ? 7 : 45; + } } } diff --git a/DayFile.cs b/DayFile.cs index a23b27e..d9763a6 100644 --- a/DayFile.cs +++ b/DayFile.cs @@ -14,6 +14,7 @@ class DayFile { public List DayfileRecs = new List(); + public string LineEnding = string.Empty; private string dayFileName = "data" + Path.DirectorySeparatorChar + "dayfile.txt"; @@ -44,6 +45,12 @@ public void LoadDayFile() int linenum = 0; int errorCount = 0; + // determine dayfile line ending + if (Utils.TryDetectNewLine(dayFileName, out string lineend)) + { + LineEnding = lineend; + } + // Clear the existing list DayfileRecs.Clear(); @@ -110,16 +117,13 @@ public void WriteDayFile() { Program.LogMessage("Dayfile.txt opened for writing"); + file.NewLine = LineEnding; + foreach (var rec in DayfileRecs) { - if (rec.HasMissingData()) - { - Program.LogMessage($"Skipping day: {rec.Date.ToString("dd/MM/yy")} - missing data"); - } - else - { - file.WriteLine(RecToCsv(rec)); - } + var line = RecToCsv(rec); + if (null != line) + file.WriteLine(line); } file.Close(); @@ -197,60 +201,205 @@ private string RecToCsv(Dayfilerec rec) // NB this string is just for logging, the dayfile update code is further down var strb = new StringBuilder(300); strb.Append(datestring + listsep); - strb.Append(rec.HighGust.ToString(Program.cumulus.WindFormat) + listsep); - strb.Append(rec.HighGustBearing + listsep); - strb.Append(rec.HighGustTime.ToString("HH:mm") + listsep); - strb.Append(rec.LowTemp.ToString(Program.cumulus.TempFormat) + listsep); - strb.Append(rec.LowTempTime.ToString("HH:mm") + listsep); - strb.Append(rec.HighTemp.ToString(Program.cumulus.TempFormat) + listsep); - strb.Append(rec.HighTempTime.ToString("HH:mm") + listsep); - strb.Append(rec.LowPress.ToString(Program.cumulus.PressFormat) + listsep); - strb.Append(rec.LowPressTime.ToString("HH:mm") + listsep); - strb.Append(rec.HighPress.ToString(Program.cumulus.PressFormat) + listsep); - strb.Append(rec.HighPressTime.ToString("HH:mm") + listsep); - strb.Append(rec.HighRainRate.ToString(Program.cumulus.RainFormat) + listsep); - strb.Append(rec.HighRainRateTime.ToString("HH:mm") + listsep); + + 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) + listsep); + strb.Append(rec.HighGustBearing + listsep); + strb.Append(rec.HighGustTime.ToString("HH:mm") + listsep); + } + + if (rec.LowTemp == 9999) + return null; + //strb.Append("0.0" + listsep + "00:00" + listsep); + else + { + strb.Append(rec.LowTemp.ToString(Program.cumulus.TempFormat) + listsep); + strb.Append(rec.LowTempTime.ToString("HH:mm") + listsep); + } + + if (rec.HighTemp == -9999) + return null; + //strb.Append("0.0" + listsep + "00:00" + listsep); + else + { + strb.Append(rec.HighTemp.ToString(Program.cumulus.TempFormat) + listsep); + strb.Append(rec.HighTempTime.ToString("HH:mm") + listsep); + } + + if (rec.LowPress == 9999) + return null; + //strb.Append("0.0" + listsep + "00:00" + listsep); + else + { + strb.Append(rec.LowPress.ToString(Program.cumulus.PressFormat) + listsep); + strb.Append(rec.LowPressTime.ToString("HH:mm") + listsep); + } + + if (rec.HighPress == -9999) + return null; + //strb.Append("0.0" + listsep + "00:00" + listsep); + else + { + strb.Append(rec.HighPress.ToString(Program.cumulus.PressFormat) + listsep); + strb.Append(rec.HighPressTime.ToString("HH:mm") + listsep); + } + + if (rec.HighRainRate == -9999) + return null; + //strb.Append("0.0" + listsep + "00:00" + listsep); + else + { + strb.Append(rec.HighRainRate.ToString(Program.cumulus.RainFormat) + listsep); + strb.Append(rec.HighRainRateTime.ToString("HH:mm") + listsep); + } + if (rec.TotalRain == -9999) - strb.Append("0.0" + listsep); + return null; + //strb.Append("0.0" + listsep); else strb.Append(rec.TotalRain.ToString(Program.cumulus.RainFormat) + listsep); - strb.Append(rec.AvgTemp.ToString(Program.cumulus.TempFormat) + listsep); + + if (rec.AvgTemp == -9999) + strb.Append(listsep); + else + strb.Append(rec.AvgTemp.ToString(Program.cumulus.TempFormat) + listsep); + + strb.Append(rec.WindRun.ToString("F1") + listsep); - strb.Append(rec.HighAvgWind.ToString(Program.cumulus.WindAvgFormat) + listsep); - strb.Append(rec.HighAvgWindTime.ToString("HH:mm") + listsep); - strb.Append(rec.LowHumidity + listsep); - strb.Append(rec.LowHumidityTime.ToString("HH:mm") + listsep); - strb.Append(rec.HighHumidity + listsep); - strb.Append(rec.HighHumidityTime.ToString("HH:mm") + listsep); + + if (rec.HighAvgWind == -9999) + strb.Append(listsep + listsep); + else + { + strb.Append(rec.HighAvgWind.ToString(Program.cumulus.WindAvgFormat) + listsep); + strb.Append(rec.HighAvgWindTime.ToString("HH:mm") + listsep); + } + + if (rec.LowHumidity == 9999) + strb.Append(listsep + listsep); + else + { + strb.Append(rec.LowHumidity + listsep); + strb.Append(rec.LowHumidityTime.ToString("HH:mm") + listsep); + } + + if (rec.HighHumidity == -9999) + strb.Append(listsep + listsep); + else + { + strb.Append(rec.HighHumidity + listsep); + strb.Append(rec.HighHumidityTime.ToString("HH:mm") + listsep); + } + strb.Append(rec.ET.ToString(Program.cumulus.ETFormat) + listsep); strb.Append(rec.SunShineHours.ToString(Program.cumulus.SunFormat) + listsep); - strb.Append(rec.HighHeatIndex.ToString(Program.cumulus.TempFormat) + listsep); - strb.Append(rec.HighHeatIndexTime.ToString("HH:mm") + listsep); - strb.Append(rec.HighAppTemp.ToString(Program.cumulus.TempFormat) + listsep); - strb.Append(rec.HighAppTempTime.ToString("HH:mm") + listsep); - strb.Append(rec.LowAppTemp.ToString(Program.cumulus.TempFormat) + listsep); - strb.Append(rec.LowAppTempTime.ToString("HH:mm") + listsep); - strb.Append(rec.HighHourlyRain.ToString(Program.cumulus.RainFormat) + listsep); - strb.Append(rec.HighHourlyRainTime.ToString("HH:mm") + listsep); - strb.Append(rec.LowWindChill.ToString(Program.cumulus.TempFormat) + listsep); - strb.Append(rec.LowWindChillTime.ToString("HH:mm") + listsep); - strb.Append(rec.HighDewPoint.ToString(Program.cumulus.TempFormat) + listsep); - strb.Append(rec.HighDewPointTime.ToString("HH:mm") + listsep); - strb.Append(rec.LowDewPoint.ToString(Program.cumulus.TempFormat) + listsep); - strb.Append(rec.LowDewPointTime.ToString("HH:mm") + listsep); - strb.Append(rec.DominantWindBearing + listsep); - strb.Append(rec.HeatingDegreeDays.ToString("F1") + listsep); - strb.Append(rec.CoolingDegreeDays.ToString("F1") + listsep); + + if (rec.HighHeatIndex == -9999) + strb.Append(listsep + listsep); + else + { + strb.Append(rec.HighHeatIndex.ToString(Program.cumulus.TempFormat) + listsep); + strb.Append(rec.HighHeatIndexTime.ToString("HH:mm") + listsep); + } + + if (rec.HighAppTemp == -9999) + strb.Append(listsep + listsep); + else + { + strb.Append(rec.HighAppTemp.ToString(Program.cumulus.TempFormat) + listsep); + strb.Append(rec.HighAppTempTime.ToString("HH:mm") + listsep); + } + + if (rec.LowAppTemp == 9999) + strb.Append(listsep + listsep); + else + { + strb.Append(rec.LowAppTemp.ToString(Program.cumulus.TempFormat) + listsep); + strb.Append(rec.LowAppTempTime.ToString("HH:mm") + listsep); + } + + if (rec.HighHourlyRain == -9999) + strb.Append(listsep + listsep); + else + { + strb.Append(rec.HighHourlyRain.ToString(Program.cumulus.RainFormat) + listsep); + strb.Append(rec.HighHourlyRainTime.ToString("HH:mm") + listsep); + } + + if (rec.LowWindChill == 9999) + strb.Append(listsep + listsep); + else + { + strb.Append(rec.LowWindChill.ToString(Program.cumulus.TempFormat) + listsep); + strb.Append(rec.LowWindChillTime.ToString("HH:mm") + listsep); + } + + if (rec.HighDewPoint == -9999) + strb.Append(listsep + listsep); + else + { + strb.Append(rec.HighDewPoint.ToString(Program.cumulus.TempFormat) + listsep); + strb.Append(rec.HighDewPointTime.ToString("HH:mm") + listsep); + } + + if (rec.LowDewPoint == -9999) + strb.Append(listsep + listsep); + else + { + strb.Append(rec.LowDewPoint.ToString(Program.cumulus.TempFormat) + listsep); + strb.Append(rec.LowDewPointTime.ToString("HH:mm") + listsep); + } + + if (rec.DominantWindBearing == 9999) + strb.Append(listsep); + else + strb.Append(rec.DominantWindBearing + listsep); + + if (rec.HeatingDegreeDays == -9999) + strb.Append(listsep); + else + strb.Append(rec.HeatingDegreeDays.ToString("F1") + listsep); + + if (rec.CoolingDegreeDays == -9999) + strb.Append(listsep); + else + strb.Append(rec.CoolingDegreeDays.ToString("F1") + listsep); + strb.Append(rec.HighSolar + listsep); strb.Append(rec.HighSolarTime.ToString("HH:mm") + listsep); strb.Append(rec.HighUv.ToString(Program.cumulus.UVFormat) + listsep); strb.Append(rec.HighUvTime.ToString("HH:mm") + listsep); - strb.Append(rec.HighFeelsLike.ToString(Program.cumulus.TempFormat) + listsep); - strb.Append(rec.HighFeelsLikeTime.ToString("HH:mm") + listsep); - strb.Append(rec.LowFeelsLike.ToString(Program.cumulus.TempFormat) + listsep); - strb.Append(rec.LowFeelsLikeTime.ToString("HH:mm") + listsep); - strb.Append(rec.HighHumidex.ToString(Program.cumulus.TempFormat) + listsep); - strb.Append(rec.HighHumidexTime.ToString("HH:mm")); + + if (rec.HighFeelsLike == -9999) + strb.Append(listsep + listsep); + else + { + strb.Append(rec.HighFeelsLike.ToString(Program.cumulus.TempFormat) + listsep); + strb.Append(rec.HighFeelsLikeTime.ToString("HH:mm") + listsep); + } + + if (rec.LowFeelsLike == 9999) + strb.Append(listsep + listsep); + else + { + strb.Append(rec.LowFeelsLike.ToString(Program.cumulus.TempFormat) + listsep); + strb.Append(rec.LowFeelsLikeTime.ToString("HH:mm") + listsep); + } + + if (rec.HighHumidex == -9999) + strb.Append(listsep + listsep); + else + { + strb.Append(rec.HighHumidex.ToString(Program.cumulus.TempFormat) + listsep); + strb.Append(rec.HighHumidexTime.ToString("HH:mm") + listsep); + } + + if (rec.ChillHours != -9999) + strb.Append(rec.ChillHours.ToString("F1")); Program.LogMessage("Dayfile.txt Added: " + datestring); @@ -391,6 +540,9 @@ private Dayfilerec ParseDayFileRec(string data) if (st.Count > idx++ && st[51].Length == 5) rec.HighHumidexTime = GetDateTime(rec.Date, st[51]); + + if (st.Count > idx++ && double.TryParse(st[52], out varDbl)) + rec.ChillHours = varDbl; } catch (Exception ex) { @@ -506,6 +658,7 @@ public class Dayfilerec public DateTime LowFeelsLikeTime; public double HighHumidex; public DateTime HighHumidexTime; + public double ChillHours; public Dayfilerec() { @@ -539,6 +692,7 @@ public Dayfilerec() HighFeelsLike = -9999; LowFeelsLike = 9999; HighHumidex = -9999; + ChillHours = -9999; } public bool HasMissingData() @@ -547,7 +701,7 @@ public bool HasMissingData() DominantWindBearing == 9999 || LowDewPoint == 9999 || HighDewPoint == -9999 || LowWindChill == 9999 || HighHourlyRain == -9999 || LowAppTemp == 9999 || HighAppTemp == -9999 || HighHeatIndex == -9999 || HighHumidity == -9999 || LowHumidity == 9999 || HighAvgWind == -9999 || AvgTemp == -9999 || HighRainRate == -9999 || LowPress == 9999 || HighPress == -9999 || - HighTemp == -9999 || LowTemp == 9999 || HighGust == -9999 + HighTemp == -9999 || LowTemp == 9999 || HighGust == -9999 || ChillHours == -9999 ) { return true; diff --git a/Program.cs b/Program.cs index 6622a84..c258e6e 100644 --- a/Program.cs +++ b/Program.cs @@ -20,6 +20,8 @@ class Program private static int RecsNoData = 0; private static int RecsOK = 0; + private static double TotalChillHours; + static void Main() { @@ -86,6 +88,22 @@ static void Main() // check if the day record exists in the day file? if (dayfile.DayfileRecs[i].Date > currDate) { + // Extract the Total Chill Hours from the last record we have to continue incrementing it + // First check if total chill hours needs to be reset + if (currDate.Month == cumulus.ChillHourSeasonStart && currDate.Day == 1) + { + TotalChillHours = 0; + } + else + { + // use whatever we have in the dayfile + TotalChillHours = dayfile.DayfileRecs[i].ChillHours; + + // unless we don't have anything, then start at zero + if (TotalChillHours == -9999) + TotalChillHours = 0; + } + while (dayfile.DayfileRecs[i].Date > currDate) { // if not step through the monthly log file(s) to recreate it @@ -112,11 +130,19 @@ static void Main() // step forward a day currDate = IncrementMeteoDate(currDate); + + // check if total chill hours needs to be reset + if (currDate.Month == cumulus.ChillHourSeasonStart && currDate.Day == 1) + { + TotalChillHours = 0; + } + // increment our index to allow for the newly inserted record if (i >= dayfile.DayfileRecs.Count) { break; } + } // undo the last date increment in the while loop, it gets incremented in the main loop now currDate = currDate.AddDays(-1); @@ -139,6 +165,12 @@ static void Main() currDate = IncrementMeteoDate(currDate); + // check if total chill hours needs to be reset + if (currDate.Month == cumulus.ChillHourSeasonStart && currDate.Day == 1) + { + TotalChillHours = 0; + } + if (currDate >= DateTime.Today) { // We don't do the future! @@ -147,6 +179,16 @@ static void Main() } currDate = IncrementMeteoDate(dayfile.DayfileRecs[dayfile.DayfileRecs.Count - 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) + { + TotalChillHours = 0; + } + else + { + TotalChillHours = dayfile.DayfileRecs[dayfile.DayfileRecs.Count - 1].ChillHours; + } // that is the dayfile processed, but what it it had missing records at the end? while (currDate <= endDate) @@ -168,6 +210,12 @@ static void Main() RecsAdded++; } currDate = IncrementMeteoDate(currDate); + + // check if total chill hours needs to be reset + if (currDate.Month == cumulus.ChillHourSeasonStart && currDate.Day == 1) + { + TotalChillHours = 0; + } } // create the new dayfile.txt with a different name @@ -221,7 +269,8 @@ private static Dayfilerec GetDayRecFromMonthly(DateTime date) HeatingDegreeDays = 0, CoolingDegreeDays = 0, TotalRain = 0, - WindRun = 0 + WindRun = 0, + ChillHours = 0 }; var started = false; var finished = false; @@ -296,6 +345,13 @@ private static Dayfilerec GetDayRecFromMonthly(DateTime date) { if (File.Exists(fileName)) { + // Have we determined the line endings for dayfile.txt yet? + if (dayfile.LineEnding == string.Empty) + { + Utils.TryDetectNewLine(fileName, out dayfile.LineEnding); + } + + try { if (CurrentLogName != fileName) @@ -310,7 +366,6 @@ private static Dayfilerec GetDayRecFromMonthly(DateTime date) double valDbl; int valInt; - while (CurrentLogLineNum < CurrentLogLines.Count) { // we use idx 0 & 1 together (date/time), set the idx to 1 @@ -605,6 +660,14 @@ private static Dayfilerec GetDayRecFromMonthly(DateTime date) rec.CoolingDegreeDays += (((outsidetemp - cumulus.NOAAcoolingthreshold) * intervalMins) / 1440); } + // chill hours + if (outsidetemp < cumulus.ChillHourThreshold) + { + TotalChillHours += intervalMins / 60.0; + } + rec.ChillHours = TotalChillHours; + + lasttempvalue = outsidetemp; } else // we are outside the time range of the current day @@ -641,6 +704,13 @@ private static Dayfilerec GetDayRecFromMonthly(DateTime date) rec.CoolingDegreeDays += (((outsidetemp - cumulus.NOAAcoolingthreshold) * intervalMins) / 1440); } + // chill hours + if (outsidetemp < cumulus.ChillHourThreshold) + { + TotalChillHours += intervalMins / 60.0; + } + rec.ChillHours = TotalChillHours; + // flag we are done with this record finished = true; } @@ -917,6 +987,10 @@ private static void AddMissingData(int idx, DateTime metDate) dayfile.DayfileRecs[idx].LowFeelsLike = newRec.LowFeelsLike; dayfile.DayfileRecs[idx].LowFeelsLikeTime = newRec.LowFeelsLikeTime; } + if (dayfile.DayfileRecs[idx].ChillHours == -9999) + { + dayfile.DayfileRecs[idx].ChillHours = newRec.ChillHours; + } Console.WriteLine("done."); RecsUpdated++; } diff --git a/Updates.txt b/Updates.txt index 0559122..0318dae 100644 --- a/Updates.txt +++ b/Updates.txt @@ -1,3 +1,8 @@ +1.1.0 +————— +- New: Adds Chill Hours for Cumulus MX v3.12.0 +- New: Now tries to determine the correct line endings for dayfile.txt. This allows CreateMissing to run on Windows with Linux files + 1.0.2 ————— - Fix: Sunshine hours always logged in the day file as zero when using a 9am meteo day diff --git a/Utils.cs b/Utils.cs index 69f2d99..afbbb15 100644 --- a/Utils.cs +++ b/Utils.cs @@ -1,6 +1,7 @@ using CumulusMX; using System; using System.Collections.Generic; +using System.IO; using System.Text; namespace CreateMissing @@ -32,7 +33,7 @@ public static double ConvertUserWindToKPH(double wind) // input is in Units.Wind case 1: return wind * 1.609344; // kph - case 2: + case 2: return wind; // knots case 3: @@ -59,7 +60,6 @@ public static double ConvertUserWindToMS(double value) }; } - public static int CalcAvgBearing(double x, double y) { var avg = 90 - (int)(180 / Math.PI * Math.Atan2(y, x)); @@ -71,6 +71,34 @@ public static int CalcAvgBearing(double x, double y) return avg; } + 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; + char curChar = (char)b; + + if (curChar == '\n') + { + newLine = prevChar == '\r' ? "\r\n" : "\n"; + return true; + } + + prevChar = curChar; + } + + // Returning false means could not determine linefeed convention + newLine = Environment.NewLine; + return false; + } + } } }