这可能是一个愚蠢的问题,但我似乎无法弄明白。我正在比较两个文件的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;
}
提前致谢
答案 0 :(得分:82)
我建议你使用扩展方法:
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())
答案 1 :(得分:37)
创建一个新的DateTime值,并将毫秒组件设置为0:
dt = dt.AddMilliseconds(-dt.Millisecond);
答案 2 :(得分:35)
如果dt
非零微秒(毫秒的分数),则应该小心。仅将毫秒设置为零是不够的
要将millis和以下设置为零(并获得成功的比较),代码将为:
dt = dt.AddTicks(-dt.Ticks % TimeSpan.TicksPerSecond); // TimeSpan.TicksPerSecond=10000000
答案 3 :(得分:22)
TimeSpan difference = dtNew - dtOrig;
if (difference >= TimeSpan.FromSeconds(1))
{
...
}
答案 4 :(得分:12)
您可以减去它们,以获得TimeSpan
。
然后使用TimeSpan.totalSeconds()
答案 5 :(得分:6)
对于单个Truncate来说这是一种过度杀伤,但如果您有多种类型,可以使用下面的通用扩展方法执行此操作:
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
}
答案 6 :(得分:3)
一种方法是创建新日期,将年,月,日,小时,分钟,秒输入构造函数。或者,您可以单独比较每个值。
答案 7 :(得分:1)
以太将其他日期时间的毫秒设置为零,或者从另一个日期时间中减去一个日期,然后检查生成的时间跨度的TotalMinutes
属性。
答案 8 :(得分:1)
您可以创建一个扩展方法,将DateTime对象的毫秒设置为零
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;
答案 9 :(得分:1)
而不是通过创建新的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
}
}
我以answer by Dean Chalk为基础进行效果比较,结果如下:
CompareWith
比TrimMilliseconds
快一点
CompareWith
比日期不相等更快
我的性能测试(在Console项目中运行)
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();
}
答案 10 :(得分:1)
这是执行此操作的最简单方法。您可以根据需要控制precision
。
bool AreEqual(DateTime a, DateTime b, TimeSpan precision)
{
return Math.Abs((a - b).TotalMilliseconds) < precision.TotalMilliseconds;
}
用法非常不言自明
var _ = AreEqual(a, b, precision: TimeSpan.FromSeconds(1));
答案 11 :(得分:1)
您可以简单地将日期时间格式与您想要的格式一起使用,然后将其再次转换为日期时间,如下所示,
//compare file's dates
String format1 = @"yyyy-MM-dd HH:mm:ss"; // you also can avoid seconds if you want
public bool CompareByModifiedDate(string strOrigFile, string strDownloadedFile)
{
//.here we will use the format
DateTime dtOrig = Convert.ToDateTime(File.GetLastWriteTime(strOrigFile).ToString(format1));
DateTime dtNew = Convert.ToDateTime(File.GetLastWriteTime(strDownloadedFile).ToString(format1));
if (dtOrig == dtNew)
return true;
else
return false;
}
答案 12 :(得分:-1)
投射可排序的字符串并进行比较。简单而且运行良好。
return string.Compare(dtOrig.ToString("s"), dtNew.ToString("s"),
StringComparison.Ordinal) == 0;
答案 13 :(得分:-3)
截断时间最直接的方法是格式化它并解析你想要的单位:
var myDate = DateTime.Parse(DateTime.Now.ToString("MM/dd/yyyy hh:mm:ss"));
DOK的方法重写
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;
}
答案 14 :(得分:-6)
不知道为什么几乎所有程序员都需要额外的行来从具有bool表达式的函数返回bool值。
代替
if (dtOrig.ZeroMilliseconds() == dtNew.ZeroMilliseconds())
return true;
else
return false;
你可以随时使用
return dtOrig.ZeroMilliseconds() == dtNew.ZeroMilliseconds()
如果表达式为true,则返回true,否则返回false。