c# - 将每周数据汇总为月份数据,赋予第一周和上周的权重
问题描述
我有一个数据库,其中包含基于周数(ISO8601 定义)的产品几年的价格值。
现在我需要按月汇总这些数据,但还要考虑每个月一周的权重。例如,如果当月一周只有 3 天,我需要给这周赋予 3/7 的权重,因此价格值为 (3/7)*price。
我已经开始编写这段代码,但我完全不知道如何继续。有没有一种简单的方法可以做到这一点,或者我需要逐个循环遍历所有年月,并以这种方式计算重量?(可能直接使用 LINQ 或 SQL)
此外,我无法获得我正在循环的月份中包含的周数(ISO-8601 定义,1 到 53)
例如,在 2021 年 1 月,我们有几个星期:
- 2020 年 53 月(部分,仅 3 天)
- 2021 年 01 月
- 2021 年 2 月 2 日
- 2021 年 3 月 3 日等。
public static decimal GetWeightedMonthlyPrice(int year, int week, int month, decimal priceValue)
{
DateTime startDate = FirstDateOfWeekISO8601(year,week);
//get weight of the week in the month
int daysInTheMonth=0;
for(int i=0;i<7;i++){
if(startDate.AddDays(i).Month==month){
daysInTheMonth++;
}
}
decimal weightedPrice= (daysInTheMonth/7m)*priceValue; //the weighted price for the current month
return weightedPrice;
}
和
public static DateTime FirstDateOfWeekISO8601(int year, int weekOfYear)
{
DateTime jan1 = new DateTime(year, 1, 1);
int daysOffset = DayOfWeek.Thursday - jan1.DayOfWeek;
DateTime firstThursday = jan1.AddDays(daysOffset);
var cal = CultureInfo.CurrentCulture.Calendar;
int firstWeek = cal.GetWeekOfYear(firstThursday, CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Monday);
var weekNum = weekOfYear;
if (firstWeek == 1)
{
weekNum -= 1;
}
var result = firstThursday.AddDays(weekNum * 7);
return result.AddDays(-3);
}
解决方案
如果您想在 C# 中执行此操作,可能类似于:
/// <summary>
///
/// </summary>
/// <param name="year"></param>
/// <param name="week"></param>
/// <param name="priceValue"></param>
/// <param name="month1">0 == december of year - 1</param>
/// <param name="weightedPrice1"></param>
/// <param name="month2">13 == january of year + 1, null == the week is fully contained in month1</param>
/// <param name="weightedPrice2">null == the week is fully contained in month1</param>
public static void GetWeightedMonthlyPrice(int year, int week, decimal priceValue, out int month1, out decimal weightedPrice1, out int? month2, out decimal? weightedPrice2)
{
DateTime startDate = FirstDateOfWeekISO8601(year, week);
month1 = startDate.Month;
int days1 = DateTime.DaysInMonth(year, month1) - startDate.Day + 1;
weightedPrice1 = days1 * priceValue / 7m;
int days2 = 7 - days1;
if (days2 != 0)
{
month2 = month1 + 1;
weightedPrice2 = days2 * priceValue / 7m;
}
else
{
month2 = null;
weightedPrice2 = null;
}
if (month1 == 12)
{
month1 = 0;
}
}
注意month
不是输入参数,而是输出参数,输出参数可以有两个month
s(如果必须拆分加权价格)。
firstThursday
如果您可以缓存调用之间的of FirstDateOfWeekISO8601
(不是说它“慢”,但我不想知道它每年被重新计算 52 或 53 次),则可以在 C# 中构建更快的解决方案。解决方案甚至可以建在 SQL 端。
推荐阅读
- python-3.x - 使用 tweepy 破坏和不完整的推文
- c# - 如何从 TCP 流中读取和解析 XML?
- jpa - 使用 IS NULL 运算符生成 Eclipselink 查询
- java - Android - 加载在 Java 上生成的动态 JAR 文件
- php - 数组中的正确图像路径
- salesforce - SingleEmailMessage 和 cc 的问题
- css - 如何并排放置 2 个图像而它们之间没有空格?
- reactjs - 如何使用 .NET Core 与 redux 项目反应基于反应组件修改页面标题?
- javascript - IE 11 上的 MutationObserver 语法错误
- c# - 同一实体类型的一对一和一对多