Snoopy 3 жил өмнө
parent
commit
3650b9cf15

+ 25 - 0
TCCElectricityTimes.sln

@@ -0,0 +1,25 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 17
+VisualStudioVersion = 17.0.32112.339
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TCCElectricityTimes", "TCCElectricityTimes\TCCElectricityTimes.csproj", "{FB9A2186-A915-4592-8517-429BA20C7254}"
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|Any CPU = Debug|Any CPU
+		Release|Any CPU = Release|Any CPU
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{FB9A2186-A915-4592-8517-429BA20C7254}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{FB9A2186-A915-4592-8517-429BA20C7254}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{FB9A2186-A915-4592-8517-429BA20C7254}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{FB9A2186-A915-4592-8517-429BA20C7254}.Release|Any CPU.Build.0 = Release|Any CPU
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+	GlobalSection(ExtensibilityGlobals) = postSolution
+		SolutionGuid = {058A6BD1-43E8-4151-B03C-D96E667A5A50}
+	EndGlobalSection
+EndGlobal

+ 6 - 0
TCCElectricityTimes/App.config

@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<configuration>
+    <startup> 
+        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.8" />
+    </startup>
+</configuration>

+ 278 - 0
TCCElectricityTimes/ElectricityTimes.cs

@@ -0,0 +1,278 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace TCCElectricityTimes
+{
+    internal class ElectricityTimes
+    {
+        #region Fields
+        // 西曆假日,每年固定5天
+        // 開國紀念日, 和平紀念日, 兒童節, 勞動節, 國慶日
+        private List<string> gregorianCalendarHoliday = new List<string>()
+        {
+            "0101", "0228", "0404", "0501", "1010"
+        };
+
+        // 農曆假日(+民族掃墓節)對應的西曆日期,每年9天(當清明節氣為4/4時和兒童節同天),注意農曆可能有閏月
+        // 農曆除夕, 初一至初五, 民族掃墓節, 端午節, 中秋節
+        private List<string> lunarCalendarHoliday = new List<string>()
+        {
+            "20220131", "20220201", "20220202", "20220203", "20220204", "20220205", "20220405", "20220603", "20220910",
+            "20230121", "20230122", "20230123", "20230124", "20230125", "20230126", "20230405", "20230622", "20230929",
+            "20240209", "20240210", "20240211", "20240212", "20240213", "20240214", "20240404", "20240610", "20240917",
+            "20250128", "20250129", "20250130", "20250131", "20250201", "20250202", "20250404", "20250531", "20251006",
+            "20260216", "20260217", "20260218", "20260219", "20260220", "20260221", "20260405", "20260619", "20260925",
+            "20270205", "20270206", "20270207", "20270208", "20270209", "20270210", "20270405", "20270609", "20270915",
+            "20280125", "20280126", "20280127", "20280128", "20280129", "20280130", "20280404", "20280528", "20281003",
+            "20290212", "20290213", "20290214", "20290215", "20290216", "20290217", "20290404", "20290616", "20290922",
+            "20300202", "20300203", "20300204", "20300205", "20300206", "20300207", "20300405", "20300605", "20300912",
+            "20310122", "20310123", "20310124", "20310125", "20310126", "20310127", "20310405", "20310624", "20311001",
+            "20320210", "20320211", "20320212", "20320213", "20320214", "20320215", "20320404", "20320612", "20320919",
+            "20330130", "20330131", "20330201", "20330202", "20330203", "20330204", "20330404", "20330601", "20330908",
+            "20340218", "20340219", "20340220", "20340221", "20340222", "20340223", "20340405", "20340620", "20340927",
+            "20350207", "20350208", "20350209", "20350210", "20350211", "20350212", "20350405", "20350610", "20350916",
+            "20360127", "20360128", "20360129", "20360130", "20360131", "20360201", "20360404", "20360530", "20361004",
+            "20370214", "20370215", "20370216", "20370217", "20370218", "20370219", "20370404", "20370618", "20370924",
+            "20380203", "20380204", "20380205", "20380206", "20380207", "20380208", "20380405", "20380607", "20380913",
+            "20390123", "20390124", "20390125", "20390126", "20390127", "20390128", "20390405", "20390527", "20391002",
+            "20400211", "20400212", "20400213", "20400214", "20400215", "20400216", "20400404", "20400614", "20400920",
+            "20410131", "20410201", "20410202", "20410203", "20410204", "20410205", "20410404", "20410603", "20410910",
+            "20420121", "20420122", "20420123", "20420124", "20420125", "20420126", "20420404", "20420622", "20420928",
+            "20430209", "20430210", "20430211", "20430212", "20430213", "20430214", "20430405", "20430611", "20430917",
+            "20440129", "20440130", "20440131", "20440201", "20440202", "20440203", "20440404", "20440531", "20441005",
+            "20450216", "20450217", "20450218", "20450219", "20450220", "20450221", "20450404", "20450619", "20450925",
+            "20460205", "20460206", "20460207", "20460208", "20460209", "20460210", "20460404", "20460608", "20460915",
+            "20470125", "20470126", "20470127", "20470128", "20470129", "20470130", "20470405", "20470529", "20471004",
+            "20480213", "20480214", "20480215", "20480216", "20480217", "20480218", "20480404", "20480615", "20480922",
+            "20490201", "20490202", "20490203", "20490204", "20490205", "20490206", "20490404", "20490604", "20490911",
+            "20500122", "20500123", "20500124", "20500125", "20500126", "20500127", "20500404", "20500623", "20500930",
+            "20510210", "20510211", "20510212", "20510213", "20510214", "20510215", "20510405", "20510613", "20510919",
+            "20520131", "20520201", "20520202", "20520203", "20520204", "20520205", "20520404", "20520601", "20520907",
+
+        };
+
+        private List<TaiPowerDailyPeriod> holidayTimesList = new List<TaiPowerDailyPeriod>();
+        private List<TaiPowerDailyPeriod> saturdayTimesList = new List<TaiPowerDailyPeriod>();
+        private List<TaiPowerDailyPeriod> nsworkdayTimesList = new List<TaiPowerDailyPeriod>();
+        private List<TaiPowerDailyPeriod> suworkdayTimesList = new List<TaiPowerDailyPeriod>();
+        #endregion
+
+        #region Constructors
+        public ElectricityTimes()
+        {
+            GenerateElectricityTimesList();
+        }
+        #endregion
+
+        #region Instance Methods
+        /// <summary>
+        /// 決定所輸入時間段主要歸屬的用電時段種類
+        /// </summary>
+        /// <param name="beginDateTime">起始日期時間</param>
+        /// <param name="endDateTime">截止日期時間</param>
+        /// <returns>用電時段種類(尖峰、半尖峰、離峰)</returns>
+        public ElectricityTimesType DetermineElectricityTimesType(DateTime beginDateTime, DateTime endDateTime)
+        {
+            ElectricityTimesType eTimesType = ElectricityTimesType.Undefine;
+            DailyType daytype;
+            DateTime dt;
+            double[] typeHours = new double[3];
+            double beginHour;
+            double endHour;
+
+            if (beginDateTime.Date == endDateTime.Date) // not overnight
+            {
+                daytype = DetermineDayType(beginDateTime);
+
+                dt = new DateTime(beginDateTime.Year, beginDateTime.Month, beginDateTime.Day);
+                beginHour = (beginDateTime - dt).TotalHours;
+                endHour = (endDateTime - dt).TotalHours;
+
+                typeHours = CalculateElectricityTimesType(beginHour, endHour, daytype);
+            }
+            else if (beginDateTime.Date < endDateTime.Date) // overnight
+            {
+                double[] typeHoursFirst = new double[3];
+                double[] typeHoursSecond = new double[3];
+
+                dt = new DateTime(beginDateTime.Year, beginDateTime.Month, beginDateTime.Day);
+                beginHour = (beginDateTime - dt).TotalHours;
+                daytype = DetermineDayType(beginDateTime);
+                typeHoursFirst = CalculateElectricityTimesType(beginHour, 24.0, daytype);
+
+                dt = new DateTime(endDateTime.Year, endDateTime.Month, endDateTime.Day);
+                endHour = (endDateTime - dt).TotalHours;
+                daytype = DetermineDayType(endDateTime);
+                typeHoursSecond = CalculateElectricityTimesType(0.0, endHour, daytype);
+
+                for (int i = 0; i < 3; i++)
+                {
+                    typeHours[i] = typeHoursFirst[i] + typeHoursSecond[i];
+                }
+            }
+            else
+            {
+                ; // something wrong
+            }
+
+            int mainIdx = Array.IndexOf(typeHours, typeHours.Max());
+
+            return (ElectricityTimesType)mainIdx;
+        }
+
+        private void GenerateElectricityTimesList()
+        {
+            holidayTimesList.Add(new TaiPowerDailyPeriod() { Type = ElectricityTimesType.OffPeak, PeriodBegin = 0.0, PeriodEnd = 24.0 });
+
+            saturdayTimesList.Add(new TaiPowerDailyPeriod() { Type = ElectricityTimesType.OffPeak, PeriodBegin = 0.0, PeriodEnd = 7.5 });
+            saturdayTimesList.Add(new TaiPowerDailyPeriod() { Type = ElectricityTimesType.SemiPeak, PeriodBegin = 7.5, PeriodEnd = 22.5 });
+            saturdayTimesList.Add(new TaiPowerDailyPeriod() { Type = ElectricityTimesType.OffPeak, PeriodBegin = 22.5, PeriodEnd = 24.0 });
+
+            nsworkdayTimesList.Add(new TaiPowerDailyPeriod() { Type = ElectricityTimesType.OffPeak, PeriodBegin = 0.0, PeriodEnd = 7.5 });
+            nsworkdayTimesList.Add(new TaiPowerDailyPeriod() { Type = ElectricityTimesType.SemiPeak, PeriodBegin = 7.5, PeriodEnd = 22.5 });
+            nsworkdayTimesList.Add(new TaiPowerDailyPeriod() { Type = ElectricityTimesType.OffPeak, PeriodBegin = 22.5, PeriodEnd = 24.0 });
+
+            suworkdayTimesList.Add(new TaiPowerDailyPeriod() { Type = ElectricityTimesType.OffPeak, PeriodBegin = 0.0, PeriodEnd = 7.5 });
+            suworkdayTimesList.Add(new TaiPowerDailyPeriod() { Type = ElectricityTimesType.SemiPeak, PeriodBegin = 7.5, PeriodEnd = 13.0 });
+            suworkdayTimesList.Add(new TaiPowerDailyPeriod() { Type = ElectricityTimesType.Peak, PeriodBegin = 13.0, PeriodEnd = 17.0 });
+            suworkdayTimesList.Add(new TaiPowerDailyPeriod() { Type = ElectricityTimesType.SemiPeak, PeriodBegin = 17.0, PeriodEnd = 18.0 });
+            suworkdayTimesList.Add(new TaiPowerDailyPeriod() { Type = ElectricityTimesType.Peak, PeriodBegin = 18.0, PeriodEnd = 20.0 });
+            suworkdayTimesList.Add(new TaiPowerDailyPeriod() { Type = ElectricityTimesType.SemiPeak, PeriodBegin = 20.0, PeriodEnd = 22.5 });
+            suworkdayTimesList.Add(new TaiPowerDailyPeriod() { Type = ElectricityTimesType.OffPeak, PeriodBegin = 22.5, PeriodEnd = 24.0 });
+        }
+
+        private DailyType DetermineDayType(DateTime datetime)
+        {
+            DailyType dayType = DailyType.Unknown;
+            string ymdDate = datetime.ToString("yyyyMMdd");
+            int mdDate = Int32.Parse(ymdDate.Substring(4, 4));
+
+            dayType = (datetime.DayOfWeek == DayOfWeek.Sunday) ? DailyType.Holiday : dayType;
+            dayType = (datetime.DayOfWeek == DayOfWeek.Saturday) ? DailyType.Saturday : dayType;
+            dayType = gregorianCalendarHoliday.Where(t => t == ymdDate.Substring(4, 4)).FirstOrDefault() != null ? DailyType.Holiday : dayType;
+            dayType = lunarCalendarHoliday.Where(t => t == ymdDate).FirstOrDefault() != null ? DailyType.Holiday : dayType;
+            if (dayType == DailyType.Unknown)
+            {
+                dayType = (mdDate < 601 || mdDate > 930) ? DailyType.NonSummerWorkDay : DailyType.SummerWorkDay;
+            }
+
+            return dayType;
+        }
+
+        private double[] CalculateElectricityTimesType(double beginHour, double endHour, DailyType dayType)
+        {
+            List<TaiPowerDailyPeriod> periodList = new List<TaiPowerDailyPeriod>();
+
+            switch (dayType)
+            {
+                case DailyType.Holiday:
+                    periodList = new List<TaiPowerDailyPeriod>(holidayTimesList);
+                    break;
+                case DailyType.Saturday:
+                    periodList = new List<TaiPowerDailyPeriod>(saturdayTimesList);
+                    break;
+                case DailyType.NonSummerWorkDay:
+                    periodList = new List<TaiPowerDailyPeriod>(nsworkdayTimesList);
+                    break;
+                case DailyType.SummerWorkDay:
+                    periodList = new List<TaiPowerDailyPeriod>(suworkdayTimesList);
+                    break;
+                default:
+                    break;
+            }
+
+            int beginIdx = -1;
+            int endIdx = -1;
+            for (int i = periodList.Count - 1; i >= 0; i--)
+            {
+                if (beginHour >= periodList[i].PeriodBegin)
+                {
+                    beginIdx = i;
+                    break;
+                }
+            }
+            for (int i = 0; i < periodList.Count; i++)
+            {
+                if (endHour <= periodList[i].PeriodEnd)
+                {
+                    endIdx = i;
+                    break;
+                }
+            }
+
+            double[] periodHours = new double[periodList.Count];
+            for (int i = beginIdx; i <= endIdx; i++)
+            {
+                if (beginIdx == endIdx)
+                {
+                    periodHours[i] = endHour - beginHour;
+                    break;
+                }
+
+                if (i == beginIdx)
+                {
+                    periodHours[i] = periodList[i].PeriodEnd - beginHour;
+                }
+                else if (i == endIdx)
+                {
+                    periodHours[i] = endHour - periodList[i].PeriodBegin;
+                }
+                else
+                {
+                    periodHours[i] = periodList[i].PeriodEnd - periodList[i].PeriodBegin;
+                }
+            }
+
+            double[] typeHours = new double[3]; // 0:Peak; 1:SemiPeak; 2:OffPeak
+            for (int i = 0; i < periodList.Count; i++)
+            {
+                switch (periodList[i].Type)
+                {
+                    case ElectricityTimesType.Peak:
+                        typeHours[0] += periodHours[i];
+                        break;
+                    case ElectricityTimesType.SemiPeak:
+                        typeHours[1] += periodHours[i];
+                        break;
+                    case ElectricityTimesType.OffPeak:
+                        typeHours[2] += periodHours[i];
+                        break;
+                }
+            }
+
+            //int mainIdx = Array.IndexOf(type, type.Max());
+
+            return typeHours;
+        }
+        #endregion
+
+        #region Nested Enums and Classes
+        public enum DailyType
+        {
+            Holiday = 0,
+            Saturday,
+            NonSummerWorkDay,
+            SummerWorkDay,
+            Unknown
+        }
+
+        public enum ElectricityTimesType
+        {
+            Peak = 0,
+            SemiPeak,
+            OffPeak,
+            Undefine
+        }
+
+        public class TaiPowerDailyPeriod
+        {
+            public ElectricityTimesType Type { get; set; }
+            public double PeriodBegin { get; set; }
+            public double PeriodEnd { get; set; }
+        }
+        #endregion
+    }
+}

+ 23 - 0
TCCElectricityTimes/Program.cs

@@ -0,0 +1,23 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace TCCElectricityTimes
+{
+    internal class Program
+    {
+        static void Main(string[] args)
+        {
+            DateTime dtBegin = new DateTime(2022, 2, 13, 11, 0, 0);
+            DateTime dtEnd = new DateTime(2022, 2, 14, 3, 50, 0);
+
+            ElectricityTimes eTimes = new ElectricityTimes();
+            ElectricityTimes.ElectricityTimesType type = eTimes.DetermineElectricityTimesType(dtBegin, dtEnd);
+
+            Console.WriteLine(type);
+            Console.ReadLine();
+        }
+    }
+}

+ 36 - 0
TCCElectricityTimes/Properties/AssemblyInfo.cs

@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// 組件的一般資訊是由下列的屬性集控制。
+// 變更這些屬性的值即可修改組件的相關
+// 資訊。
+[assembly: AssemblyTitle("TCCElectricityTimes")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("TCCElectricityTimes")]
+[assembly: AssemblyCopyright("Copyright ©  2022")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// 將 ComVisible 設為 false 可對 COM 元件隱藏
+// 組件中的類型。若必須從 COM 存取此組件中的類型,
+// 的類型,請在該類型上將 ComVisible 屬性設定為 true。
+[assembly: ComVisible(false)]
+
+// 下列 GUID 為專案公開 (Expose) 至 COM 時所要使用的 typelib ID
+[assembly: Guid("fb9a2186-a915-4592-8517-429ba20c7254")]
+
+// 組件的版本資訊由下列四個值所組成:
+//
+//      主要版本
+//      次要版本
+//      組建編號
+//      修訂
+//
+// 您可以指定所有的值,也可以使用 '*' 將組建和修訂編號
+// 設為預設,如下所示:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]

+ 54 - 0
TCCElectricityTimes/TCCElectricityTimes.csproj

@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProjectGuid>{FB9A2186-A915-4592-8517-429BA20C7254}</ProjectGuid>
+    <OutputType>Exe</OutputType>
+    <RootNamespace>TCCElectricityTimes</RootNamespace>
+    <AssemblyName>TCCElectricityTimes</AssemblyName>
+    <TargetFrameworkVersion>v4.8</TargetFrameworkVersion>
+    <FileAlignment>512</FileAlignment>
+    <AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
+    <Deterministic>true</Deterministic>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <PlatformTarget>AnyCPU</PlatformTarget>
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>bin\Debug\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <PlatformTarget>AnyCPU</PlatformTarget>
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>bin\Release\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="System" />
+    <Reference Include="System.Core" />
+    <Reference Include="System.Xml.Linq" />
+    <Reference Include="System.Data.DataSetExtensions" />
+    <Reference Include="Microsoft.CSharp" />
+    <Reference Include="System.Data" />
+    <Reference Include="System.Net.Http" />
+    <Reference Include="System.Xml" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="ElectricityTimes.cs" />
+    <Compile Include="Program.cs" />
+    <Compile Include="Properties\AssemblyInfo.cs" />
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="App.config" />
+  </ItemGroup>
+  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+</Project>