Skip to content

Instantly share code, notes, and snippets.

@jamescrowley
Created November 27, 2013 14:20
Show Gist options
  • Save jamescrowley/7676415 to your computer and use it in GitHub Desktop.
Save jamescrowley/7676415 to your computer and use it in GitHub Desktop.
Clock for Testing/freezing time
public static class Clock
{
private static DateTime? _frozenTime;
/// <summary>
/// Gets a <see cref="DateTime"/> object that is set to the current date and time on this computer,
/// expressed as the local time.
/// </summary>
public static DateTime Now
{
get { return _frozenTime.HasValue ? _frozenTime.Value.ToLocalTime() : DateTime.Now; }
}
/// <summary>
/// Gets the current date.
/// </summary>
public static DateTime Today
{
get { return Now.Date; }
}
/// <summary>
/// Gets a <see cref="DateTime"/> object that is set to the current date and time on this computer,
/// expressed as the Coordinated Universal Time (UTC).
/// </summary>
public static DateTime UtcNow
{
get { return _frozenTime.HasValue ? _frozenTime.Value.ToUniversalTime() : DateTime.UtcNow; }
}
/// <summary>
/// Freezes the clock with the current time.
/// Until <see cref="Thaw()"/> is called, all calls to <see cref="Now"/>, <see cref="Today"/>, and
/// <see cref="UtcNow"/> will return the exact same values.
/// </summary>
public static DisposableClock Freeze()
{
return FreezeLocal(Clock.Now);
}
/// <summary>
/// Freezes the clock with the given date and time, considered to be local time.
/// Until <see cref="Thaw()"/> is called, all calls to <see cref="Now"/>, <see cref="Today"/>, and
/// <see cref="UtcNow"/> will return the exact same values.
/// </summary>
/// <param name="localDateTime">The local date and time to freeze to</param>
public static DisposableClock FreezeLocal(DateTime localDateTime)
{
if (_frozenTime.HasValue)
throw new InvalidOperationException("Clock is already frozen");
_frozenTime = DateTime.SpecifyKind(localDateTime, DateTimeKind.Local);
return new DisposableClock();
}
/// <summary>
/// Freezes the clock with the given date and time, considered to be Coordinated Universal Time (UTC).
/// Until <see cref="Thaw()"/> is called, all calls to <see cref="Now"/>, <see cref="Today"/>, and
/// <see cref="UtcNow"/> will return the exact same values.
/// </summary>
/// <param name="utcDateTime">The UTC date and time to freeze to</param>
public static DisposableClock FreezeUtc(DateTime utcDateTime)
{
_frozenTime = DateTime.SpecifyKind(utcDateTime, DateTimeKind.Utc);
return new DisposableClock();
}
/// <summary>
/// Thaws the clock so that <see cref="Now"/>, <see cref="Today"/>, and <see cref="UtcNow"/>
/// return normal values.
/// </summary>
public static void Thaw()
{
if (!_frozenTime.HasValue)
throw new InvalidOperationException("Clock is not frozen");
_frozenTime = null;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment