Dates
April 3, 2026 ยท View on GitHub
By default dates and times (DateTime, DateTimeOffset, DateOnly, and TimeOnly) are sanitized during verification. This is done by finding each date and taking a counter based that that specific date. That counter is then used replace the date values. This allows for repeatable tests when date values are changing.
var dateTime = DateTime.Now;
var dateTimeOffset = DateTimeOffset.Now;
var target = new DateTimeTarget
{
DateTime = dateTime,
Date = new(dateTime.Year, dateTime.Month, dateTime.Day),
DateNullable = new(dateTime.Year, dateTime.Month, dateTime.Day),
DateString = new Date(dateTime.Year, dateTime.Month, dateTime.Day).ToString(),
DateTimeNullable = dateTime,
DateTimeString = dateTime.ToString("F"),
DateTimeOffset = dateTimeOffset,
DateTimeOffsetNullable = dateTimeOffset,
DateTimeOffsetString = dateTimeOffset.ToString("F")
};
await Verify(target);
Results in the following:
{
DateTime: DateTime_1,
DateTimeNullable: DateTime_1,
Date: Date_1,
DateNullable: Date_1,
DateTimeOffset: DateTimeOffset_1,
DateTimeOffsetNullable: DateTimeOffset_1,
DateTimeString: DateTimeOffset_2,
DateTimeOffsetString: DateTimeOffset_2,
DateString: Date_1
}
To disable this behavior use:
Instance
var target = new
{
Date = new DateTime(2020, 10, 10, 0, 0, 0, DateTimeKind.Utc)
};
var settings = new VerifySettings();
settings.DontScrubDateTimes();
return Verify(target, settings);
Fluent
var target = new
{
Date = new DateTime(2020, 10, 10, 0, 0, 0, DateTimeKind.Utc)
};
return Verify(target)
.DontScrubDateTimes();
Globally
[ModuleInitializer]
public static void ModuleInitializer() =>
VerifierSettings.DontScrubDateTimes();
DisableDateCounting
If many calls are made to the current date/time in quick succession, the date counting behavior (DateTime_x) can result in inconsistent results. To revert to the simpler scrubbing convention ({Scrubbed}) use DisableDateCounting.
Instance
var target = new
{
Date = new DateTime(2020, 10, 10, 0, 0, 0, DateTimeKind.Utc)
};
var settings = new VerifySettings();
settings.DisableDateCounting();
return Verify(target, settings);
Fluent
var target = new
{
Date = new DateTime(2020, 10, 10, 0, 0, 0, DateTimeKind.Utc)
};
return Verify(target)
.DisableDateCounting();
Globally
[ModuleInitializer]
public static void ModuleInitializer() =>
VerifierSettings.DisableDateCounting();
AddExtraDateTimeFormat
AddExtraDateTimeFormat allows specifying custom date formats to be scrubbed.
[ModuleInitializer]
public static void UseAddExtraDateTimeFormat() =>
VerifierSettings.AddExtraDateTimeFormat("yyyy-MM-dd");
[Fact]
public Task WithExtraDateTimeFormat() =>
Verify(
new
{
date = "2022-11-08"
});
Inline Dates
Strings containing inline dates can also be scrubbed. There a equivalent APIs for DateOnly, DateTime, and DateTimeOffset.
Instance
[Fact]
public Task ScrubInlineDateTimesInstance()
{
var settings = new VerifySettings();
settings.ScrubInlineDateTimes("yyyy-MM-dd");
return Verify(
"content 2020-10-20 content",
settings);
}
Fluent
[Fact]
public Task ScrubInlineDateTimesFluent() =>
Verify("content 2020-10-20 content")
.ScrubInlineDateTimes("yyyy-MM-dd");
Globally
public static class ModuleInitializer
{
[ModuleInitializer]
public static void Init() =>
VerifierSettings.ScrubInlineDateTimes("yyyy-MM-dd");
}
Named Date and Times
Specific date or times can be named. When any of those values are found, they will be matched with the corresponding name.
Instance
var settings = new VerifySettings();
settings.AddNamedDate(new(2020, 10, 11), "instanceNamedDate");
settings.AddNamedTime(new(1, 2), "instanceTime");
settings.AddNamedDateTime(new(2030, 1, 2), "instanceNamedDateTime");
settings.AddNamedDateTimeOffset(new DateTime(2030, 1, 2), "instanceNamedTimeOffset");
await Verify(target, settings);
Instance
await Verify(target)
.AddNamedDate(new(2020, 10, 11), "instanceNamedDate")
.AddNamedTime(new(1, 2), "instanceTime")
.AddNamedDateTime(new(2030, 1, 2), "instanceNamedDateTime")
.AddNamedDateTimeOffset(new DateTime(2030, 1, 2), "instanceNamedTimeOffset");
Globally
[ModuleInitializer]
public static void NamedDatesAndTimesGlobal()
{
VerifierSettings.AddNamedDateTime(new(2030, 1, 1), "namedDateTime");
VerifierSettings.AddNamedTime(new(1, 1), "namedTime");
VerifierSettings.AddNamedDate(new(2030, 1, 1), "namedDate");
VerifierSettings.AddNamedDateTimeOffset(new(new(2030, 1, 1)), "namedDateTimeOffset");
}
Inferred Name
The name can be inferred from the variable name by omitting the name argument:
[Fact]
public Task InferredNamedDateFluent()
{
var namedDate = new Date(1935, 10, 1);
return Verify(
new
{
value = namedDate
})
.AddNamedDate(namedDate);
}
Result:
{
value: namedDate
}
Custom Comparers
The following comparers can be overridden
DateTime
Default Comparer:
class DateTimeComparer : IEqualityComparer<DateTime>
{
public bool Equals(DateTime x, DateTime y) =>
x == y &&
x.Kind == y.Kind;
public int GetHashCode(DateTime obj) =>
obj.GetHashCode() + (int) obj.Kind;
}
Custom Comparer:
[ModuleInitializer]
public static void UseCustomDateTimeComparer() =>
Counter.UseDateTimeComparer(new CustomDateTimeComparer());
public class CustomDateTimeComparer :
IEqualityComparer<DateTime>
{
public bool Equals(DateTime x, DateTime y) =>
new DateTime(x.Year, x.Month, x.Day) ==
new DateTime(y.Year, y.Month, y.Day);
public int GetHashCode(DateTime date) =>
new DateTime(date.Year, date.Month, date.Day).GetHashCode();
}
DateTimeOffset
Default Comparer:
class DateTimeOffsetComparer :
IEqualityComparer<DateTimeOffset>
{
public bool Equals(DateTimeOffset x, DateTimeOffset y) =>
x == y && x.Offset == y.Offset;
public int GetHashCode(DateTimeOffset obj) =>
obj.GetHashCode() + (int) obj.Offset.TotalMinutes;
}
Custom Comparer:
[ModuleInitializer]
public static void UseCustomDateTimeOffsetComparer() =>
Counter.UseDateTimeOffsetComparer(new CustomDateTimeOffsetComparer());
public class CustomDateTimeOffsetComparer :
IEqualityComparer<DateTimeOffset>
{
public bool Equals(DateTimeOffset x, DateTimeOffset y) =>
new DateTimeOffset(new(x.Year, x.Month, x.Day)) ==
new DateTimeOffset(new(y.Year, y.Month, y.Day));
public int GetHashCode(DateTimeOffset date)
{
var dateTime = new DateTime(date.Year, date.Month, date.Day);
return new DateTimeOffset(dateTime)
.GetHashCode();
}
}
TimeOnly
Default Comparer:
EqualityComparer<Time>.Default;
Custom Comparer:
[ModuleInitializer]
public static void UseCustomTimeComparer() =>
Counter.UseTimeComparer(new CustomTimeComparer());
public class CustomTimeComparer :
IEqualityComparer<Time>
{
public bool Equals(Time x, Time y) =>
new Time(x.Hour, x.Minute, x.Second) ==
new Time(y.Hour, y.Minute, y.Second);
public int GetHashCode(Time date) =>
new Time(date.Hour, date.Minute, date.Second).GetHashCode();
}