날짜에 대한 Math.Min 및 Math.Max에 해당합니까?


369

두 날짜 사이에 최소 (또는 최대) 값을 얻는 가장 빠르고 쉬운 방법은 무엇입니까? 날짜에 대해 Math.Min (& Math.Max)에 해당합니까?

나는 다음과 같은 것을하고 싶다 :

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

분명히 위의 Math.Min은 날짜이므로 작동하지 않습니다.

답변:


416

DateTime 값에는 과부하가 없지만 Ticks값에 포함 된 긴 값 을 가져 와서 비교 한 다음 결과에서 새 DateTime 값을 만들 수 있습니다.

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

DateTime 구조에는 Kind새 값으로 유지되지 않는 속성 도 포함되어 있습니다 . 이것은 일반적으로 문제가되지 않습니다. 다른 종류의 DateTime 값을 비교하면 어쨌든 의미가 없습니다.


2
이 Math.Min에 대한 한 줄 교체 / 상당에 가장 가까운 그러나이 될 나에게 듯 다른 답변했다 큰도 완전성
hawbsl

6
- 당신은 완전히 원래의 (눈금 제외) 모든 정보 느슨한 System.DateTime-instance
안드레아스 Niedermair

9
@AndreasNiedermair : 다른 종류의 날짜를 비교하는 경우 어쨌든 직접 비교할 수는 없습니다. 나는 이미 답변에서 이것을 다루었 다.
Guffa

4
@Iain : 당신은 항상 를 비교,하지만 당신은 비교할 수 없습니다 값을 비교하면, 결과는 쓸모가 없다. 킬로미터 거리를 마일 거리와 비교하는 것과 같이 비교할 수없는 다른 값과 동일합니다. 값을 잘 비교할 수 있지만 아무 의미가 없습니다.
Guffa

4
종류에 대해 손으로 wav을 때 -1. @ user450의 답변에 표시된 것처럼 두 시간을 UTC로 변환하고 정보를 버리지 않고 안전하게 비교하는 것은 매우 쉽습니다.
piedar

484

이를 수행 할 수있는 내장 된 방법이 없습니다. 다음 표현식을 사용할 수 있습니다.

(date1 > date2 ? date1 : date2)

둘 중 최대 값을 찾습니다.

계산 Min하거나 Max모든 유형 ( Comparer<T>.Default적절하게 설정되어있는 경우)에 대한 일반적인 방법을 작성할 수 있습니다 .

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

LINQ도 사용할 수 있습니다 :

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

15
이것은 실제로 받아 들여질만한 답입니다.
Larry

38

어때요 :

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;
}

지원하는 모든 유형의 작동 IComparable<T>또는 IComparable.

실제로 LINQ의 또 다른 대안은 다음과 같습니다.

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

6
LINQ 예제에 투표하십시오.
Oundless

20
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;
    }
}

이렇게하면 날짜가 다른 '종류'를 가질 수 있으며 전달 된 인스턴스를 반환합니다 (Ticks 또는 밀리 초로 구성된 새 DateTime을 반환하지 않음).

[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);
    }

이 테스트는 그리니치 동부에서 실패합니다 ...


왜 ToUniversalTime () 부분을 삭제하지 않습니까?
David Thielen

18

Linq.Min()/ Linq.Max()방법 :

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(); 

17

Math.Max와 같이 더 많이 호출하려면 다음과 같이 매우 짧은 표현식 본문과 같이 할 수 있습니다.

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

오 천재 야! 이렇게하면 매번 비교할 필요가 없습니다. 데이터를 다 사용한 후에 한 번만하십시오. 대단히 감사합니다!
tfrascaroli

이것은 매우 우아한 솔루션입니다
pberggreen

2

방법에 대한 DateTime확장 방법은?

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

용법:

var maxDate = date1.MaxOf(date2);

나는로 사용하는 것을 선호 DateTime.MaxOf(dt1, dt2)하지만 어떻게해야할지 모르겠다.
Zach Smith

@ZachSmith DateTime 클래스는 부분이 아니기 때문에 오버로드 할 수 없습니다. 어쩌면 우리는 DateTimeHelper.Max (DT1, DT2)를 사용할 수 있습니다
shtse8

@ shtse8-과부하로 무엇을 의미합니까? 확장 방법을 추가하려고 생각했습니다. 인스턴스화 된 인스턴스가 없으면 수행 할 수 없다는 것을 알게되었습니다. 확장 방법을 추가하는 것이 과부하의 한 형태라고 말하는 것 같습니까? 나는 그것을 고려한 적이 없다 .. 맞습니까? 이제 제가 생각하기에 ... 과부하가 정확히 무엇을 의미합니까?
Zach Smith

@ZachSmith Oh, DateTime 정적 멤버를 기반으로하는 "DateTime.Now"와 같이 "DateTime.MaxOf (dt1, dt2)"라는 확장을 추가한다고 생각했습니다.
shtse8

-2

이제 LINQ가 있으므로 두 값 (DateTimes, TimeSpans 등)으로 배열을 만든 다음 .Max () 확장 메서드를 사용할 수 있습니다.

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

잘 읽히고 Max만큼 효율적이며 2 개 이상의 비교 값에 재사용 할 수 있습니다.

.Kind에 대해 걱정하는 아래의 모든 문제는 큰 문제입니다 ... 그러나 나는 결코 현지 시간에 일하지 않아서 그것을 피합니다. 시간과 관련하여 중요한 점이 있으면 더 많은 작업이 필요하더라도 항상 UTC로 작업합니다.


1
내 답변의 사본
Toshi

-3
// 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/


좋은 제안 (실제로)이지만 설명이 없으면 왜 좋은지 찾기가 어렵습니다. 트릭이 어디에 있는지 설명하십시오. 설명이 없으면 코드 블록 일 뿐이며 대답은 아닙니다.
Artemix

3
질문은 태그가 없습니다 .NET Javascript
hawbsl

죄송합니다. .NET을 눈치 채지 못했습니다. 어쨌든 클라이언트 측에서 최소 날짜를 찾아서 서버로 보낼 수 있습니다.
Sergey Suvorov

4
당신은 우리가 ASP에 대해 이야기하고 있다고 가정합니다. 훨씬 더 위험 (자바 스크립트 비활성화)을이 있기 때문에 또한 불필요한 트래픽을 생성하는 것하고있을 것 (네트워크 속도에 따라) 느린, 클라이언트에 차이를 calcluate하는 것은 매우 어리석은 것
jalgames
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.