Check how many hours/days passed

Hello Guys!


I’m trying to make a function to give an award every hour and every day.

For that I want to implement a function that given 2 DateTime check how many hours/days passed.

I already have a Coroutine to call that function every second.

For example, I want to give awards every 00:00:00, 01:00:00 … 12:00:00 … 23:00:00


Example:

DateTime date0 = new DateTime(2018, 8, 9, 20, 59, 59);
DateTime date1 = new DateTime(2018, 8, 9, 21, 0, 0);
int hoursPassed = (int) date1.Subtract(date0).TotalHours;
Debug.Log("Hours "+ hoursPassed);

The hoursPassed will be equal to 0 in this case. I want to make a function (maybe already exists) that retrieve me 1 instead. The same with the days.


Example 2

DateTime date0 = new DateTime(2018, 8, 9, 23, 59, 59);
    DateTime date1 = new DateTime(2018, 8, 10, 00, 00, 00);
    int DaysPassed = (int) date1.Subtract(date0).TotalDays;
    Debug.Log("Days "+ DaysPassed);

It will retrieve 0 and I want to retrieve 1.


I also want this to work when multiple hours/days have passed .


Can anybody help me?

Thank you

You don’t want to work with relative times but with absolute timestamps. If you want to award something at a certain time of the day you should store the time of the last award and keep that until the next is due.

Note it’s quite unusual to award accumulated hours / days without a limit. I’ve once posted an answer over here that resembles the life regeneration or games like candy crush. You have a max of 5 lives. Every say 30 minutes you regenerate 1 life but only up to a max of 5. If you quite the app at 0 lives and start it again later it will regenerate one life for every 30 minutes that have passed. Though no more than 5. So if a user did not play the game for 5 years he doesn’t have 87000 lives but only 5.

Generally there are two ways how you could implement awards:

  • Either awarded every full hour / day (day means at 00:00)
  • Or after a relative period of 60 minutes / 24 hours. That means if the user starts the app at 13:20 he gets an award at 14:20 / 15:20 / … The daily award would be awarded 14:20 the next day.

The second solution is the easiest solution since you just have to store the time of the last award so you can easily work out how much time has passed.

For the first solution you would do the same but you just store the date of the last daily award or the date and hour of the last hourly award. If you really want to award something every hour that has passed you can simply subtract the stored date from the current so you get the days that have passed. Make sure to not store the time as well but only use a date for the daily award. Likewise for the hourly award you don’t want to store the minutes or seconds of the last award but only the date and hour

**THIS ANSWER IS NOT MINE. NineBerry DID IT in another forum. **


The easiest way is to create trimmed DateTime variables by stripping minutes/seconds when interested in hours only and by trimming hours/minutes/seconds when interested in days only. Then calculate the difference in hours or days.


// Calculates the number of hour strikes between the two given times
public static int HourStrikesBetween(DateTime from, DateTime to)
{
    if(from > to)
    {
        throw new ArgumentException("from must not be after to");
    }

    // Trim to hours
    DateTime fromTrimmed = new DateTime(from.Year, from.Month, from.Day, from.Hour, 0, 0);
    DateTime toTrimmed = new DateTime(to.Year, to.Month, to.Day, to.Hour, 0, 0);

    int hours = (int)(toTrimmed - fromTrimmed).TotalHours;

    return hours;
}

// Calculates the number of midnights between the two given times


public static int MidnightsBetween(DateTime from, DateTime to)
{
    if (from > to)
    {
        throw new ArgumentException("from must not be after to");
    }

    // Trim to days
    DateTime fromTrimmed = new DateTime(from.Year, from.Month, from.Day);
    DateTime toTrimmed = new DateTime(to.Year, to.Month, to.Day);

    int days = (toTrimmed - fromTrimmed).Days;

    return days;
}

Sample:


DateTime date0 = new DateTime(2018, 8, 9, 20, 59, 59);
DateTime date1 = new DateTime(2018, 8, 9, 21, 0, 0);
int hourspassed = HourStrikesBetween(date0, date1);  // = 1

date0 = new DateTime(2018, 8, 9, 20, 00, 00);
date1 = new DateTime(2018, 8, 9, 21, 50, 0);
hourspassed = HourStrikesBetween(date0, date1);  // = still 1

date0 = new DateTime(2018, 8, 9, 20, 59, 59);
date1 = new DateTime(2018, 8, 9, 22, 10, 0);
hourspassed = HourStrikesBetween(date0, date1);  // = 2


date0 = new DateTime(2018, 8, 9, 23, 59, 59);
date1 = new DateTime(2018, 8, 10, 00, 00, 00);
int daysPassed = MidnightsBetween(date0, date1);  // = 1

Note that this will only work when crossing Dayligth Saving Time boundaries if you consistently use UTC DateTime instead of Local DateTime.