How can I tell if DateTime.Now() is on a day AFTER a different DateTime

4,775

Solution 1

I don't know flutter, but my approach would be to not store the last check, but store the date at which the next check should occur. So when you perform a check you calculate the next midnight and store that. Now you can use isAfter.

In javascript this would look something like this:

const now = new Date();

//this also handles overflow into the next month
const nextCheck = new Date(now.getYear(), now.getMonth(), now.getDate() + 1)

//store nextCheck somewhere

//in js there is no isAfter, you just use >
if(new Date() > nextCheck) {
   //do the thing
}

of course you could also calculate nextCheck every time you want to compare it, but I dislike performing the same calculation over and over if I can avoid it.

A thing to mention here is timezones, depending on your date library and if your system and user timezones align, you may need to shift the date.

Solution 2

I cannot write a complete code for now but this is what it would look like:

(pseudocode)

expirationDay = lastDailyCheck.add(oneDayDuration);
isOneDayAfter = DateTime.now().isAfter(expirationDay);

You give an expiration date and compare the DateTime to that. You have to use isAfter for reliability, instead of .day check.

Solution 3

Figured out another potential solution!

In addition to checking if the day is different (which by itself won't work) you can also check the month and year. Only 1 of those needs to differ for it be true :)

if (now.isAfter(lastDailyCheck)) {
  if (now.day != lastDailyCheck.day ||
      now.month != lastDailyCheck.month ||
      now.year != lastDailyCheck.year) {
    return true;
  }
}

Solution 4

this is the way I prefer to do some logics based on the comparison between two different times:

var now = DateTime.now();
var myDate = new DateTime.utc(2022, 1, 1);
if(myDate.compareTo(now)>0) //positive value means myDate is greater than DateTime.now()
{
  // here is your logic based on the comparison between two times
} else {
 //your logic if DateTime.now() pass myDate
}

Solution 5

I would compute the difference between midnight of the day of the last timestamp and midnight of the current timestamp. That is, consider only the date portion of a DateTime and ignore the time.

DateTime date(DateTime dateTime) =>
    DateTime(dateTime.year, dateTime.month, dateTime.day);

// Intentionally check for a positive difference in hours instead of days
// so we don't need to worry about 23-hour days from DST.  Any non-zero
// number of hours here means a difference of at least a "day".
if (date(DateTime.now()).difference(date(lastDailyCheck)).inHours > 0) {
  // "One day" after.
}

If you're using UTC timestamps and don't care about when midnight is in whatever the local time is, the comparison could more intuitively use .inDays >= 1.

Share:
4,775
matthias_code
Author by

matthias_code

Main iOS Engineer at Red Android. Formerly @OetkerDigital, @IBM_iX. Also doing Unity3D. Not on the 30u30 List, Opinions are my own. Twitter: @matthias_code Go watch my youtube iOS tutorials!

Updated on December 19, 2022

Comments

  • matthias_code
    matthias_code over 1 year

    I'm running this on flutter, but I guess this could be a more general issue.

    I am saving a DateTime in the preferences. I want to be able to then tell if DateTime.now() is on at least a day after the last saved DateTime, i.e.

    (pseudocode)
    lastDailyCheck = 2020.04.10
    now = 2020.04.11
    

    => now is a day after the lastDailyCheck.

    This should already work if it is 00:01 on the new day, even if the lastDailyCheck was on 23:58 the day before, meaning the difference can be as low as minutes between the 2 DateTimes.

    Turns out this is really complicated!

    Here's what doesn't work:

    DateTime.Now().isAfter(lastDailyCheck)

    This only checks if now is after the last one, it also return true after a second, and on the same day.

    DateTime.Now().isAfter(lastDailyCheck) && lastDailyCheck.day != DateTime.Now().day

    I thought this was clever. If the day is different and it is after the last then it does work in recognizing it is a day later - but then I realized it would bug out when both days are say on the 15th of the month - then lastDailyCheck.day would equal DateTime.Now().day.

    What do you think would be possible here?

  • matthias_code
    matthias_code about 4 years
    Neat, that should bypass the potential lastDailyCheck.day != now.day issue! :D
  • matthias_code
    matthias_code about 4 years
    Cool Approach! :) Not sure it would fully work when the actual difference between the 2 days would be less than 24h, e.g. lastDailyCheck at 23:00, and the current day at 12:00
  • matthias_code
    matthias_code about 4 years
    That sounds like a much more clever way to do it, I'll try that! :D
  • venir
    venir over 2 years
    I know this has nothing to do with the original question, but this answer actually SAVED my code since I was trying to add a fixed amount of days in my calculations and I had problems with the DST! Using something like DateTime(2021, 11, 01-7) actually includes the DST calculations for us. Wow! Thank you!