好,提取日期的方法如下:
public DateTime ExtractDateTime(string log)
{
var regex = new Regex(@"\d{4}.\d{2}.\d{2} \d{2}.\d{2}.\d{2}.\d{4}");
var match = regex.Match(log);
return match.Success ? DateTime.ParseExact(match.Value, "yyyy.MM.dd hh:mm:ss:ffff", CultureInfo.InvariantCulture) : new DateTime();
}
日志文件如下:
“ 2018.07.26 10:33:05:0927:ECOM-请求新会话...成功(启动开始会话线程)”,
我创建了一个测试,以确保提取的DateTime
是正确的。测试方法如下:
[Test]
public void CanExtractDate()
{
// Assemble
var service = TroposContext.GivenServices();
var log = service.WhenCreateLog("ECOM - New Session Requested... Success (Start Session Thread Started)", 2018, 7, 26, 10, 33, 5, 927, out var actualDate);
// Act
var dateTime = service.LogValidator.ExtractDateTime(log);
var compare = dateTime.CompareTo(actualDate);
// Assert
compare.Should().Be(0);
}
它失败了,因为compare
实际上是-1。
方法WhenCreateLog
有一个out DateTime
参数,该参数由发送给该方法的参数创建。该方法如下所示:
public string WhenCreateLog(string log, int year, int month, int day, int hour, int minute, int second, int millisecond, out DateTime actualDate)
{
var request = $"{year}.{month.ToString().PadLeft(2, '0')}.{day.ToString().PadLeft(2, '0')} {hour.ToString().PadLeft(2, '0')}:{minute.ToString().PadLeft(2, '0')}:{second.ToString().PadLeft(2, '0')}:{millisecond.ToString().PadLeft(4, '0')}: {log}";
actualDate = new DateTime(year, month, day, hour, minute, second, millisecond);
return request;
}
因此,在检查两个日期时,我可以看到dateTime
变量的毫秒数等于92,而actualDate
为927。
actualDate
是正确的,dateTime
为什么显示不正确?
答案 0 :(得分:0)
我已经弄清楚了。看来new DateTime()
毫秒介于0到999之间。但是我的字符串使用的是4位数字。 DateTime.ParseExact
允许我拥有任何价值,因此我必须确保两种方法都使用相同的ParseExact
。因此,我将 LogValidator 方法更改为此:
public const string Format = "yyyy.MM.dd hh:mm:ss:ffff";
public DateTime ExtractDateTime(string log)
{
var regex = new Regex(@"\d{4}.\d{2}.\d{2} \d{2}.\d{2}.\d{2}.\d{4}");
var match = regex.Match(log);
return match.Success ? DateTime.ParseExact(match.Value, Format, null) : new DateTime();
}
然后将我的 WhenCreateLog 方法更改为:
public string WhenCreateLog(string log, int year, int month, int day, int hour, int minute, int second, int millisecond, out DateTime actualDate)
{
var dateString = $"{year}.{month.ToString().PadLeft(2, '0')}.{day.ToString().PadLeft(2, '0')} {hour.ToString().PadLeft(2, '0')}:{minute.ToString().PadLeft(2, '0')}:{second.ToString().PadLeft(2, '0')}:{millisecond.ToString().PadLeft(4, '0')}";
var request = $"{dateString}: {log}";
actualDate = DateTime.ParseExact(dateString, LogValidator.Format, null);
return request;
}
那行得通
答案 1 :(得分:0)
好吧,如果您想保留这四个位置,您可以将毫秒PadLeft
更改为PadRight
,这没关系。另一种选择是使用DateTime.ToString()
重载,只是更改语句的顺序:
选项1:
var dateString = $"{year}.{month.ToString().PadLeft(2, '0')}.{day.ToString().PadLeft(2, '0')} {hour.ToString().PadLeft(2, '0')}:{minute.ToString().PadLeft(2, '0')}:{second.ToString().PadLeft(2, '0')}:{millisecond.ToString().PadRight(4, '0')}";
选项2:
actualDate = new DateTime(year, month, day, hour, minute, second, millisecond);
var request = $"{actualDate.ToString("yyyy.MM.dd HH:mm:ss:ffff")}: {log}";
此外,您应该检查Date是否有效,并且最好使用静态Regex.Match而不是实例,因为静态方法会缓存模式以加快将来的使用:
public DateTime ExtractDateTime(string log)
{
string pattern = @"\d{4}.\d{2}.\d{2} \d{2}.\d{2}.\d{2}.\d{4}";
var match = Regex.Match(log, pattern);
DateTime parsedDate;
if(DateTime.TryParseExact(match.Value, "yyyy.MM.dd hh:mm:ss:ffff",System.Globalization.CultureInfo.InvariantCulture,System.Globalization.DateTimeStyles.None, out parsedDate))
{
return parsedDate;
}
return new DateTime();
}
public string WhenCreateLog(string log, int year, int month, int day, int hour, int minute, int second, int millisecond, out DateTime actualDate)
{
actualDate = new DateTime(year, month, day, hour, minute, second, millisecond);
var request = $"{actualDate.ToString("yyyy.MM.dd HH:mm:ss:ffff")}: {log}";
//Or
//var request = $"{year}.{month.ToString().PadLeft(2, '0')}.{day.ToString().PadLeft(2, '0')} {hour.ToString().PadLeft(2, '0')}:{minute.ToString().PadLeft(2, '0')}:{second.ToString().PadLeft(2, '0')}:{millisecond.ToString().PadRight(4, '0')}";
return request;
}