using System;
using System.Runtime.InteropServices;
namespace Wayne.Lib
{
///
/// System time structure for Win32.
///
[StructLayout(LayoutKind.Sequential)]
internal struct SystemTime
{
[MarshalAs(UnmanagedType.U2)]
public short Year;
[MarshalAs(UnmanagedType.U2)]
public short Month;
[MarshalAs(UnmanagedType.U2)]
public short DayOfWeek;
[MarshalAs(UnmanagedType.U2)]
public short Day;
[MarshalAs(UnmanagedType.U2)]
public short Hour;
[MarshalAs(UnmanagedType.U2)]
public short Minute;
[MarshalAs(UnmanagedType.U2)]
public short Second;
[MarshalAs(UnmanagedType.U2)]
public short Milliseconds;
}
///
/// System time proxy, should be used instead of DateTime.Now, and injected to the class,
/// so the current time can be mocked in unit tests.
///
/// Added routine to set system time, this seemed as good a place as any to put it. (JHC)
///
public class WayneSystemTime : ISystemTime
{
///
/// The current Date and time.
///
public DateTime Now
{
get { return DateTime.Now; }
set { SetSystemTime(value); }
}
[DllImport("kernel32.dll")]
static extern bool SetSystemTime(
ref SystemTime systemTime);
[DllImport("kernel32.dll")]
static extern bool SetLocalTime(
ref SystemTime systemTime);
///
/// Sets the system time
///
///
///
public void SetSystemTime(DateTime newTime)
{
SystemTime st = ConvertToSystemTime(newTime.ToUniversalTime());
bool rc = SetSystemTime(ref st);
if (!rc)
{
int wrc = Marshal.GetLastWin32Error();
throw new Exception("Error " + wrc + " setting system time");
}
}
///
/// Set local time
///
///
public void SetLocalTime(DateTime newTime)
{
// Microsoft.VisualBasic.DateAndTime.TimeOfDay = DateTime.SpecifyKind(newTime, DateTimeKind.Local);
SystemTime st = ConvertToSystemTime(newTime);
bool rc = SetLocalTime(ref st);
if (!rc)
{
int wrc = Marshal.GetLastWin32Error();
throw new Exception("Error " + wrc + " setting local time");
}
}
internal static SystemTime ConvertToSystemTime(DateTime t)
{
SystemTime st = new SystemTime();
st.Year = (short)t.Year;
st.Month = (short)t.Month;
st.Day = (short)t.Day;
st.Hour = (short)t.Hour;
st.Minute = (short)t.Minute;
st.Second = (short)t.Second;
return st;
}
}
}