2009-12-31 18 views
258

Cách nhanh nhất và dễ nhất để nhận giá trị Min (hoặc Max) giữa hai ngày là gì? Có tương đương với Math.Min (& Math.Max) cho các ngày không?Tương đương với Math.Min & Math.Max ​​cho các ngày?

tôi muốn làm một cái gì đó như:

if (Math.Min(Date1, Date2) < MINIMUM_ALLOWED_DATE) { 
     //not allowed to do this 
} 

Rõ ràng là Math.Min trên không làm việc bởi vì họ đang hẹn hò.

Trả lời

277

Không có tình trạng quá tải cho các giá trị DateTime, nhưng bạn có thể nhận được giá trị lâu Ticks đó là những gì các giá trị chứa, so sánh chúng và sau đó tạo ra một mới DateTime giá trị từ kết quả:.

new DateTime(Math.Min(Date1.Ticks, Date2.Ticks)) 

(Lưu ý rằng cấu trúc DateTime cũng chứa một tài sản Kind, mà không được giữ lại trong các giá trị mới này là bình thường không phải là một vấn đề, nếu bạn so sánh giá trị DateTime các loại khác nhau compa rison không có ý nghĩa nào.)

+2

Điều này dường như với tôi là gần nhất với một thay thế một dòng/tương đương cho Math.Min nhưng các câu trả lời khác cũng tuyệt vời, để hoàn thành – hawbsl

+3

-, bạn hoàn toàn mất tất cả thông tin (ngoại trừ các dấu tích) của 'System.DateTime' gốc -instance –

+1

@AndreasNiedermair: Thông tin duy nhất tồn tại trong giá trị 'DateTime' là thuộc tính' Ticks' và 'Kind'. Tất cả các thuộc tính khác đều bắt nguồn từ những thuộc tính đó. – Guffa

324

Không có phương thức tích hợp sẵn để thực hiện điều đó. Bạn có thể sử dụng cụm từ:

(date1 > date2 ? date1 : date2) 

để tìm tối đa hai.

Bạn có thể viết một phương pháp tổng quát để tính toán Min hoặc Max cho bất kỳ loại (với điều kiện là Comparer<T>.Default được thiết lập một cách thích hợp):

public static T Max<T>(T first, T second) { 
    if (Comparer<T>.Default.Compare(first, second) > 0) 
     return first; 
    return second; 
} 

Bạn có thể sử dụng LINQ quá:

new[]{date1, date2, date3}.Max() 
29

Làm thế nào về:

public static T Min<T>(params T[] values) 
{ 
    if (values == null) throw new ArgumentNullException("values"); 
    var comparer = Comparer<T>.Default; 
    switch(values.Length) { 
     case 0: throw new ArgumentException(); 
     case 1: return values[0]; 
     case 2: return comparer.Compare(values[0],values[1]) < 0 
       ? values[0] : values[1]; 
     default: 
      T best = values[0]; 
      for (int i = 1; i < values.Length; i++) 
      { 
       if (comparer.Compare(values[i], best) < 0) 
       { 
        best = values[i]; 
       } 
      } 
      return best; 
    }   
} 
// overload for the common "2" case... 
public static T Min<T>(T x, T y) 
{ 
    return Comparer<T>.Default.Compare(x, y) < 0 ? x : y; 
} 

Làm việc với bất kỳ công ty nào pe hỗ trợ IComparable<T> hoặc IComparable.

Trên thực tế, với LINQ, thay thế khác là:

var min = new[] {x,y,z}.Min(); 
+5

Vote cho ví dụ LINQ. –

-2
// Two different dates 
var date1 = new Date(2013, 05, 13); 
var date2 = new Date(2013, 04, 10) ; 
// convert both dates in milliseconds and use Math.min function 
var minDate = Math.min(date1.valueOf(), date2.valueOf()); 
// convert minDate to Date 
var date = new Date(minDate); 

http://jsfiddle.net/5CR37/

+0

Đề nghị tốt (thực sự), nhưng không có mô tả thật khó để tìm thấy lý do tại sao nó là tốt. Vui lòng mô tả vị trí của mẹo. Nếu không có mô tả nó chỉ là một khối mã và không phải là một câu trả lời. – Artemix

+2

câu hỏi được gắn thẻ .NET không Javascript – hawbsl

+0

Xin lỗi, không nhận thấy .NET. Dù sao, chúng tôi có thể tìm thấy ngày tối thiểu ở phía khách hàng và gửi nó đến máy chủ. –

14
public static class DateTool 
{ 
    public static DateTime Min(DateTime x, DateTime y) 
    { 
     return (x.ToUniversalTime() < y.ToUniversalTime()) ? x : y; 
    } 
    public static DateTime Max(DateTime x, DateTime y) 
    { 
     return (x.ToUniversalTime() > y.ToUniversalTime()) ? x : y; 
    } 
} 

Điều này cho phép ngày để có 'loại' khác nhau và trả về trường hợp đó đã được thông qua (không trả lại một DateTime mới được xây dựng từ Ticks hoặc mili giây).

[TestMethod()] 
    public void MinTest2() 
    { 
     DateTime x = new DateTime(2001, 1, 1, 1, 1, 2, DateTimeKind.Utc); 
     DateTime y = new DateTime(2001, 1, 1, 1, 1, 1, DateTimeKind.Local); 

     //Presumes Local TimeZone adjustment to UTC > 0 
     DateTime actual = DateTool.Min(x, y); 
     Assert.AreEqual(x, actual); 
    } 

Lưu ý rằng thử nghiệm này sẽ thất bại Đông Greenwich ...

6

Nếu bạn muốn gọi nó giống như Math.Max, bạn có thể làm một cái gì đó giống như cơ thể biểu hiện rất ngắn này:

public static DateTime Max(params DateTime[] dates) => dates.Max(); 
[...] 
var lastUpdatedTime = DateMath.Max(feedItemDateTime, assemblyUpdatedDateTime); 
+0

oh, đó là thiên tài! Bằng cách này tôi không phải so sánh mỗi lần, chỉ một lần sau khi tôi hoàn thành dữ liệu. Cảm ơn nhiều! – tfrascaroli

3

Linq.Min()/Linq.Max() cách tiếp cận:

DateTime date1 = new DateTime(2000,1,1); 
DateTime date2 = new DateTime(2001,1,1); 

DateTime minresult = new[] { date1,date2 }.Min(); 
DateTime maxresult = new[] { date1,date2 }.Max(); 
1

Bây giờ chúng ta có LINQ, bạn có thể tạo một mảng với hai giá trị của bạn (DateTimes, TimeSpans, bất cứ điều gì) và sau đó sử dụng phương thức mở rộng .Max().

var values = new[] { Date1, Date2 }; 
var max = values.Max(); 

Nó đẹp, hiệu quả như Max có thể và có thể sử dụng lại cho hơn 2 giá trị so sánh.

Toàn bộ vấn đề bên dưới đáng lo ngại về .Kind là một vấn đề lớn ... nhưng tôi tránh điều đó bằng cách không bao giờ làm việc trong giờ địa phương, bao giờ hết. Nếu tôi có một cái gì đó quan trọng liên quan đến thời gian, tôi luôn luôn làm việc trong UTC, ngay cả khi nó có nghĩa là nhiều công việc để đạt được điều đó.

0

Làm cách nào về phương thức mở rộng DateTime?

public static DateTime MaxOf(this DateTime instance, DateTime dateTime) 
{ 
    return instance > dateTime ? instance : dateTime; 
} 

Cách sử dụng:

var maxDate = date1.MaxOf(date2); 
Các vấn đề liên quan