RunUO Community

This is a sample guest message. Register a free account today to become a member! Once signed in, you'll be able to participate on this site by adding your own topics and posts, as well as connect with other members through your own private inbox!

Getting a Specific DateTime

kevin10

Sorceror
I want a certain action to only happen at a certain of day. How would I format DateTime to make this happen, say for example, 8pm?
 

Mortis

Knight
I added SendMessage just for testing.
As you can see you can use seperatly or combine what you need or all.

I had wrong hour and minute as I was testing it on another hour and another minute.
If it was 8:20 they would be right.

Code:
        if ( DateTime.Now.Month == 8 &&  DateTime.Now.Day == 20 && DateTime.Now.Hour != 8 && DateTime.Now.Minute != 20)
        {

            m.SendMessage("Wrong Month, Day, Hour, or minute");

        }

Code:
        if ( DateTime.Now.Month == 8 )
        {

            m.SendMessage("Right Month");

        }

Code:
        if (  DateTime.Now.Day == 20 )
        {

            m.SendMessage("Right  Day");

        }

Code:
        if ( DateTime.Now.Hour != 8 )
        {

            m.SendMessage("Wrong Hour");

        }

Code:
        if ( DateTime.Now.Minute != 20)
        {

            m.SendMessage("Wrong Minute");

        }
 

Amazonia

Sorceror
There certainly has to be a way though. :/ It could be very helpful for shards who could have something automated going on at every 8pm.
 

Mortis

Knight
You can still use a 24 hour format.
Say for 8 PM

Code:
        if ( DateTime.Now.Hour != 20 )
        {

            m.SendMessage("Wrong Hour");

        }
 

Talow

Sorceror
If you are interested in more info you can get out the gettime from the server.items.clock It is used in the misc/lightcycles.cs to control the light at whatever time.
 

Vorspire

Knight
This might help :p

Rich (BB code):
	public class Scheduler : Timer
	{
		public delegate void ScheduleHandler();

		private DateTime _When;
		public DateTime When { get { return _When; } }

		private TimeSpan _Interval = TimeSpan.FromDays(1.0);
		public TimeSpan Interval { get { return _Interval; } }

		private int _InternalCounter = 0;
		private int _Count = 0;
		public int Count { get { return _Count; } }

		private ScheduleHandler _Handler;
		public ScheduleHandler Handler { get { return _Handler; } }

		public Scheduler(DateTime when, ScheduleHandler handler)
			: this(when, TimeSpan.Zero, handler)
		{ }

		public Scheduler(DateTime when, TimeSpan interval, ScheduleHandler handler)
			: this(when, interval, 0, handler)
		{ }

		public Scheduler(DateTime when, TimeSpan interval, int count, ScheduleHandler handler)
			: base(TimeSpan.Zero, TimeSpan.FromMinutes(1.0), count)
		{
			Update(when.Year, when.Month, when.Day, when.Hour, when.Minute);
			Update(interval);
			Update(count);
			Update(handler);
		}

		public void Update(int year, int month, int day, int hour, int minute)
		{
			if (year < DateTime.Now.Year)
			{ year = DateTime.Now.Year; }

			if (year > 9999)
			{ year = 9999; }

			if (month < 0)
			{ month = 0; }

			if (month > 11)
			{ month = 11; }

			if (day < 0)
			{ day = 0; }

			if (day > 31)
			{ day = 31; }

			if (hour < 0)
			{ hour = 0; }

			if (hour > 23)
			{ hour = 23; }

			if (minute < 0)
			{ minute = 0; }

			if (minute > 59)
			{ minute = 59; }

			_When = new DateTime(year, month, day, hour, minute, 0);
		}

		public void Update(TimeSpan interval)
		{
			if (interval.TotalMinutes < 1.0)
			{ interval = TimeSpan.FromMinutes(1.0); }

			_Interval = interval;
		}

		public void Update(int count)
		{
			if (count < 0)
			{ count = 0; }

			_InternalCounter = 0;
			_Count = count;
		}

		public void Update(ScheduleHandler handler)
		{
			if (handler == null)
			{ return; }

			_Handler = handler;
		}

		public bool CheckHandle(DateTime now)
		{
			DateTime schedule = new DateTime(_When.Year, _When.Month, _When.Day, _When.Hour, _When.Minute, now.Second, now.Millisecond);

			if (schedule == now)
			{ return true; }

			return false;
		}

		protected override void OnTick()
		{
			base.OnTick();

			DateTime now = DateTime.Now;

			if (CheckHandle(now))
			{
				_Handler.Invoke();
				_InternalCounter++;

				if (CanRepeat())
				{
					_When = _When.Add(_Interval);

					if (!Running)
					{ Start(); }
				}
			}
		}

		public virtual bool CanRepeat()
		{ return (_Interval.TotalMinutes >= 1.0 && _Count == 0 || _InternalCounter < _Count); }

		public override string ToString()
		{ return String.Format("{0:D4}:{1:D2}:{2:D2}:{3:D2}:{4:D2}", _When.Year, _When.Month, _When.Day, _When.Hour, _When.Minute); }
	}

Example:
Code:
private Scheduler _Schedule = new Scheduler( DateTime.Now, TimeSpan.FromMinutes(10.0), new ScheduleHandler( DoSomething ) );

public void DoSomething()
{
    /*DoSomething every 10 minutes, or whatever time you specified.*/
}
 

Amazonia

Sorceror
Okay I have an idea based on logic, but coding wise, up to you.. why just not set a specific datetime, like... August 23, 2011 8pm!
Setted up the same way as "LastStrGain".
Then, once it is 24 hours later than that specific date, it starts the event or whatever, and it also RESET the "LastEvenDate" (or w/e) to the current date time,
just the same way as housing decays... even if you crash/save or whatever, its all about datetime so that wont change anything whether its been closed or not.

EDIT: Mistake in that logic... if you close for a month and come back, the event would start right away and the date would completely change... So lets say the "LastEvenDate" is FIX! IT NEVER CHANGES! Like it substracts TimeSpan.FromDays on both sides (both current and fix time), then it only keeps the hours... and... if time equals that, then it works.
 

Vorspire

Knight
EDIT: Mistake in that logic... if you close for a month and come back, the event would start right away and the date would completely change... So lets say the "LastEvenDate" is FIX! IT NEVER CHANGES! Like it substracts TimeSpan.FromDays on both sides (both current and fix time), then it only keeps the hours... and... if time equals that, then it works.

You wouldn't have to make the "LastEventDate" a constant value, you could just save/load (serialize) it along with world save if you know how to construct your own GenericWriter reference object :)
Serialization is a fundamental part of all of my larger projects, the need to retain data for when any application is down is a must imho.

Also, if you use that Scheduler class I posted above, you don't have to construct it with DateTime.Now, you can set it to any date, right down to the minute (check the constructors) - You can construct it with a previously loaded DateTime value or you can give it a constant.

For example, if I wanted to set myself a birthday alert, I would use the following:
Rich (BB code):
//Norify for: 05-Jan-2011 @ 10:30 AM
private static Scheduler _Scheduler = new Scheduler( DateTime.Now.Year, 1, 5, 10, 30, new ScheduleHandler( Notify ) );
public static Scheduler Schedule { get { return _Schedule; } }

private static PlayerMobile _Mobile = <set by constructor>;
public static PlayerMobile Mobile { get { return _Mobile; } }

public static void Notify()
{
    _Mobile.SendMessage("It's your birthday :)");
}

//Hook into RunUO's post-compile-time delegates
public static void Initialize()
{
      //The Scheduler class is just a repeating Timer,
      //it only ticks once per minute and "polls" the conditions matching the current date/time to the set value
      Schedule.Start();
}
 
Top