Nice programing

두 개의 날짜 시간을 비교할 때 밀리 초 무시

nicepro 2020. 11. 9. 20:56
반응형

두 개의 날짜 시간을 비교할 때 밀리 초 무시


이것은 아마도 어리석은 질문이지만 그것을 알아낼 수없는 것 같습니다. 두 파일의 LastWriteTime을 비교하고 있지만 인터넷에서 다운로드 한 파일에는 항상 밀리 초가 0으로 설정되어 있고 원본 파일에 실제 값이 있기 때문에 항상 실패합니다. 비교할 때 밀리 초를 무시하는 간단한 방법이 있습니까?

내 기능은 다음과 같습니다.

//compare file's dates
public bool CompareByModifiedDate(string strOrigFile, string strDownloadedFile)
{
     DateTime dtOrig = File.GetLastWriteTime(strOrigFile);
     DateTime dtNew = File.GetLastWriteTime(strDownloadedFile);

     if (dtOrig == dtNew)
        return true;
     else
        return false;
}

미리 감사드립니다


milliseconds 구성 요소를 0으로 설정하여 새 DateTime 값을 만듭니다.

dt = dt.AddMilliseconds(-dt.Millisecond);

확장 방법을 사용하는 것이 좋습니다.

public static DateTime TrimMilliseconds(this DateTime dt)
{
    return new DateTime(dt.Year, dt.Month, dt.Day, dt.Hour, dt.Minute, dt.Second, 0, dt.Kind);
}

그런 다음 그냥 :

if (dtOrig.TrimMilliseconds() == dtNew.TrimMilliseconds())

0dt아닌 마이크로 초 ( 밀리 초 단위) 가있는 경우주의해야합니다 . 밀리 초 만 0으로 설정하는 것만으로는 충분하지 않습니다.
millis 이하를 0으로 설정하고 성공적으로 비교하려면 코드는 다음과 같습니다.

dt = dt.AddTicks(-dt.Ticks % TimeSpan.TicksPerSecond); // TimeSpan.TicksPerSecond=10000000

TimeSpan difference = dtNew - dtOrig;
if (difference >= TimeSpan.FromSeconds(1))
{
    ...
}

이를 빼면 TimeSpan.

그런 다음 TimeSpan.totalSeconds()


이것은 단일 자르기에는 과잉이지만 여러 유형이있는 경우 아래 일반화 된 확장 방법을 사용하여이를 수행 할 수 있습니다.

DateTime dtSecs = DateTime.Now.TruncateTo(Extensions.DateTruncate.Second);
DateTime dtHrs  = DateTime.Now.TruncateTo(Extensions.DateTruncate.Hour);

더 일반적인 사용 확장 방법 :

    public static DateTime TruncateTo(this DateTime dt, DateTruncate TruncateTo)
    {
        if (TruncateTo == DateTruncate.Year)
            return new DateTime(dt.Year, 0, 0);
        else if (TruncateTo == DateTruncate.Month)
            return new DateTime(dt.Year, dt.Month, 0);
        else if (TruncateTo == DateTruncate.Day)
            return new DateTime(dt.Year, dt.Month, dt.Day);
        else if (TruncateTo == DateTruncate.Hour)
            return new DateTime(dt.Year, dt.Month, dt.Day, dt.Hour, 0, 0);
        else if (TruncateTo == DateTruncate.Minute)
            return new DateTime(dt.Year, dt.Month, dt.Day, dt.Hour, dt.Minute, 0);
        else 
            return new DateTime(dt.Year, dt.Month, dt.Day, dt.Hour, dt.Minute, dt.Second);

    }
    public enum DateTruncate
    {
        Year,
        Month,
        Day,
        Hour,
        Minute,
        Second
    }

한 가지 방법은 생성자에 연도, 월, 일,시, 분, 초를 입력하여 새 날짜를 만드는 것입니다. 또는 단순히 각 값을 개별적으로 비교할 수 있습니다.


Ether는 다른 날짜 시간의 밀리 초를 0으로 설정하거나 다른 날짜에서 하나의 날짜를 빼고 TotalMinutes결과 시간 범위 속성을 확인하십시오 .


DateTime 개체에 대해 밀리 초를 0으로 설정하는 확장 메서드를 만들 수 있습니다.

public static DateTime ZeroMilliseconds(this DateTime value) {
  return new DateTime(value.Year, value.Month, value.Day, 
    value.Hours, value.Minutes, value.Seconds);
}

그런 다음 귀하의 기능에서

 if (dtOrig.ZeroMilliseconds() == dtNew.ZeroMilliseconds())
        return true;
     else
        return false;

새로운 생성을 통해 관련 없는 DateTime 부분을 자르는 대신 관련 부분 DateTime만 비교하십시오 .

public static class Extensions
{
    public static bool CompareWith(this DateTime dt1, DateTime dt2)
    {
        return
            dt1.Second == dt2.Second && // 1 of 60 match chance
            dt1.Minute == dt2.Minute && // 1 of 60 chance
            dt1.Day == dt2.Day &&       // 1 of 28-31 chance
            dt1.Hour == dt2.Hour &&     // 1 of 24 chance
            dt1.Month == dt2.Month &&   // 1 of 12 chance
            dt1.Year == dt2.Year;       // depends on dataset
    }
}

I took answer by Dean Chalk as base for performance comparison, and results are:

  • CompareWith is a bit faster than TrimMilliseconds in case of equal dates

  • CompareWith is a faster than dates are not equal

my perf test (run in Console project)

static void Main(string[] args)
{
    var dtOrig = new DateTime(2018, 03, 1, 10, 10, 10);
    var dtNew = dtOrig.AddMilliseconds(100);

    //// perf run for not-equal dates comparison
    //dtNew = dtNew.AddDays(1);
    //dtNew = dtNew.AddMinutes(1);

    int N = 1000000;

    bool isEqual = false;

    var sw = Stopwatch.StartNew();
    for (int i = 0; i < N; i++)
    {
        // TrimMilliseconds comes from 
        // https://stackoverflow.com/a/7029046/1506454 
        // answer by Dean Chalk
        isEqual = dtOrig.TrimMilliseconds() == dtNew.TrimMilliseconds();
    }
    var ms = sw.ElapsedMilliseconds;
    Console.WriteLine("DateTime trim: " + ms + " ms");

    sw = Stopwatch.StartNew();
    for (int i = 0; i < N; i++)
    {
        isEqual = dtOrig.CompareWith(dtNew);
    }
    ms = sw.ElapsedMilliseconds;
    Console.WriteLine("DateTime partial compare: " + ms + " ms");

    Console.ReadKey();
}

Here is the simplest way of doing this. You can control precision as you want.

bool AreEqual(DateTime a, DateTime b, TimeSpan precision)
{
    return Math.Abs((a - b).TotalMilliseconds) < precision.TotalMilliseconds;
}

and usage is pretty self-explanatory

var _ = AreEqual(a, b, precision: TimeSpan.FromSeconds(1));

cast sortable strings and compare. simple and run well.

    return string.Compare(dtOrig.ToString("s"), dtNew.ToString("s"), 
StringComparison.Ordinal) == 0;

The most straightforward way to truncate time is to format it and parse on the units that you want:

var myDate = DateTime.Parse(DateTime.Now.ToString("MM/dd/yyyy hh:mm:ss"));

DOK's method re-written

public bool CompareByModifiedDate(string strOrigFile, string strDownloadedFile)
    {
         DateTime dtOrig = DateTime.Parse(File.GetLastWriteTime(strOrigFile).ToString("MM/dd/yyyy hh:mm:ss"));
         DateTime dtNew = DateTime.Parse(File.GetLastWriteTime(strDownloadedFile).ToString("MM/dd/yyyy hh:mm:ss"));

         if (dtOrig == dtNew)
            return true;
         else
            return false;
    }

Don't know why almost all programmers needs extra lines to return a bool value from a function with a bool expression.

instead

if (dtOrig.ZeroMilliseconds() == dtNew.ZeroMilliseconds())
    return true;
 else
    return false;

you can always just use

return dtOrig.ZeroMilliseconds() == dtNew.ZeroMilliseconds()

if the expression is true it returns true else false.

참고URL : https://stackoverflow.com/questions/7028930/ignore-milliseconds-when-comparing-two-datetimes

반응형