How to implement a scheduled "Run At" date/time?

Hi all

I need to implement functionality in my Windows service such that it executes on a given day at a given time. The service has been written in C#.

I need to read a day + time string from a app.config file, e.g.

    <add key="run.at.day.time" value="Thursday, 18:00" />

though I'm open to persuasion about the format of this.

I can't seem to get this to work. The following attempt fails if the day of the week in the app.config file is NOT today(!).

    string[] myFormats = {"dddd, HH:mm"};

    DateTime runAt = DateTime.ParseExact(
            MyConfig.Read("run.at.day.time"),
            myFormats,
            new CultureInfo("en-GB"),
            DateTimeStyles.AllowWhiteSpaces
            );

And is there a way to persuade the DateTime instance that, if the timestamp in the config file is PRIOR to now, that it should assume the timestamp means NEXT WEEK?

Thanks.
seandynanAsked:
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

x
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Bob LearnedCommented:
if (runat.Subtract(DateTime.Now).TotalDays < 0)
   runat = runat.AddDays(7);

Bob
seandynanAuthor Commented:
Thanks Bob - that'll probably solve my closing question.

Have you any strategy for implementing my general scheduling task, how to generate a DateTime given just a day and time? At the moment my feeble attempt above is throwing a FormatException if the day isn't today.
Bob LearnedCommented:
Generally it is acceptable practice to only ask 1 question at a time, in order for these questions to double as a knowledge base, but I am feeling generous this morning.

Can I see your feeble attempt, please?

Bob

Become a CompTIA Certified Healthcare IT Tech

This course will help prep you to earn the CompTIA Healthcare IT Technician certification showing that you have the knowledge and skills needed to succeed in installing, managing, and troubleshooting IT systems in medical and clinical settings.

seandynanAuthor Commented:
> but I am feeling generous this morning.

LOL...okay, well my burning question really is, given a string containing a day and a time, how can I get my hands on a DateTime instance that reflects the next occurrence of that day & time?

For example, if today's date was Sunday, 01 Jan 2006 and I offered up "Friday, 13:00" in my config file, how would I generate a DateTime instance that reflected Friday, 06 Jan 2006, 13:00:00 ?


> Can I see your feeble attempt, please?

In a nutshell:

    string[] myFormats = {"dddd, HH:mm"};

    DateTime runAt = DateTime.ParseExact(
            "Friday, 13:00",
            myFormats,
            new CultureInfo("en-GB"),
            DateTimeStyles.AllowWhiteSpaces | DateTimeStyles.AdjustToUniversal
            );

This throws a FormatException ("String was not recognized as a valid DateTime") if the day of the week is NOT today.

Presumably the DateTime constructors expect an actual indication of some kind of date somewhere, and I'm not going to get away with the simple, single-step construction I'm attempting :-(

Thanks.
Bob LearnedCommented:
Try this method instead:

  public static DateTime TimestampToDate(string timeStamp)
  {

    int pos = timeStamp.IndexOf(",");
    if (pos == -1)
    {
      throw new ArgumentException("Invalid format for timestamp");
    }

    string dayWeek = timeStamp.Substring(0, pos);
    string time = timeStamp.Substring(pos + 1).Trim();
    DayOfWeek weekDay = ((DayOfWeek)(Enum.Parse(typeof(DayOfWeek), dayWeek)));

    pos = time.IndexOf(":");
    if (pos == -1)
    {
      throw new ArgumentException("Invalid time format");
    }

    int hour = Convert.ToInt32(time.Substring(0, pos));
    int minute = Convert.ToInt32(time.Substring(pos + 1));
    DateTime dt = new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, hour, minute, 0);

    while (dt.DayOfWeek != weekDay)
    {
      dt = dt.AddDays(1);
    }

    return dt;

Bob

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
seandynanAuthor Commented:
Hey Bob, that works a treat. Many thanks.
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
C#

From novice to tech pro — start learning today.