[英]What is the easiest way to get the difference in months between two dates in C#?
[英]C# get difference in months?
我正在C#開發一個項目。 我有一個名為ExamResult
的模型,它有一個名為Date
的字段,定義為String
。
然后我定義以下內容
var executionQuery = (from x in db.ExamResult
where x.Student.Equals(iStudent)
orderby x.Date
select *);
Date以<YEAR>-<MONTH>
格式獲取值,如下所示
2014-01
2013-04
2013-09
我想要做的是創建一個表,該表獲取返回的所有日期的最小值,並創建一個與最小日期相差幾個月的表。
例:
當我們得到如上所示的結果時,我想獲得下表(如果我們得到的最小值是2013-04)
9
0
5
我嘗試執行以下操作但是我收到了System.NotSupported
異常
var dates = executionQuery.Select(x => int.Parse(x.Date.Substring(0,
4)) * 12 + int.Parse(x.Date.Substring(5, 2)) -
int.Parse(minDate.Substring(0, 4)) * 12 -
int.Parse(minDate.Substring(5, 2)));
你知道我怎么做嗎?
將字符串轉換為實際的“DateTime”對象將使事情變得更簡單。
// Getting DateTime objects instead of strings
var dates = executionQuery.ToArray().Select(
x => DateTime.ParseExact(x.Date,"yyyy-MM", CultureInfo.InvariantCulture));
// calculating smallest date
var minDate = dates.Min(x => x);
// this will help you get a collection of integers
var diffDates = dates.Select(
x => ((x.Year - minDate.Year) * 12) + x.Month - minDate.Month);
我使用一個小的Func<TIn, TOut>
委托將您的字符串日期轉換為DateTimes,然后它們可以正確排序。
首先,將日期字符串轉換為DateTime
對象的簡單方法:
// Split the string and instantiate new DateTime object to sort by later
Func<string, DateTime> getDate = s => {
int[] dateParts = s
.Split(new char[] {'-'})
.Select(dp => int.Parse(dp))
.ToArray();
// Let's use the new DateTime(int year, int month, int day) constructor overload
// dateParts[0] is the year and dateParts[1] is the month;
// the magic number 1 below is just a day to give to the DateTime constructor
return new DateTime(dateParts[0], dateParts[1], 1);
};
您的代碼可能看起來像這樣; 我無法測試您的代碼,因此這取決於您是否可以使其工作:
注意我將您的Linq
查詢分開並在C#中進行排序; 所以你可以隨心所欲地從數據庫中獲取東西,然后訂購這些東西。 我希望這有效; 否則,你必須兩次調用我的getDate
Func
- 一次在orderby
,一次在select
; 我不喜歡那個選擇。
// The select now builds an anonymous object; You can also create a new class, ExamResultWithDate,
// for example, that has all fields of ExamResult plus a DateTime field; OR you can just add that
// property to the partial class generated by EF or Linq-to-Sql or whatever right on the ExamResult
// entity.
var executionQuery = (from x in db.ExamResult
where x.Student.Equals(iStudent)
select new { Entity = x, ActualDate = getDate(x.Date) }); // note select * as in your OP doesn't compile :)
var orderedQuery = executionQuery
.OrderBy(eq => eq.ActualDate)
.Select(er => er.Entity); // gets you just the entities in this case and discards the dates
要獲得有差異的日期,只需在最短的日期做一些簡單的計算:這也是你的程序的偽代碼;
// Let's get the minimum date and difference in months;
DateTime minDate = executionQuery
.ToList()
.Select(o => o.ActualDate)
.Min();
// I am just using the dates here but you can easily use your entire entity or whatever you need
Dictionary<DateTime, int> datesWithMonthDifference = executionQuery
.ToDictionary(
eq => eq.ActualDate
eq => ((eq.Year - minDate.Year) * 12) + eq.Month - minDate.Month // this formula calculates month difference as an integer
);
這是一個可以滿足您需求的工作程序:請注意,這只是一個需要適合您的項目的示例。
using System;
using System.Collections.Generic;
using System.Linq;
namespace DateTimeFromString
{
class Program
{
static void Main(string[] args)
{
List<string> dates = new List<string>()
{
"2014-01",
"2013-04",
"2013-09"
};
// Split the string and instantiate new DateTime object to sort by later
Func<string, DateTime> getDate = s => {
int[] dateParts = s
.Split(new char[] {'-'})
.Select(dp => int.Parse(dp))
.ToArray();
// Let's use the new DateTime(int year, int month, int day) constructor overload
// dateParts[0] is the year and dateParts[1] is the month;
// the magic number 1 below is just a day to give to the DateTime constructor
return new DateTime(dateParts[0], dateParts[1], 1);
};
List<DateTime> sortedDates = dates
.Select(d => getDate(d))
.OrderBy(d => d)
.ToList();
Console.WriteLine(" Sorted Dates: ");
sortedDates.ForEach(d => Console.WriteLine(d.Year.ToString() + " - " + d.Month.ToString()));
// Let's get the minimum date and difference in months;
DateTime minDate = sortedDates.Min();
Dictionary<DateTime, int> datesWithMonthDifference = sortedDates
.ToDictionary(
sd => sd,
sd => ((sd.Year - minDate.Year) * 12) + sd.Month - minDate.Month
);
Console.WriteLine();
Console.WriteLine("Sorted dates with month difference:");
foreach (var key in datesWithMonthDifference.Keys)
{
Console.WriteLine("{0} has difference of {1}", key, datesWithMonthDifference[key]);
}
Console.ReadKey();
}
}
}
我的測試程序的結果如下所示:
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.