简体   繁体   English

ASP.NET MVC 按周过滤日期时间

[英]ASP.NET MVC Filter datetime by weeks

I've got a Web API and a Get method, returning a query:我有一个 Web API 和一个 Get 方法,返回一个查询:

var query = from results in context.Table
            where results.Date>= startDate && results.Date <= endDate
            select new 
{ 
Week = { this is where I need a method to group by weeks },
Average = results.Where(x => x.Number).Average()
}

return query.ToList();

I want to calculate the average for each 7 days (that being the first week).我想计算每 7 天(即第一周)的平均值。

Example:示例:

Average 1 ... day 7 (Week 1)
Average 2 ... day 14 (Week 2)

How can I do that?我该怎么做? Being given an interval of datetimes, to filter it by weeks (not week of year)给定一个日期时间间隔,按周(而不是一年中的一周)过滤它

Why not write a stored procedure, I think there may be some limitations on your flexibility using Linq because of the idea that normally the GroupBy groups by value (the value of the referenced "thing") so you can group by State, or Age, but I guess you can Group week... (new thought)为什么不编写存储过程,我认为使用 Linq 可能会限制您使用 Linq 的灵活性,因为通常 GroupBy 按值(引用的“事物”的值)分组,因此您可以按状态或年龄分组,但我想你可以组周...(新想法)

Add a property called EndOfWeek and for example, the end of this week is (Sunday let's say) then EndOfWeek = 9.2.16 whereas last week was 8.28.16... etc. then you can easily group but you still have to arrange the data.添加一个名为 EndOfWeek 的属性,例如,本周末是(假设是星期日)然后 EndOfWeek = 9.2.16 而上周是 8.28.16... 等等,那么您可以轻松地分组,但您仍然必须安排数据。

I know I didn't answer the question but I hope that I sparked some brain activity in an area that allows you to solve the problem.我知道我没有回答这个问题,但我希望我在一个可以让你解决问题的领域引发了一些大脑活动。

--------- UPDATED ---------------- --------- 更新 ----------------

simple solution, loop through your records, foreach record determine the EndOfWeek for that record.简单的解决方案,遍历您的记录,foreach 记录确定该记录的 EndOfWeek。 After this you will now have a groupable value.在此之后,您现在将拥有一个可分组的值。 Easily group by EndOfWeek.按 EndOfWeek 轻松分组。 Simple!!!!!!!!!!!!简单!!!!!!!!!!!! Now, @MikeMcCaughan please tell me how this doesn't work?现在,@MikeMcCaughan 请告诉我这怎么行不通? Is it illogical to extend an object?扩展一个对象是不合逻辑的吗? What are you talking about?你在说什么?

------------ HERE IS THE CODE ---------------- ------------ 这里是代码 ----------------

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace SandboxConsole
{
class Program
{
    static void Main(string[] args)
    {
        var t = new Transactions();
        List<Transactions> transactions = t.GetTransactions();

        // Now let's add a Weeks end date so we can determine the average per week
        foreach(var transaction in transactions)
        {
            var transactionDayOfWeek = transaction.TransactionDate;
            int daysUntilEndOfWeek_Sat = ((int)DayOfWeek.Saturday - (int)transactionDayOfWeek.DayOfWeek + 7) % 7;
            transaction.Newly_Added_Property_To_Group_By_Week_To_Get_Averages = transactionDayOfWeek.AddDays(daysUntilEndOfWeek_Sat).ToShortDateString();
            //Console.WriteLine("{0} {")
        }

        foreach(var weekEnd in transactions.GroupBy(tt => tt.Newly_Added_Property_To_Group_By_Week_To_Get_Averages))
        {
            decimal weekTotal = 0;
            foreach(var trans in weekEnd)
            {
                weekTotal += trans.Amount;
            }

            var weekAverage = weekTotal / 7;
            Console.WriteLine("Week End: {0} - Avg {1}", weekEnd.Key.ToString(), weekAverage.ToString("C"));
        }
        Console.ReadKey();
    }
}

class Transactions
{
    public int Id { get; set; }
    public string SomeOtherProp { get; set; }
    public DateTime TransactionDate { get; set; }
    public decimal Amount { get; set; }
    public string Newly_Added_Property_To_Group_By_Week_To_Get_Averages { get; set; }

    public List<Transactions> GetTransactions()
    {
        var results = new List<Transactions>();

        for(var i = 0; i<100; i++)
        {
            results.Add(new Transactions
            {
                Id = i,
                SomeOtherProp = "Customer " + i.ToString(),
                TransactionDate = GetRandomDate(i),
                Amount = GetRandomAmount()
            });
        }

        return results;
    }

    public DateTime GetRandomDate(int i)
    {
        Random gen = new Random();
        DateTime startTime = new DateTime(2016, 1, 1);
        int range = (DateTime.Today - startTime).Days + i;
        return startTime.AddDays(gen.Next(range));
    }
    public int GetRandomAmount()
    {
        Random rnd = new Random();
        int amount = rnd.Next(1000, 10000);
        return amount;
    }
}

} }

------------ OUTPUT --------------- Sample Output ------------ OUTPUT ---------------样本输出

Try this (not tested with tables)试试这个(没有用表格测试)

var avgResult = context.QuestionaireResults
               .Where(r => (r.DepartureDate >= startDate && r.DepartureDate <= endDate)).ToList()
               .GroupBy( g => (Decimal.Round(g.DepartureDate.Day / 7)+1))
               .Select( g => new
                {
                   Week = g.Key,
                   Avg = g.Average(n => n.Number)
                }); 

You will need to group by the number of days, since a reference date, divided by 7, so您需要按自参考日期起的天数除以 7 进行分组,因此

.GroupBy(x => Math.Floor(((x.DepartureDate - new DateTime(1980,1,1)).TotalDays + 2) / 7))

Subtracting "Jan 1, 1980" from your departure date, gives you a TimeSpan object with the difference between the two dates.从您的出发日期减去“1980 年 1 月 1 日”,您将得到一个 TimeSpan 对象,其中包含两个日期之间的差异。 The TotalDays property of that timespan gives you timespan in days.该时间跨度的 TotalDays 属性以天为单位为您提供时间跨度。 Adding 2 corrects for the fact that "Jan 1, 1980" was a Tuesday.为“1980 年 1 月 1 日”是星期二这一事实添加 2 个更正。 Dividing by 7 gives you the number of weeks since then.除以 7 可以得出从那时起经过的周数。 Math.Floor rounds it down, so that you get a consistent integer for the week, given any day of the week or portion of days within the week. Math.Floor 将其四舍五入,以便在给定一周中的任何一天或一周内的部分天数的情况下获得一致的一周整数。

You could simplify a little by picking a reference date that is a Sunday (assuming that is your "first day of the week"), so you dont have to add 2 to correct.您可以通过选择星期日作为参考日期来简化一些(假设这是您的“一周的第一天”),因此您不必添加 2 来更正。 Like so:像这样:

.GroupBy(x => Math.Floor(((x.DepartureDate - new DateTime(1979,12,30)).TotalDays) / 7))

If you are sure that your data all falls within a single calendar year, you could maybe use the Calendar.GetWeekOfYear method to figure out the week, but I am not sure it would be any simpler.如果您确定您的数据都在一个日历年内,您可以使用 Calendar.GetWeekOfYear 方法来计算周,但我不确定它会更简单。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM