diff --git a/Backend/Models/Device.cs b/Backend/Models/Device.cs index 72c53d6..6f8bad7 100644 --- a/Backend/Models/Device.cs +++ b/Backend/Models/Device.cs @@ -82,6 +82,7 @@ namespace Backend.Models public List Device_disasters { get; set; } //防災類型 public List Device_nodes { get; set; } //設備子節點 + public System.DateTime created_at { get; set; } /// /// 前次成功日期;下次重新歸檔日期 /// @@ -277,6 +278,8 @@ namespace Backend.Models public string Point { get; set; } public string FullDeviceNumberPoint { get; set; } public System.DateTime archive_lastDate { get; set; } + + public System.DateTime created_at { get; set; } } public class ImportDevForCoo diff --git a/BackendWorkerService/Quartz/Jobs/ArchiveElectricMeterDayJob.cs b/BackendWorkerService/Quartz/Jobs/ArchiveElectricMeterDayJob.cs index 619d5c3..e4a2b9e 100644 --- a/BackendWorkerService/Quartz/Jobs/ArchiveElectricMeterDayJob.cs +++ b/BackendWorkerService/Quartz/Jobs/ArchiveElectricMeterDayJob.cs @@ -99,6 +99,7 @@ namespace BackendWorkerService.Quartz.Jobs deviceNumberPoint.Point = point.points; deviceNumberPoint.FullDeviceNumberPoint = string.Format("{0}_{1}", electricMeter.Device_number, point.points); deviceNumberPoint.archive_lastDate = electricMeter.archive_lastDate; + deviceNumberPoint.created_at = electricMeter.created_at; electricDeviceNumberPoints.Add(deviceNumberPoint); } } @@ -117,7 +118,7 @@ namespace BackendWorkerService.Quartz.Jobs deviceNumberPoint.Point = point.points; deviceNumberPoint.FullDeviceNumberPoint = string.Format("{0}_{1}", waterMeter.Device_number, point.points); deviceNumberPoint.archive_lastDate = waterMeter.archive_lastDate; - + deviceNumberPoint.created_at = waterMeter.created_at; waterDeviceNumberPoints.Add(deviceNumberPoint); } } @@ -168,6 +169,10 @@ namespace BackendWorkerService.Quartz.Jobs { var startDay = deviceNumberPoint.archive_lastDate.ToString("yyyy-MM-dd"); var endDay = System.DateTime.Now.AddDays(-1).ToString("yyyy-MM-dd"); + if (startDay == "0001-01-01") // 假設archive_lastDate為null + { + startDay = deviceNumberPoint.created_at.ToString("yyyy-MM-dd"); + } foreach (DateTime day in EachDay(startDay, endDay)) { var sDay = string.Format("{0}T00:00:00.000+08:00", day.ToString("yyyy-MM-dd").Replace(" ", "T")); // 巨蛋用此時間抓到的實際是T00:15:00的資料 @@ -252,6 +257,10 @@ namespace BackendWorkerService.Quartz.Jobs { var startDay = deviceNumberPoint.archive_lastDate.ToString("yyyy-MM-dd"); var endDay = System.DateTime.Now.AddDays(-1).ToString("yyyy-MM-dd"); + if (startDay == "0001-01-01") // 假設archive_lastDate為null + { + startDay = deviceNumberPoint.created_at.ToString("yyyy-MM-dd"); + } foreach (DateTime day in EachDay(startDay, endDay)) { var sDay = string.Format("{0}T00:00:00.000+08:00", day.ToString("yyyy-MM-dd").Replace(" ", "T")); // 巨蛋用此時間抓到的實際是T00:15:00的資料 @@ -1101,27 +1110,10 @@ namespace BackendWorkerService.Quartz.Jobs try { await task_Detail.InsertWorkTime("ArchiveElectricMeterDayJob", "Month", "水電表月任務開始"); - var preDay = now.AddDays(-1); //取得前一天 - var dayInMonth = DateTime.DaysInMonth(preDay.Year, preDay.Month); - var FirstDay = new DateTime(preDay.Year, preDay.Month, 1); - //var LastDay = now.AddMonths(1).AddDays(-now.AddMonths(1).Day); // 這是抓到該月最後一天 - var LastDay = now; - - - - //var startTimestamp = string.Format("{0}T23:59:59.000+08:00", FirstDay.AddDays(-1).ToString("yyyy-MM-dd")); // 巨蛋要這樣抓數據才是對的 - var startTimestamp = string.Format("{0}T00:00:00.000+08:00", FirstDay.ToString("yyyy-MM-dd")); - - //var endTimestamp = string.Format("{0}T23:59:59.000+08:00", LastDay.ToString("yyyy-MM-dd")); - var endTimestamp = string.Format("{0}T00:15:00.000+08:00", LastDay.ToString("yyyy-MM-dd")); // 240131 jay for dome - - - var historyQueryFilter = $@" - - - - "; + string startTimestamp = ""; + string endTimestamp = ""; + string historyQueryFilter = ""; //Stopwatch stopWatch = new Stopwatch(); //stopWatch.Start(); @@ -1131,138 +1123,229 @@ namespace BackendWorkerService.Quartz.Jobs List> waterArchiveMonthRawDatas = new List>(); foreach (var deviceNumberPoint in electricDeviceNumberPoints) { - device_number = deviceNumberPoint.FullDeviceNumberPoint; - if (tagQuantity.Equals("5")) - station = await backgroundServiceRepository.GetOneAsync($@"select parent_path from import_niagara_item_history + var startDay = deviceNumberPoint.archive_lastDate.ToString("yyyy-MM-dd"); + + var endDay = System.DateTime.Now.AddDays(-1).ToString("yyyy-MM-dd"); + + foreach (DateTime day in EachMonth(startDay, endDay)) + { + if (day.ToString("yyyy-MM") == System.DateTime.Now.AddDays(-1).ToString("yyyy-MM")) + { + var preDay = now.AddDays(-1); //取得前一天 + + var dayInMonth = DateTime.DaysInMonth(preDay.Year, preDay.Month); + var FirstDay = new DateTime(preDay.Year, preDay.Month, 1); + //var LastDay = now.AddMonths(1).AddDays(-now.AddMonths(1).Day); // 這是抓到該月最後一天 + var LastDay = now; + + //var startTimestamp = string.Format("{0}T23:59:59.000+08:00", FirstDay.AddDays(-1).ToString("yyyy-MM-dd")); // 巨蛋要這樣抓數據才是對的 + startTimestamp = string.Format("{0}T00:00:00.000+08:00", FirstDay.ToString("yyyy-MM-dd")); + + //var endTimestamp = string.Format("{0}T23:59:59.000+08:00", LastDay.ToString("yyyy-MM-dd")); + endTimestamp = string.Format("{0}T00:15:00.000+08:00", LastDay.ToString("yyyy-MM-dd")); // 240131 jay for dome + + + historyQueryFilter = $@" + + + + "; + + } + else + { + var dayInMonth = DateTime.DaysInMonth(day.Year, day.Month); + var FirstDay = new DateTime(day.Year, day.Month, 1); + var LastDay = new DateTime(day.Year, day.Month, dayInMonth); + + startTimestamp = string.Format("{0}T00:00:00.000+08:00", FirstDay.ToString("yyyy-MM-dd")); + + endTimestamp = string.Format("{0}T00:15:00.000+08:00", LastDay.ToString("yyyy-MM-dd")); + historyQueryFilter = $@" + + + + "; + } + + device_number = deviceNumberPoint.FullDeviceNumberPoint; + if (tagQuantity.Equals("5")) + station = await backgroundServiceRepository.GetOneAsync($@"select parent_path from import_niagara_item_history where device_building_tag = '{device_number.Split("_")[0]}' and device_floor_tag = '{device_number.Split("_")[2]}' and device_name_tag = '{device_number.Split("_")[1]}' and device_point_name = '{device_number.Split("_")[5]}'"); - else - station = backgroundServiceRepository.GetOneAsync($@"select parent_path from import_niagara_item_history + else + station = backgroundServiceRepository.GetOneAsync($@"select parent_path from import_niagara_item_history where device_building_tag = '{device_number.Split("_")[1].Replace("$3", "")}' and device_system_tag = '{device_number.Split("_")[2]}' and device_name_tag = '{device_number.Split("_")[3]}' and device_floor_tag = '{device_number.Split("_")[4]}' and device_master_tag = '{device_number.Split("_")[5]}' and device_last_name_tag = '{device_number.Split("_")[6]}' and device_serial_tag = '{device_number.Split("_")[7]}' and device_point_name = '{device_number.Split("_")[8]}'").Result; - archiveRequest = (HttpWebRequest)WebRequest.Create($"{obixApiConfig.ApiBase}obix/histories/{station}/{deviceNumberPoint.FullDeviceNumberPoint.Replace("$3", "")}/~historyRollup/"); - //HttpWebRequest archiveMonthRequest = (HttpWebRequest)WebRequest.Create($"{obixApiConfig.ApiBase}obix/histories/{station}/H_E1_B1F_MVCB_MVCBH_V1/~historyRollup/"); - archiveRequest.Method = "POST"; - archiveRequest.Headers.Add("Authorization", "Basic " + encoded); - archiveRequest.PreAuthenticate = true; + archiveRequest = (HttpWebRequest)WebRequest.Create($"{obixApiConfig.ApiBase}obix/histories/{station}/{deviceNumberPoint.FullDeviceNumberPoint.Replace("$3", "")}/~historyRollup/"); + //HttpWebRequest archiveMonthRequest = (HttpWebRequest)WebRequest.Create($"{obixApiConfig.ApiBase}obix/histories/{station}/H_E1_B1F_MVCB_MVCBH_V1/~historyRollup/"); + archiveRequest.Method = "POST"; + archiveRequest.Headers.Add("Authorization", "Basic " + encoded); + archiveRequest.PreAuthenticate = true; - byte[] byteArray = Encoding.UTF8.GetBytes(historyQueryFilter); - using (Stream reqStream = archiveRequest.GetRequestStream()) - { - reqStream.Write(byteArray, 0, byteArray.Length); - } - - archiveResponse = (HttpWebResponse)archiveRequest.GetResponse(); - archiveResponseContent = new StreamReader(archiveResponse.GetResponseStream()).ReadToEnd(); - archiveResponse.Dispose(); - archiveResponse.Close(); - - xmlDocument.LoadXml(archiveResponseContent); - archiveJson = JsonConvert.SerializeXmlNode(xmlDocument); - archiveJsonResult = (JObject)JsonConvert.DeserializeObject(archiveJson); - - if (archiveJsonResult.ContainsKey("err")) //抓取錯誤 - { - //logger.LogError("【ArchiveElectricMeterDayJob】【月歸檔】【取得資料失敗】"); - //logger.LogError("【ArchiveElectricMeterDayJob】【月歸檔】【取得資料失敗】[錯誤內容]:{0}", archiveMonthJsonResult); - - Dictionary archiveMonthRawData = new Dictionary(); - archiveMonthRawData.Add("@device_number", deviceNumberPoint.DeviceNumber); - archiveMonthRawData.Add("@point", deviceNumberPoint.Point); - archiveMonthRawData.Add("@start_timestamp", startTimestamp.Replace("T", " ").Substring(0, 19)); - archiveMonthRawData.Add("@end_timestamp", endTimestamp.Replace("T", " ").Substring(0, 19)); - archiveMonthRawData.Add("@is_complete", 0); - archiveMonthRawData.Add("@repeat_times", 0); - archiveMonthRawData.Add("@fail_reason", archiveJson); - - archiveMonthRawData.Add("@count_rawdata", 0); - archiveMonthRawData.Add("@min_rawdata", 0); - archiveMonthRawData.Add("@max_rawdata", 0); - archiveMonthRawData.Add("@avg_rawdata", 0); - archiveMonthRawData.Add("@sum_rawdata", 0); - archiveMonthRawData.Add("@updated_at", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")); - - electricArchiveMonthRawDatas.Add(archiveMonthRawData); - } - - if (archiveJsonResult.ContainsKey("obj")) //表示可以讀取到內容 - { - var ArrangeRawDatas = ArrangeRawData(deviceNumberPoint, archiveJsonResult); - if (ArrangeRawDatas != null && ArrangeRawDatas.Count() > 0) + byte[] byteArray = Encoding.UTF8.GetBytes(historyQueryFilter); + using (Stream reqStream = archiveRequest.GetRequestStream()) { - electricArchiveMonthRawDatas.AddRange(ArrangeRawDatas); + reqStream.Write(byteArray, 0, byteArray.Length); + } + + archiveResponse = (HttpWebResponse)archiveRequest.GetResponse(); + archiveResponseContent = new StreamReader(archiveResponse.GetResponseStream()).ReadToEnd(); + archiveResponse.Dispose(); + archiveResponse.Close(); + + xmlDocument.LoadXml(archiveResponseContent); + archiveJson = JsonConvert.SerializeXmlNode(xmlDocument); + archiveJsonResult = (JObject)JsonConvert.DeserializeObject(archiveJson); + + if (archiveJsonResult.ContainsKey("err")) //抓取錯誤 + { + //logger.LogError("【ArchiveElectricMeterDayJob】【月歸檔】【取得資料失敗】"); + //logger.LogError("【ArchiveElectricMeterDayJob】【月歸檔】【取得資料失敗】[錯誤內容]:{0}", archiveMonthJsonResult); + + Dictionary archiveMonthRawData = new Dictionary(); + archiveMonthRawData.Add("@device_number", deviceNumberPoint.DeviceNumber); + archiveMonthRawData.Add("@point", deviceNumberPoint.Point); + archiveMonthRawData.Add("@start_timestamp", startTimestamp.Replace("T", " ").Substring(0, 19)); + archiveMonthRawData.Add("@end_timestamp", endTimestamp.Replace("T", " ").Substring(0, 19)); + archiveMonthRawData.Add("@is_complete", 0); + archiveMonthRawData.Add("@repeat_times", 0); + archiveMonthRawData.Add("@fail_reason", archiveJson); + + archiveMonthRawData.Add("@count_rawdata", 0); + archiveMonthRawData.Add("@min_rawdata", 0); + archiveMonthRawData.Add("@max_rawdata", 0); + archiveMonthRawData.Add("@avg_rawdata", 0); + archiveMonthRawData.Add("@sum_rawdata", 0); + archiveMonthRawData.Add("@updated_at", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")); + + electricArchiveMonthRawDatas.Add(archiveMonthRawData); + } + + if (archiveJsonResult.ContainsKey("obj")) //表示可以讀取到內容 + { + var ArrangeRawDatas = ArrangeRawData(deviceNumberPoint, archiveJsonResult); + if (ArrangeRawDatas != null && ArrangeRawDatas.Count() > 0) + { + electricArchiveMonthRawDatas.AddRange(ArrangeRawDatas); + } } } } foreach (var deviceNumberPoint in waterDeviceNumberPoints) { - device_number = deviceNumberPoint.FullDeviceNumberPoint; - if (tagQuantity.Equals("5")) - station = await backgroundServiceRepository.GetOneAsync($@"select parent_path from import_niagara_item_history + var startDay = deviceNumberPoint.archive_lastDate.ToString("yyyy-MM-dd"); + + var endDay = System.DateTime.Now.AddDays(-1).ToString("yyyy-MM-dd"); + + foreach (DateTime day in EachMonth(startDay, endDay)) + { + if (day.ToString("yyyy-MM") == System.DateTime.Now.AddDays(-1).ToString("yyyy-MM")) + { + var preDay = now.AddDays(-1); //取得前一天 + + var dayInMonth = DateTime.DaysInMonth(preDay.Year, preDay.Month); + var FirstDay = new DateTime(preDay.Year, preDay.Month, 1); + //var LastDay = now.AddMonths(1).AddDays(-now.AddMonths(1).Day); // 這是抓到該月最後一天 + var LastDay = now; + + //var startTimestamp = string.Format("{0}T23:59:59.000+08:00", FirstDay.AddDays(-1).ToString("yyyy-MM-dd")); // 巨蛋要這樣抓數據才是對的 + startTimestamp = string.Format("{0}T00:00:00.000+08:00", FirstDay.ToString("yyyy-MM-dd")); + + //var endTimestamp = string.Format("{0}T23:59:59.000+08:00", LastDay.ToString("yyyy-MM-dd")); + endTimestamp = string.Format("{0}T00:15:00.000+08:00", LastDay.ToString("yyyy-MM-dd")); // 240131 jay for dome + + + historyQueryFilter = $@" + + + + "; + + } + else + { + var dayInMonth = DateTime.DaysInMonth(day.Year, day.Month); + var FirstDay = new DateTime(day.Year, day.Month, 1); + var LastDay = new DateTime(day.Year, day.Month, dayInMonth); + + startTimestamp = string.Format("{0}T00:00:00.000+08:00", FirstDay.ToString("yyyy-MM-dd")); + + endTimestamp = string.Format("{0}T00:15:00.000+08:00", LastDay.ToString("yyyy-MM-dd")); + historyQueryFilter = $@" + + + + "; + } + device_number = deviceNumberPoint.FullDeviceNumberPoint; + if (tagQuantity.Equals("5")) + station = await backgroundServiceRepository.GetOneAsync($@"select parent_path from import_niagara_item_history where device_building_tag = '{device_number.Split("_")[0]}' and device_floor_tag = '{device_number.Split("_")[2]}' and device_name_tag = '{device_number.Split("_")[1]}' and device_point_name = '{device_number.Split("_")[5]}'"); - else - station = backgroundServiceRepository.GetOneAsync($@"select parent_path from import_niagara_item_history + else + station = backgroundServiceRepository.GetOneAsync($@"select parent_path from import_niagara_item_history where device_building_tag = '{device_number.Split("_")[1].Replace("$3", "")}' and device_system_tag = '{device_number.Split("_")[2]}' and device_name_tag = '{device_number.Split("_")[3]}' and device_floor_tag = '{device_number.Split("_")[4]}' and device_master_tag = '{device_number.Split("_")[5]}' and device_last_name_tag = '{device_number.Split("_")[6]}' and device_serial_tag = '{device_number.Split("_")[7]}' and device_point_name = '{device_number.Split("_")[8]}'").Result; - archiveRequest = (HttpWebRequest)WebRequest.Create($"{obixApiConfig.ApiBase}obix/histories/{station}/{deviceNumberPoint.FullDeviceNumberPoint.Replace("$3", "")}/~historyRollup/"); - //HttpWebRequest archiveMonthRequest = (HttpWebRequest)WebRequest.Create($"{obixApiConfig.ApiBase}obix/histories/{station}/H_E1_B1F_MVCB_MVCBH_V1/~historyRollup/"); - archiveRequest.Method = "POST"; - archiveRequest.Headers.Add("Authorization", "Basic " + encoded); - archiveRequest.PreAuthenticate = true; + archiveRequest = (HttpWebRequest)WebRequest.Create($"{obixApiConfig.ApiBase}obix/histories/{station}/{deviceNumberPoint.FullDeviceNumberPoint.Replace("$3", "")}/~historyRollup/"); + //HttpWebRequest archiveMonthRequest = (HttpWebRequest)WebRequest.Create($"{obixApiConfig.ApiBase}obix/histories/{station}/H_E1_B1F_MVCB_MVCBH_V1/~historyRollup/"); + archiveRequest.Method = "POST"; + archiveRequest.Headers.Add("Authorization", "Basic " + encoded); + archiveRequest.PreAuthenticate = true; - byte[] byteArray = Encoding.UTF8.GetBytes(historyQueryFilter); - using (Stream reqStream = archiveRequest.GetRequestStream()) - { - reqStream.Write(byteArray, 0, byteArray.Length); - } - - archiveResponse = (HttpWebResponse)archiveRequest.GetResponse(); - archiveResponseContent = new StreamReader(archiveResponse.GetResponseStream()).ReadToEnd(); - archiveResponse.Dispose(); - archiveResponse.Close(); - - xmlDocument.LoadXml(archiveResponseContent); - archiveJson = JsonConvert.SerializeXmlNode(xmlDocument); - archiveJsonResult = (JObject)JsonConvert.DeserializeObject(archiveJson); - - if (archiveJsonResult.ContainsKey("err")) //抓取錯誤 - { - //logger.LogError("【ArchiveElectricMeterDayJob】【月歸檔】【取得資料失敗】"); - //logger.LogError("【ArchiveElectricMeterDayJob】【月歸檔】【取得資料失敗】[錯誤內容]:{0}", archiveMonthJsonResult); - - Dictionary archiveMonthRawData = new Dictionary(); - archiveMonthRawData.Add("@device_number", deviceNumberPoint.DeviceNumber); - archiveMonthRawData.Add("@point", deviceNumberPoint.Point); - archiveMonthRawData.Add("@start_timestamp", startTimestamp.Replace("T", " ").Substring(0, 19)); - archiveMonthRawData.Add("@end_timestamp", endTimestamp.Replace("T", " ").Substring(0, 19)); - archiveMonthRawData.Add("@is_complete", 0); - archiveMonthRawData.Add("@repeat_times", 0); - archiveMonthRawData.Add("@fail_reason", archiveJson); - - archiveMonthRawData.Add("@count_rawdata", 0); - archiveMonthRawData.Add("@min_rawdata", 0); - archiveMonthRawData.Add("@max_rawdata", 0); - archiveMonthRawData.Add("@avg_rawdata", 0); - archiveMonthRawData.Add("@sum_rawdata", 0); - archiveMonthRawData.Add("@updated_at", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")); - - waterArchiveMonthRawDatas.Add(archiveMonthRawData); - } - - if (archiveJsonResult.ContainsKey("obj")) //表示可以讀取到內容 - { - var ArrangeRawDatas = ArrangeRawData(deviceNumberPoint, archiveJsonResult); - if (ArrangeRawDatas != null && ArrangeRawDatas.Count() > 0) + byte[] byteArray = Encoding.UTF8.GetBytes(historyQueryFilter); + using (Stream reqStream = archiveRequest.GetRequestStream()) { - waterArchiveMonthRawDatas.AddRange(ArrangeRawDatas); + reqStream.Write(byteArray, 0, byteArray.Length); + } + + archiveResponse = (HttpWebResponse)archiveRequest.GetResponse(); + archiveResponseContent = new StreamReader(archiveResponse.GetResponseStream()).ReadToEnd(); + archiveResponse.Dispose(); + archiveResponse.Close(); + + xmlDocument.LoadXml(archiveResponseContent); + archiveJson = JsonConvert.SerializeXmlNode(xmlDocument); + archiveJsonResult = (JObject)JsonConvert.DeserializeObject(archiveJson); + + if (archiveJsonResult.ContainsKey("err")) //抓取錯誤 + { + //logger.LogError("【ArchiveElectricMeterDayJob】【月歸檔】【取得資料失敗】"); + //logger.LogError("【ArchiveElectricMeterDayJob】【月歸檔】【取得資料失敗】[錯誤內容]:{0}", archiveMonthJsonResult); + + Dictionary archiveMonthRawData = new Dictionary(); + archiveMonthRawData.Add("@device_number", deviceNumberPoint.DeviceNumber); + archiveMonthRawData.Add("@point", deviceNumberPoint.Point); + archiveMonthRawData.Add("@start_timestamp", startTimestamp.Replace("T", " ").Substring(0, 19)); + archiveMonthRawData.Add("@end_timestamp", endTimestamp.Replace("T", " ").Substring(0, 19)); + archiveMonthRawData.Add("@is_complete", 0); + archiveMonthRawData.Add("@repeat_times", 0); + archiveMonthRawData.Add("@fail_reason", archiveJson); + + archiveMonthRawData.Add("@count_rawdata", 0); + archiveMonthRawData.Add("@min_rawdata", 0); + archiveMonthRawData.Add("@max_rawdata", 0); + archiveMonthRawData.Add("@avg_rawdata", 0); + archiveMonthRawData.Add("@sum_rawdata", 0); + archiveMonthRawData.Add("@updated_at", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")); + + waterArchiveMonthRawDatas.Add(archiveMonthRawData); + } + + if (archiveJsonResult.ContainsKey("obj")) //表示可以讀取到內容 + { + var ArrangeRawDatas = ArrangeRawData(deviceNumberPoint, archiveJsonResult); + if (ArrangeRawDatas != null && ArrangeRawDatas.Count() > 0) + { + waterArchiveMonthRawDatas.AddRange(ArrangeRawDatas); + } } } } @@ -1663,7 +1746,7 @@ namespace BackendWorkerService.Quartz.Jobs { var strtday = DateTime.Parse(from); var endday = DateTime.Parse(thru); - for (var _month = strtday.Date; _month.Month <= endday.Month; _month = _month.AddDays(1)) + for (var _month = strtday.Date; _month.Month <= endday.Month; _month = _month.AddMonths(1)) yield return _month; }