C#中对键为DateTime类型的字典排序以获取最小及最大时间键
问题原因
- 普通
Dictionary<TKey,TValue>属于无序集合,遍历顺序默认和元素插入顺序一致,不会自动排序。且LINQ的OrderBy方法不会修改原集合,只会返回一个新的排序后序列,你的代码中没有接收该返回值,所以排序逻辑完全没有生效。 - 你写的排序规则仅指定了按小时排序,没有包含分钟维度,就算排序逻辑生效,同小时的不同分钟条目也无法得到正确顺序。
解决方案
方案1:直接对原字典排序后遍历
DateTime类型本身已实现比较逻辑,无需单独拆分小时、分钟字段,直接按键排序后遍历返回的新序列即可:
var slots = new Dictionary<DateTime, DateTime>(); slots.Add(DateTime.UtcNow.Date + new TimeSpan(9, 0, 0), DateTime.UtcNow.Date + new TimeSpan(9, 30, 0)); slots.Add(DateTime.UtcNow.Date + new TimeSpan(10, 0, 0), DateTime.UtcNow.Date + new TimeSpan(10, 30, 0)); slots.Add(DateTime.UtcNow.Date + new TimeSpan(9, 30, 0), DateTime.UtcNow.Date + new TimeSpan(9, 45, 0)); slots.Add(DateTime.UtcNow.Date + new TimeSpan(11, 0, 0), DateTime.UtcNow.Date + new TimeSpan(11, 45, 0)); // 接收排序后的序列 var orderedSlots = slots.OrderBy(x => x.Key).ToList(); foreach (var slot in orderedSlots) { Console.WriteLine("Start Time : {0}, End Time: {1}", slot.Key, slot.Value); }
方案2:使用有序字典自动维护排序
如果需要长期使用按Key排序的集合,可以直接用SortedDictionary替代普通Dictionary,添加元素时会自动按Key升序维护顺序,无需手动排序:
// 直接声明有序字典 var slots = new SortedDictionary<DateTime, DateTime>(); slots.Add(DateTime.UtcNow.Date + new TimeSpan(9, 0, 0), DateTime.UtcNow.Date + new TimeSpan(9, 30, 0)); slots.Add(DateTime.UtcNow.Date + new TimeSpan(10, 0, 0), DateTime.UtcNow.Date + new TimeSpan(10, 30, 0)); slots.Add(DateTime.UtcNow.Date + new TimeSpan(9, 30, 0), DateTime.UtcNow.Date + new TimeSpan(9, 45, 0)); slots.Add(DateTime.UtcNow.Date + new TimeSpan(11, 0, 0), DateTime.UtcNow.Date + new TimeSpan(11, 45, 0)); // 直接遍历就是升序结果 foreach (var slot in slots) { Console.WriteLine("Start Time : {0}, End Time: {1}", slot.Key, slot.Value); }
额外需求:取最小/最大键
不需要全量排序也可以直接获取边界值:
DateTime minStartTime = slots.Keys.Min(); DateTime maxStartTime = slots.Keys.Max();
内容的提问来源于stack exchange,提问作者mnu-nasir
相关产品推荐
相关产品推荐

