Search
Module:
Directory

   Desktop Functions:

   Smart Device Functions:


Show Recent Changes
Subscribe (RSS)
Misc. Pages
Comments
FAQ
Helpful Tools
Playground
Suggested Reading
Website TODO List
Download Visual Studio Add-In

SystemTime (Structures)
 
.
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

Please edit this page!

Do you have...

  • helpful tips?
  • corrections to the existing content?
  • alternate definitions?
  • additional languages you want to include?

Select "Edit This Page" on the right hand toolbar and edit it! Or add new pages containing any supporting types needed.

 
Access PInvoke.net directly from VS:
Terms of Use
Edit This Page
Find References
Show Printable Version
Revisions