![](/img/trans.png)
[英]how to get first day of month and last day of month using date time in C#
[英]C# Find day first time and last time in a range of dates
我有一個看起來像這樣的文件(列表已排序):
2013-05-02 07:45:15
2013-05-02 09:25:01
2013-05-02 18:15:15
2013-05-04 08:45:15
2013-05-04 17:45:35
我只想獲得該列表中每一天的第一時間和最后時間,所以這意味着我想要得到:
2013-05-02 07:45:15
2013-05-02 18:15:15
2013-05-04 08:45:15
2013-05-04 17:45:35
什么是實現這一目標的最有效方法? 我想我可以使用周期獲取它,並在其中比較日期。 但是也許有更有效的方法? 是否可以使用linq或其他一些比使用周期更快/更干凈的方法來實現結果?
var result = File.ReadAllLines("yourPath")
.Select(line => DateTime.ParseExact(line,
"yyyy-MM-dd HH:mm:ss",
CultureInfo.CurrentCulture))
.GroupBy(d => d.Date)
.SelectMany(g => new[] { g.Min(), g.Max() });
按日期分組,並獲得每個日期的第一行和最后一行。 例:
string[] dates = {
"2013-05-02 07:45:15",
"2013-05-02 09:25:01",
"2013-05-02 18:15:15",
"2013-05-04 08:45:15",
"2013-05-04 17:45:35"
};
var days =
dates.GroupBy(s => s.Substring(0, 10))
.Select(g => new { First = g.First(), Last = g.Last() });
foreach (var day in days) {
Console.WriteLine("{0} - {1}", day.First, day.Last);
}
輸出:
2013-05-02 07:45:15 - 2013-05-02 18:15:15
2013-05-04 08:45:15 - 2013-05-04 17:45:35
要獲取最新日期,可以使用:
var latestDate = datetimeCollection.Max();
對於最古老的一個:
var oldestDate = datetimeCollection.Min();
請注意, datetimeCollection
是DateTime
對象的List / Collection。
與此類似的東西應該起作用。
var allDates = new[]
{
"2013-05-02 07:45:15",
"2013-05-02 09:25:01",
"2013-05-02 18:15:15",
"2013-05-04 08:45:15",
"2013-05-04 17:45:35"
};
var earliest = allDates.GroupBy(date => Convert.ToDateTime(date).Day).Select(g => new
{
first = g.Min(),
last = g.Max()
});
static void Main(string[] args)
{
var dates = System.IO.File.ReadAllLines(@"C:\dates.txt").Select(o => DateTime.Parse(o));
var res = new List<DateTime>();
foreach (var item in (from o in dates group o by o.Date into g select g.Key))
{
var dummy = dates.Where(o => o.Date == item);
res.Add(dummy.Max());
res.Add(dummy.Min());
}
}
您可以按日期對日期進行分組,然后對分組內容進行排序並獲得第一個和最后一個元素:
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
class Program {
static void Main(string[] args) {
string[] fileContents = new string[] {
"2013-05-02 07:45:15",
"2013-05-02 09:25:01",
"2013-05-02 18:15:15",
"2013-05-04 08:45:15",
"2013-05-04 17:45:35"
};
List<DateTime> dates = fileContents.ToList().ConvertAll(s => DateTime.ParseExact(s, "yyyy-MM-dd HH:mm:ss", CultureInfo.InvariantCulture));
foreach (var datesInSameDay in dates.GroupBy(d => d.Day)) {
var datesList = datesInSameDay.ToList();
datesList.Sort();
Console.WriteLine(datesList.First());
Console.WriteLine(datesList.Last());
}
}
}
“實現這一目標的最有效方法是什么?”
由於您說的是列表已排序,因此我們可以通過一次遍歷源時間來生成所需時間。
這避免了所有其他答案的分組。 如果未對輸入數據進行排序,則必須進行這種分組,但是由於它是按升序的日期/時間進行排序的,因此我們無需顯式分組。
首先,讓我們定義一個簡單的轉換器,將字符串轉換為DateTime
:
public IEnumerable<DateTime> ParseTimes(IEnumerable<string> times)
{
return times.Select(time => DateTime.ParseExact(time, "yyyy-MM-dd HH:mm:ss", CultureInfo.InvariantCulture));
}
然后,我們可以編寫一個簡單的方法,該方法返回每天的第一次和最后一次時間(如果一天中只有一次,則返回一天中的唯一時間),如下所示:
public IEnumerable<DateTime> FirstAndLastTimesForEachDay(IEnumerable<DateTime> times)
{
DateTime previous = DateTime.MinValue;
DateTime current = DateTime.MinValue;
foreach (var time in times)
{
if (previous.Date < time.Date)
{
if (previous != current)
yield return previous;
yield return time;
current = time;
}
previous = time;
}
if (previous != current)
yield return previous;
}
然后,您可以像這樣使用它:
var times = new []
{
"2013-05-02 07:45:15",
"2013-05-02 09:25:01",
"2013-05-02 18:15:15",
"2013-05-03 12:34:45",
"2013-05-04 08:45:15",
"2013-05-04 17:45:35",
"2013-05-05 20:00:00"
};
foreach (var time in FirstAndLastTimesForEachDay(ParseTimes(times)))
Console.WriteLine(time);
請注意,以上實現僅在僅包含單個DateTime的日期中輸出單個DateTime。 相反,如果您希望輸出在一天中包含單個出現的DateTime的兩倍(因此,即使時間相同,則每天總是有一對DateTime),則將實現更改為:
public IEnumerable<DateTime> FirstAndLastTimesForEachDay(IEnumerable<DateTime> times)
{
DateTime previous = DateTime.MinValue;
foreach (var time in times)
{
if (previous.Date < time.Date)
{
if (previous != DateTime.MinValue)
yield return previous;
yield return time;
}
previous = time;
}
if (previous != DateTime.MinValue)
yield return previous;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.