0

I am working on a WFA application that changes the computer date to a day ahead or a day behind, depending on the button click. Here is my code:

public Form1()
        {
            InitializeComponent();
            currentTime.Start();
        }

        private void CurrentTime_Tick(object sender, EventArgs e)
        {
            DateTime dateTime = DateTime.Now;
            this.lblTime.Text = dateTime.ToString();
        }

        public struct Systemtime
        {
            public short WDay;
        }

        [DllImport("kernel32.dll", SetLastError = true)]
        public static extern bool SetSystemTime([In] ref Systemtime st);

        private void BtnChangeDate_Click(object sender, EventArgs e)
        {
            Systemtime st = new Systemtime();

            st.WDay++;

            SetSystemTime(ref st);
        }

        private void BtnExit_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        private void BtnPreviousDay_Click(object sender, EventArgs e)
        {
            Systemtime st = new Systemtime();

            st.WDay--;

            SetSystemTime(ref st);
        }

The problem I have right now is the buttons do nothing, even if I have hard-coded values. What do I need to do to get this work correctly?

BowerdotJson
  • 55
  • 1
  • 9
  • This might help you: http://stackoverflow.com/questions/650849/change-system-date-programatically – Adam Jul 20 '15 at 16:53
  • @Adam - I tried this already and it does not work. It does with hard coding the days, but I want to the user to be able to move whatever day they want. – BowerdotJson Jul 20 '15 at 16:54
  • In case you have trouble finding documentation - [SYSTEMTIME structure](https://msdn.microsoft.com/en-us/library/windows/desktop/ms724950(v=vs.85).aspx) – crashmstr Jul 20 '15 at 17:15

2 Answers2

2

You need to correctly set up your Systemtime structure before you call the SetSystemTime function, it's not sufficient to just set the WDay value. I'd create a method to do both ways like below. Note that I use the built in methods to get the date and add/subtract the correct number of days. This handles all situations such as start/end of months/years.

private void ChangeDate(int numDays)
{
    Systemtime st = new Systemtime();

    var newDate = DateTime.Now.AddDays(numDays);

    //Set up all the values, no need to set wDayOfWeek as it's ignored by the set function
    st.wYear = newDate.Year;
    st.wMonth = newDate.Month;
    st.wDay = newDate.Day;
    st.wHour = newDate.Hour;
    st.wMinute = newDate.Minute;
    st.wSecond = newDate.Second;
    st.wMilliseconds = newDate.Millisecond;

    SetSystemTime(ref st);
}

Now you call it like this:

//Forward 1 day
ChangeDate(1);

//Back 1 day
ChangeDate(-1);
DavidG
  • 113,891
  • 12
  • 217
  • 223
  • Alright so I have been debugging your method and it is changing the dates correctly in the program but not on my machine. It also creates an infinite loop in my CurrentTime_Tick method, so I'm thinking that's where the problem lies. – BowerdotJson Jul 20 '15 at 18:05
0

Here is the solution.

public partial class Form1 : Form
{
    [DllImport("kernel32.dll")]
    static extern bool SetSystemTime([In] ref SYSTEMTIME st);

    public Form1()
    {
        InitializeComponent();
    }

    public struct SYSTEMTIME
    {
        public ushort wYear;
        public ushort wMonth;
        public ushort wDayOfWeek;
        public ushort wDay;
        public ushort wHour;
        public ushort wMinute;
        public ushort wSecond;
        public ushort wMilliseconds;
        public void FromDateTime(DateTime time)
        {
            wYear = (ushort)time.Year;
            wMonth = (ushort)time.Month;
            wDayOfWeek = (ushort)time.DayOfWeek;
            wDay = (ushort)time.Day;
            wHour = (ushort)time.Hour;
            wMinute = (ushort)time.Minute;
            wSecond = (ushort)time.Second;
            wMilliseconds = (ushort)time.Millisecond;
        }
        public DateTime ToDateTime()
        {
            return new DateTime(wYear, wMonth, wDay, wHour, wMinute, wSecond, wMilliseconds);
        }
        public static DateTime ToDateTime(SYSTEMTIME time)
        {
            return time.ToDateTime();
        }
    }

    private void BtnChangeDate_Click(object sender, EventArgs e)
    {
        ChangeDateUp(0);
    }

    private void BtnPreviousDay_Click(object sender, EventArgs e)
    {
        ChangeDateDown(0);
    }
    private void ChangeDateUp(int numDays)
    {            
        DateTime t = DateTime.Now.AddDays(1);
        SYSTEMTIME st = new SYSTEMTIME();
        st.FromDateTime(t);
        SetSystemTime(ref st);
    }

    private void ChangeDateDown(int numDays)
    {
        DateTime t = DateTime.Now.AddDays(-1);
        SYSTEMTIME st = new SYSTEMTIME();
        st.FromDateTime(t);
        SetSystemTime(ref st);
    }

    private void BtnExit_Click(object sender, EventArgs e)
    {
        this.Close();
    }
}
BowerdotJson
  • 55
  • 1
  • 9