# Checking the date is within x days of specified time, ignoring year?

Hi Friends!

I’m setting up some seasonal events stuff for our app. Things like automatically turning on Halloween/Xmas content based on the date. We want to be able to say “Xmas content is available in the month of December” or “Halloween is available for 2 weeks around Oct 31st”.

We don’t need to worry about checking the time with an online server or anything since it’s a paid app with no multiplayer. We figure if people want to experience the Xmas content during July, they can go for it

If you have two dates that you want to compare, C# has a handy TimeSpan type that can calculate the number of days between them.

1 Like

Get current DateTime with DateTime.Now.

Create a DateTime for the year of DateTime.Now, but the targets you want.

For example if you wanted to know if you’re within 2 days of noon time on Halloween in either direction you could say:

``````var dt = DateTime.Now;
var targetDate = new DateTime(dt.Year, 10, 31, 12, 0, 0);
if(Math.Abs((targetDate - dt).TotalDays) <= 2.0d)
{
//do stuff
}
``````

Or if you were wanting to check if they were in December:

``````var dt = DateTime.Now;
var minDate = new DateTime(dt.Year, 12, 1, 0, 0, 0);
var maxDate = new DateTime(dt.Year + 1, 1, 1, 0, 0, 0); //we're going to check < new years
if(dt >= minDate && dt < maxDate)
{
//do stuff
}
``````

Note there are many methods on DateTime for manipulating it in sensible ways. Like to get new years I could have said:

``````var maxDate = minDate.AddMonths(1);
``````

Here is the doc for DateTime:

And when you do things like DateTime - DateTime, mind you that it returns a TimeSpan of the difference:

2 Likes

This worked perfectly, thanks team!

“Team” lol

1 Like

I know I am very late but i have a great and easy to understand solution:

``````var dt = Convert.ToDateTime(DateTime.Now.ToString ("MM/dd/yyyy"));
var targetDt = Convert.ToDateTime ("01/02/2022");
string[] abc;
string CountDaysString=(dt-targetDt).ToString();
abc=CountDaysString.Split(":"[0]);

if (float.Parse(abc [0]) >= 30)
{
}
``````

I see a few little oddities with your code.

1. Why “:”[0]? If you want to get the char code : than say ‘:’ (single quote). In C# double quote is string, single quote is char.

2. Why tostring everything? This is costly and creates a bunch of garbage. I’m not arguing you should make your game 100% garbage free because that’s nearly impossible on any reasonable level. But DateTime has arithmetic built in, might as well use it.

3. Why use parsing for creating your dates? It’s slower than just instantiating a DateTime.

4. Parsing relies on culture info (unless otherwise defined as an optional parameter). This logic will work for you because you’re developing in the US, using US style date formatting. But what if you distribute this game to someone in Europe where it’s far more common to format the date dd/MM/yyyy? They’re going to get out february 1st rather than january 2nd. And other countries can get even weirder like in Asia where it’s common to go yyyy/MM/dd.

So reading your code it appears your logic is saying “if today is at least 30 days after january 2 2022”.

So why not:

``````if ((DateTime.Today - new DateTime(2022, 1, 2)).TotalDays >= 30)
{
}
``````

Note that your:
Convert.ToDateTime(DateTime.Now.ToString (“MM/dd/yyyy”))

is the same as just saying:
DateTime.Today

DateTime.Today returns today’s date without the time. Which is what you’re doing by tostring’n with “MM/dd/yyyy”, you’re shaving off the time of DateTime.Now, and then parsing the string back.

Also

1. Your logic could easily break if someone were to come along and try to modify it or adapt it to new purposes.

What I mean is that when you do (dt - targetDt).ToString(), what you’re doing is a getting the TimeSpan between both dates and than ToString’n it. And you’re relying on the fact that TimeSpan returns its difference in the format:
[-][d.]hh:mm:ss[.fffffff]

Problem is… notice that the [d.] is optional. It only occurs IF the TimeSpan >= 24 hours.

If the TimeSpan happens to be < 1 day, I can falsely get numbers between 0->23 from that ToString.

Of course in your logic you account for this by shaving off all ‘time’ and only dealing in days. But it’s not obvious as such. And what if I came along one day and I was "oh… I want to know if we’re 10 days past NOON on the 2nd (because maybe time of day does come into play). I now change just your 2nd line of code to be:

``````var targetDt = Convert.ToDateTime("01/02/2022 12:00:00");
``````

Thing is technically your code will work!

Unless it just so happens to be jan 3rd. In which case we’ll resolve it’s midnight, 12 hours from noon, and our abc array with have a “12” in the first slot making it APPEAR it’s 12 days after the 2nd, when actually it’s only a day.

Where as the code I showed would become:

``````if ((DateTime.Today - new DateTime(2022, 1, 2, 12, 0, 0)).TotalDays >= 10)
{
}
``````

And it would continue working.

Of course this may cause before noon of a day 10 days later to not register. But that’s an easy bug to resolve. “I noticed that the first 12 hours of the 10th day aren’t registering as 10 days later. OH, cause I moved the time to noon!” Where as the other bug is “Why does the entire day of the 3rd register as 10 days after the 2nd???”

Also it’s more readable in my opinion…

DateTime.Today = Today… what’s today? Sounds like it’s probably today’s date, but isn’t that ‘Now’? [looks in docs] oh, today is just Now without the time portion.

Convert.ToDateTime(DateTime.Now.ToString (“MM/dd/yyyy”)) = ??? Ummm… what does this format string mean? [looks up ToString format string logic], that’s… ok so you’re formatting Now as month day year. Why? Then you just parse it back into a date? Why not just take the date? OHHHH, you’re shaving off the time! Wait? Huh? Why not just use DateTime.Today? I saw it when I was looking in the docs for ToString format strings of DateTime.

``````string CountDaysString=(dt-targetDt).ToString();
abc=CountDaysString.Split(":"[0]);
``````

Like wat? What is this? What is this even doing?

I need intimate knowledge of the .net api to know what this means.

I am an advanced programmer with years of practice. Most languages I don’t need to know to be able to suss out the basics of what is going on. Because most languages express themselves.

``````(DateTime.Today - new DateTime(2022, 1, 2)).TotalDays >= 30
``````

If I don’t know C#/.net/mono I can suss it out…

We got a DateTime type, probably represents dates and time. We subtract 2 of them. Ok… that probably gives some sort of “difference” of dates. I don’t know the type it would be… but I figure it’s going to return some representation of time duration, may it be a number, or a data type like a struct. Since it says ‘.TotalDays’, I’m going to bet it’s a struct, and TotalDays is the number of days that time duration was. Put it all together… the number of days between today and jan 2nd is greater than or equal to 30. I understand that.

This though?

``````string CountDaysString=(dt-targetDt).ToString();
abc=CountDaysString.Split(":"[0]);
``````

Well what is the type that returns from (dt - targetDt)?
What happens when I ToString it?
It appears the developer assumes that the result when stringified will have “:” in it. But in what manner? Most formats as an American I know if hh:mm:ss, so are they getting the “hours”?
Who wants to test if it’s 30 hours since the 2nd? That’s weird.
I’m going to have to pull up the documentation of DateTime and see where this leads me. First going to have to see what subtracting DateTime’s get’s you. Then what that date type does when I tostring it.
And with all that I need to make the assumption that the coder didn’t write this wrong/sloppy!

1 Like