SYSTEMTIME (Structures)
Last changed: -45.137.113.229

.
Summary
Represents a date and time using individual members for the month, day, year, weekday, hour, minute, second, and millisecond.

C# Definition:

[StructLayout(LayoutKind.Sequential)]
private 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;

  public SYSTEMTIME( DateTime dt )
  {
    dt = dt.ToUniversalTime();  // SetSystemTime expects the SYSTEMTIME in UTC
    Year = (short)dt.Year;
    Month = (short)dt.Month;
    DayOfWeek = (short)dt.DayOfWeek;
    Day = (short)dt.Day;
    Hour = (short)dt.Hour;
    Minute = (short)dt.Minute;
    Second = (short)dt.Second;
    Milliseconds = (short)dt.Millisecond;
  }
}

VB Definition:

<StructLayout(LayoutKind.Sequential)> _
Private Structure SYSTEMTIME
   <MarshalAs(UnmanagedType.U2)> Public Year As Short
   <MarshalAs(UnmanagedType.U2)> Public Month As Short
   <MarshalAs(UnmanagedType.U2)> Public DayOfWeek As Short
   <MarshalAs(UnmanagedType.U2)> Public Day As Short
   <MarshalAs(UnmanagedType.U2)> Public Hour As Short
   <MarshalAs(UnmanagedType.U2)> Public Minute As Short
   <MarshalAs(UnmanagedType.U2)> Public Second As Short
   <MarshalAs(UnmanagedType.U2)> Public Milliseconds As Short
End Structure

Notes:

Sometimes, when trying to transform this struct into a CLR DateTime, I noticed that the year is 1 year behind. I don't know why.

Tips & Tricks:

Please add some!

C# Sample Class:

[StructLayout(LayoutKind.Sequential, Pack=2)]
internal struct SystemTime
{
   public ushort Year;
   public ushort Month;
   public ushort DayOfWeek;
   public ushort Day;
   public ushort Hour;
   public ushort Minute;
   public ushort Second;
   public ushort Milliseconds;

   public SystemTime(DateTime dt)
   {
      dt = dt.ToUniversalTime();
      Year = Convert.ToUInt16(dt.Year);
      Month = Convert.ToUInt16(dt.Month);
      DayOfWeek = Convert.ToUInt16(dt.DayOfWeek);
      Day = Convert.ToUInt16(dt.Day);
      Hour = Convert.ToUInt16(dt.Hour);
      Minute = Convert.ToUInt16(dt.Minute);
      Second = Convert.ToUInt16(dt.Second);
      Milliseconds = Convert.ToUInt16(dt.Millisecond);
   }

   public SystemTime(ushort year, ushort month, ushort day, ushort hour = 0, ushort minute = 0, ushort second = 0, ushort millisecond = 0)
   {
      Year = year;
      Month = month;
      Day = day;
      Hour = hour;
      Minute = minute;
      Second = second;
      Milliseconds = millisecond;
      DayOfWeek = 0;
   }

   public static implicit operator DateTime(SystemTime st)
   {
      if (st.Year == 0 || st == MinValue)
     return DateTime.MinValue;
      if (st == MaxValue)
     return DateTime.MaxValue;
      return new DateTime(st.Year, st.Month, st.Day, st.Hour, st.Minute, st.Second, st.Milliseconds, DateTimeKind.Local);
   }

   public static bool operator ==(SystemTime s1, SystemTime s2)
   {
      return (s1.Year == s2.Year && s1.Month == s2.Month && s1.Day == s2.Day && s1.Hour == s2.Hour && s1.Minute == s2.Minute && s1.Second == s2.Second && s1.Milliseconds == s2.Milliseconds);
   }

   public static bool operator !=(SystemTime s1, SystemTime s2)
   {
      return !(s1 == s2);
   }

   public static readonly SystemTime MinValue, MaxValue;

   static SystemTime()
   {
      MinValue = new SystemTime(1601, 1, 1);
      MaxValue = new SystemTime(30827, 12, 31, 23, 59, 59, 999);
   }

   public override bool Equals(object obj)
   {
      if (obj is SystemTime)
     return ((SystemTime)obj) == this;
      return base.Equals(obj);
   }

   public override int GetHashCode()
   {
      return base.GetHashCode();
   }
}

C# Sample Class:

[Serializable ]

[StructLayout(LayoutKind.Explicit, Size = 16, CharSet = CharSet.Ansi)]

public sealed class SystemTime : object, IXmlSerializable

{

    #region Fields

    [FieldOffset(0)] private ushort wYear;

    [FieldOffset(2)] private ushort wMonth;

    [FieldOffset(4)] private ushort wDayOfWeek;

    [FieldOffset(6)] private ushort wDay;

    [FieldOffset(8)] private ushort wHour;

    [FieldOffset(10)] private ushort wMinute;

    [FieldOffset(12)] private ushort wSecond;

    [FieldOffset(14)] private ushort wMilliseconds;

    #endregion

    #region Properties

    public ushort Year
    {
    get => wYear;
    set
    {
        wYear = value > 1600 && value < 30828
        ? value
        : throw new ArgumentOutOfRangeException(nameof(Year), value, null);
        int daysInMonth = GetDaysInMonth(wMonth, wYear);
        if (wDay > daysInMonth) wDay = (ushort) daysInMonth;
        wDayOfWeek = (ushort)GetDayOfWeek(wDay, wMonth, wYear);
    }
    }

    public ushort Month
    {
    get => wMonth;
    set
    {
        wMonth = value > 0 && value < 13
        ? value
        : throw new ArgumentOutOfRangeException(nameof(Month), value, null);
        int daysInMonth = GetDaysInMonth(wMonth, wYear);
        if (wDay > daysInMonth) wDay = (ushort) daysInMonth;
        wDayOfWeek = (ushort)GetDayOfWeek(wDay, wMonth, wYear);
    }
    }

    public ushort Day
    {
    get => wDay;
    set
    {
        wDay = value > 0 && value <= GetDaysInMonth(wMonth, wYear)
        ? value
        : throw new ArgumentOutOfRangeException(nameof(Day), value, null);
        wDayOfWeek = (ushort)GetDayOfWeek(wDay, wMonth, wYear);
    }
    }

    public DayOfWeek DayOfWeek
    {
    get => (DayOfWeek)wDayOfWeek;
    }

    public ushort Hour
    {
    get => wHour;
    set => wHour = value < 24 ? value
        : throw new ArgumentOutOfRangeException(nameof(Hour), value, null);
    }

    public ushort Minute
    {
    get => wMinute;
    set => wMinute = value < 60 ? value
        : throw new ArgumentOutOfRangeException(nameof(Minute), value, null);
    }

    public ushort Second
    {
    get => wSecond;
    set => wSecond = value < 60 ? value
        : throw new ArgumentOutOfRangeException(nameof(Second), value, null);
    }

    public ushort Milliseconds
    {
    get => wMilliseconds;
    set => wMilliseconds = value < 1000 ? value
        : throw new ArgumentOutOfRangeException(nameof(Milliseconds), value, null);
    }

    #endregion

    #region Constructor

    public SystemTime()
    {
    wYear = 1601;
    wMonth = 1;
    wDay = 1;
    wDayOfWeek = (ushort) GetDayOfWeek(wDay, wMonth, wYear);
    wHour = 0;
    wMinute = 0;
    wSecond = 0;
    wMilliseconds = 0;
    }

    public SystemTime(long fileTime)
    {
    FileTimeToSystemTimeNative(fileTime, this);
    }

    public SystemTime(DateTime dateTime)
    {
    long fileTime = dateTime.ToFileTimeUtc();
    SystemTime systemTime = new SystemTime();
    FileTimeToSystemTimeNative(fileTime, systemTime);
    }

    #endregion

    #region Win32 imports

    [DllImport("kernel32.dll", EntryPoint = "GetSystemTime", SetLastError = true)]
    private static extern void GetSystemTimeNative([Out, MarshalAs(UnmanagedType.Struct)]
    SystemTime systemTime);

    [DllImport("kernel32.dll", EntryPoint = "SetLocalTime", SetLastError = true)]
    [return: MarshalAs(UnmanagedType.Bool)]
    private static extern bool SetLocalTimeNative([In, MarshalAs(UnmanagedType.Struct)]
    SystemTime systemTime);

    [DllImport("kernel32.dll", EntryPoint = "SetSystemTime", SetLastError = true)]
    [return: MarshalAs(UnmanagedType.Bool)]
    private static extern bool SetSystemTimeNative([In, MarshalAs(UnmanagedType.Struct)]
    SystemTime systemTime);

    [DllImport("kernel32.dll", EntryPoint = "GetLocalTime", SetLastError = true)]
    private static extern void GetLocalTimeNative([Out, MarshalAs(UnmanagedType.Struct)]
    SystemTime systemTime);

    [DllImport("kernel32.dll", EntryPoint = "FileTimeToSystemTime", SetLastError = true)]
    [return: MarshalAs(UnmanagedType.Bool)]
    private static extern bool FileTimeToSystemTimeNative([In, MarshalAs(UnmanagedType.I8)] long fileTime,
    [Out, MarshalAs(UnmanagedType.Struct)]
    SystemTime systemTime);

    [DllImport("kernel32.dll", EntryPoint = "SystemTimeToFileTime", SetLastError = true)]
    [return: MarshalAs(UnmanagedType.Bool)]
    private static extern bool SystemTimeToFileTimeNative([In, MarshalAs(UnmanagedType.Struct)]
    SystemTime systemTime,
    [Out, MarshalAs(UnmanagedType.I8)] out long fileTime);

    [DllImport("kernel32.dll", EntryPoint = "GetTickCount", SetLastError = true)]
    [return: MarshalAs(UnmanagedType.U4)]
    private static extern ulong GetTickCountNative();

    [DllImport("kernel32.dll", EntryPoint = "GetTickCount64", SetLastError = true)]
    [return: MarshalAs(UnmanagedType.U8)]
    private static extern ulong GetTickCount64Native();

    [DllImport("kernel32.dll", EntryPoint = "GetSystemTimeAdjustment", SetLastError = true)]
    [return: MarshalAs(UnmanagedType.Bool)]
    private static extern bool GetSystemTimeAdjustmentNative(
    [Out, MarshalAs(UnmanagedType.U4)] out ulong lpTimeAdjustment,
    [Out, MarshalAs(UnmanagedType.U4)] out ulong lpTimeIncrement,
    [Out, MarshalAs(UnmanagedType.Bool)] out bool lpTimeAdjustmentDisabled);

    [DllImport("kernel32.dll", EntryPoint = "SetSystemTimeAdjustment", SetLastError = true)]
    [return: MarshalAs(UnmanagedType.Bool)]
    private static extern bool SetSystemTimeAdjustmentNative(
    [In, MarshalAs(UnmanagedType.U4)] ulong dwTimeAdjustment,
    [In, MarshalAs(UnmanagedType.Bool)] bool bTimeAdjustmentDisabled);

    #endregion

    #region Methods

    private static bool CheckIsLeapYear(int year)
    {
    return year % 4 == 0 && year % 100 != 0 || year % 400 == 0;
    }

    private int GetDaysInMonth(int month, int year)
    {
    return month == 2 && (year % 4 == 0 && year % 100 != 0 || year % 400 == 0) ? 29 : 28 + ((62648012 >> (month * 2)) & 3);
    }

    private static int GetDayOfWeek(int day, int month, int year)
    {
    int a = (14 - month) / 12;
    int y = year - a;
    int m = month + 12 * a - 2;
    return ((7000 + (day + y + y / 4 - y / 100 + y / 400 + (31 * m) / 12)) % 7);
    }

    public long ToFileTime()
    {
    return SystemTimeToFileTimeNative(this, out long fileTime) ? fileTime : 0L;
    }

    public DateTime ToDateTime()
    {
    return SystemTimeToFileTimeNative(this, out long fileTime)
        ? DateTime.FromFileTimeUtc(fileTime)
        : DateTime.MinValue;
    }

    public double ToUnixTime()
    {
    SystemTimeToFileTimeNative(this, out long fileTime);
    long seconds = fileTime / 10000000;
    double unixTime = seconds - 11644473600;
    return Math.Round(unixTime, 2);
    }

    public static SystemTime FromFileTime(long fileTime)
    {
    SystemTime systemTime = new SystemTime();
    FileTimeToSystemTimeNative(fileTime, systemTime);
    return systemTime;
    }

    public static SystemTime FromDateTime(DateTime dateTime)
    {
    long fileTime = dateTime.ToFileTimeUtc();
    SystemTime systemTime = new SystemTime();
    FileTimeToSystemTimeNative(fileTime, systemTime);
    return systemTime;
    }

    public static SystemTime FromUnixTime(double unixTime)
    {
    SystemTime systemTime = new SystemTime();
    long seconds = Convert.ToInt64(Math.Floor(unixTime + 11644473600));
    long fileTime = seconds * 10000000;
    FileTimeToSystemTimeNative(fileTime, systemTime);
    return systemTime;
    }

    public static bool SetLocalTime(SystemTime systemTime)
    {
    return systemTime != null && SetLocalTimeNative(systemTime);
    }

    public static bool SetLocalTime(DateTime dateTime)
    {
    var systemTime = FromDateTime(dateTime);
    return systemTime != null && SetLocalTimeNative(systemTime);
    }

    public static bool SetSystemTime(SystemTime systemTime)
    {
    return systemTime != null && SetSystemTimeNative(systemTime);
    }

    public static bool SetSystemTime(DateTime dateTime)
    {
    var systemTime = FromDateTime(dateTime);
    return systemTime != null && SetSystemTimeNative(systemTime);
    }

    public static SystemTime GetSystemTime()
    {
    SystemTime systemTime = new SystemTime();
    GetSystemTimeNative(systemTime);
    return systemTime;
    }

    public static SystemTime GetLocalTime()
    {
    SystemTime systemTime = new SystemTime();
    GetLocalTimeNative(systemTime);
    return systemTime;
    }

    public XmlSchema GetSchema()
    {
    return null;
    }

    public void ReadXml(XmlReader reader)
    {
    long fileTime = reader.ReadContentAsLong();
    FileTimeToSystemTimeNative(fileTime, this);
    }

    public void WriteXml(XmlWriter writer)
    {
    SystemTimeToFileTimeNative(this, out long fileTime);
    writer.WriteValue(fileTime);
    }

    public override bool Equals(object obj)
    {
    return ReferenceEquals(this, obj)
           || obj is SystemTime systemTime && this == systemTime
           || obj is long fileTime && ToFileTime() == fileTime
           || obj is DateTime dt && ToDateTime() == dt;
    }

    public override int GetHashCode()
    {
    return ToFileTime().GetHashCode();
    }

    public override string ToString()
    {
    return ToDateTime().ToString(CultureInfo.CurrentCulture);
    }

    public string ToString(IFormatProvider provider)
    {
    return ToDateTime().ToString(provider);
    }

    public string ToString(string format)
    {
    return ToDateTime().ToString(format);
    }

    public string ToString(string format, IFormatProvider provider)
    {
    return ToDateTime().ToString(format, provider);
    }

    #endregion

    #region Operators

    public static explicit operator DateTime(SystemTime systemTime)
    {
    return systemTime.ToDateTime();
    }

    public static explicit operator SystemTime(DateTime dateTime)
    {
    return FromDateTime(dateTime);
    }

    public static explicit operator long(SystemTime systemTime)
    {
    return systemTime.ToFileTime();
    }

    public static explicit operator SystemTime(long fileTime)
    {
    return FromFileTime(fileTime);
    }

    public static explicit operator double(SystemTime systemTime)
    {
    return systemTime.ToUnixTime();
    }

    public static explicit operator SystemTime(double unixTime)
    {
    return FromUnixTime(unixTime);
    }

    public static SystemTime operator +(SystemTime origin, long interval)
    {
    return FromFileTime(origin.ToFileTime() + interval);
    }

    public static SystemTime operator +(SystemTime origin, TimeSpan interval)
    {
    return FromDateTime(origin.ToDateTime() + interval);
    }

    public static long operator -(SystemTime left, SystemTime right)
    {
    return left.ToFileTime() - right.ToFileTime();
    }

    public static SystemTime operator -(SystemTime origin, long interval)
    {
    return FromFileTime(origin.ToFileTime() - interval);
    }

    public static SystemTime operator -(SystemTime origin, TimeSpan interval)
    {
    return FromDateTime(origin.ToDateTime() - interval);
    }

    public static bool operator >(SystemTime left, SystemTime right)
    {
    return left.ToFileTime() > right.ToFileTime();
    }

    public static bool operator <(SystemTime left, SystemTime right)
    {
    return left.ToFileTime() < right.ToFileTime();
    }

    public static bool operator >=(SystemTime left, SystemTime right)
    {
    return left.ToFileTime() >= right.ToFileTime();
    }

    public static bool operator <=(SystemTime left, SystemTime right)
    {
    return left.ToFileTime() <= right.ToFileTime();
    }

    public static bool operator ==(SystemTime left, SystemTime right)
    {
    return left == null && right == null || left?.ToFileTime() == right?.ToFileTime();
    }

    public static bool operator !=(SystemTime left, SystemTime right)
    {
    return left == null ^ right == null || left?.ToFileTime() != right?.ToFileTime();
    }

    #endregion

}

Documentation
SYSTEMTIME on MSDN