views:

58

answers:

2

I'm trying to determine a TimeSpan (eg., time between logout and login), but with the caveat that a part of each day shouldn't be counted (eg., don't count the time between 7PM and 7AM on a given day). Removing that time from full days is easy enough, but what's the best way to check for parts of a day (eg., user logs out at 6PM and logs back in at 8PM the same day) and other edge cases?

ETA: I've currently got a set-up that looks like this:

public class HasProductiveHours
{
    //These fields should represent an hour of the day (in 24-hour format)
    // in which production should start or stop.
    public int startProductiveHour;
    public int endProductiveHour;
    //Resource type enum
    public ResourceType resourceType
    //How often this resource is collected, in seconds
    public float harvestTime

    public HasProductiveHours (int startProductiveHour, int endProductiveHour, ResourceType resourceType, int harvestTime)
    {
        // Other creation-time things
        this.startProductiveHour = startProductiveHour;
        this.endProductiveHour = endProductiveHour;
        this.resourceType = resourceType;
        this.harvestTime = harvestTime;
        TimeSimulator.Instance.SimulateElapsedTime (this);
    }
}

Instances of this class and its children are simulating production of some resource every hour or so (depending on the resource). There's a system in place to simulate elapsed time since the user's last logout.

DateTime lastLogoutTime;

public void Logout ()
{
    // Other logout things
    lastLogoutTime = DateTime.Now;
}

public void SimulateElapsedTime (HasProductiveHours toSimulate)
{
    DateTime currentTime = DateTime.Now;
    TimeSpan timeSinceLogout = currentTime - lastLogout;
    int unproductiveHours = Math.Abs (toSimulate.startProductionHour - toSimulate.endProductionHour) * timeSinceLogout.Days;
    timeSinceLogout.Subtract (new TimeSpan (unproductiveHours, 0, 0);
    double secondsElapsed = timeSinceLogout.TotalSeconds;
int harvestsElapsed = (int)(secondsElapsed / toSimulate.harvestTime);
PlayerData.Instance.AddResource (toSimulate.resourceType, harvestsElapsed);
}
+2  A: 

A few steps should easily fix this:

  1. Check the logout time - see if it is between 7am and 7pm (The hour method gives you the number of hours since midnight. You want to see if it is >=7 and <=19). If it is not, move the time forward to 7am. Should be easy enough to do - If the time is <7am, change the time to 7am. If the Time is greater than 7pm, change the time to 7am the next day

  2. Check the login time - see if it is between 7am and 7pm. If it is not, move the time back to 7pm. Should be easy enough to do - If the hour >7pm, set it to 7pm, if the hour is <7am, change the time to 7pm on the previous day

  3. Check to make sure logout time < login time. If not, the entire time logged out was during the none counting hours, so your time span should be set to 0. If your logout time < login, just subtract them to get your timespan

This for the situation described in the comment:

If the day numbers are the now the same these are the steps I would take:

  1. Create a new datetime with the logout outs date, and a time of 1900. Subtract the new date from the logout date - this will give you the timespan until the end of day

  2. Move the logout date to 7am the next day. If the logout and the login are now on the same day, just subtract the logout from the login, this is the timespan for that day. If they are not the same date, repeat step 1

  3. Add the timespans generated in step 1 and step 2 together. This gives your total time

For example: I logout Jan 1, at 16:00. I login Jan 2, at 10:00

The time I was logout on Jan 1 during tracking hours is 3hours (Jan 1, 19:00 - Jan 1, 16:00)

I move the logout time to Jan 2, at 07:00.

The day of logout is 2, and the day of login is 2, now I can subtract them

The time I was logout in Jan 2 during tracking hours is 3hours (Jan 2, 10:00 - Jan 2, 07:00)

I now add them together and get 6hours of logout time during tracking hours.

thorkia
These suggestions helped a lot, but it doesn't seem to cover the case where the logout and login are not altered (ie, logged out between 0700 and 1900 and logged in between 0700 and 1900) and fewer than 24 hours have elapsed. For example, if I log out at 1800 Jan. 1st and log in 0800 Jan. 2nd the number of days elapsed is 0, but one full cycle of unproductive hours should be deducted. How can I differentiate this case from, say, logging out at 0800 Jan. 1st and logging back in at 0900 Jan. 1st?
burnumd
see my edit. I have added logic to handle when dates are not same
thorkia
Brilliant! Thanks a bunch.
burnumd
A: 

@thorkia has some good suggestions.

Alternatively you can calculate the time difference and then sum up (from another table) the total non-production/non-time that was covered and subtract that from the total.

So

8am-6am = 2 hours total

6am to 7am = 1 hour non-time

result = 1 hour total real-time

John M
Interesting idea... Never thought of doing it that way. That would work really well also.
thorkia