두 개의 날짜 시간을 비교할 때 밀리 초 무시
이것은 아마도 어리석은 질문이지만 그것을 알아낼 수없는 것 같습니다. 두 파일의 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 thanTrimMilliseconds
in case of equal datesCompareWith
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
'Nice programing' 카테고리의 다른 글
클래스가 키 값 코딩을 준수하지 않습니다. (0) | 2020.11.09 |
---|---|
특정 좌표 근처의 특정 장소를 검색하는 Google지도 URL을 형성합니다. (0) | 2020.11.09 |
UICollectionView에서 레이아웃을 동적으로 설정하면 설명 할 수없는 contentOffset 변경이 발생합니다. (0) | 2020.11.08 |
CMake target_include_directories 범위의 의미 (0) | 2020.11.08 |
jQuery : mousemove 이벤트 중 눌린 마우스 버튼 감지 (0) | 2020.11.08 |