Testing DateTime in C# using TimeProvider in 10 Minutes or Less
Read full transcript 10 segments
-
The time provider in C sharp allows us The time provider in C sharp allows us to more easily test our code that uses to more easily test our code that uses to more easily test our code that uses date and time values. Let's look at how date and time values. Let's look at how date and time values. Let's look at how to use this option as well as how to to use this option as well as how to to use this option as well as how to test our code that relies on the date test our code that relies on the date test our code that relies on the date and time. and time. and time. Now, for most of my training, I work to Now, for most of my training, I work to Now, for most of my training, I work to give you an in-depth look at technology give you an in-depth look at technology give you an in-depth look at technology so you have an understanding of when and so you have an understanding of when and so you have an understanding of when and why to use something, not just how to why to use something, not just how to why to use something, not just how to use it. But sometimes you just need that use it. But sometimes you just need that use it. But sometimes you just need that quick answer to the question, how do I quick answer to the question, how do I quick answer to the question, how do I do this? That's why I created this do this? That's why I created this do this? That's why I created this 10-minute training series. 10-minute training series. 10-minute training series. Now, what I've got for you is a Now, what I've got for you is a Now, what I've got for you is a pre-built demo. I'll give you the end pre-built demo. I'll give you the end pre-built demo. I'll give you the end code down in the description. Just go code down in the description. Just go code down in the description. Just go ahead and click on the link in there and ahead and click on the link in there and ahead and click on the link in there and it'll it'll email you the the completed it'll it'll email you the the completed it'll it'll email you the the completed code. Um so, what we have here is two code. Um so, what we have here is two code. Um so, what we have here is two things. First of all, a console things. First of all, a console things. First of all, a console application and in here I have a class application and in here I have a class application and in here I have a class called demos. We have a time of day called demos. We have a time of day called demos. We have a time of day message. So, if it's before 6:00 a.m. it message. So, if it's before 6:00 a.m. it message. So, if it's before 6:00 a.m. it says good early morning, otherwise says good early morning, otherwise says good early morning, otherwise before noon it says good morning, good before noon it says good morning, good before noon it says good morning, good afternoon, good evening, and good night. afternoon, good evening, and good night. afternoon, good evening, and good night. And then we have is this a leap year? I And then we have is this a leap year? I And then we have is this a leap year? I don't know if you know this, but don't know if you know this, but don't know if you know this, but calculating leap year is a little more calculating leap year is a little more calculating leap year is a little more complicated. Now, with date time you can complicated. Now, with date time you can complicated. Now, with date time you can calculate leap year also by saying is calculate leap year also by saying is calculate leap year also by saying is this a leap year? Um but we're not going this a leap year? Um but we're not going this a leap year? Um but we're not going to do that. We're actually going to to do that. We're actually going to to do that. We're actually going to calculate by hand. So, it's if the year calculate by hand. So, it's if the year calculate by hand. So, it's if the year is divisible by four, is divisible by four, is divisible by four, then it's leap year except if the year then it's leap year except if the year then it's leap year except if the year is divisible by a hundred, is divisible by a hundred, is divisible by a hundred, except if the year is divisible by four except if the year is divisible by four except if the year is divisible by four hundred. So, if it's divisible by four, hundred. So, if it's divisible by four, hundred. So, if it's divisible by four, it's probably a leap year except when it's probably a leap year except when it's probably a leap year except when the year is divisible by a hundred, but
-
the year is divisible by a hundred, but the year is divisible by a hundred, but if it's if it's if it's divisible by four hundred, then it is a divisible by four hundred, then it is a divisible by four hundred, then it is a leap year again. So, basically 1900 not leap year again. So, basically 1900 not leap year again. So, basically 1900 not a leap year. 2000, yes, it's a leap a leap year. 2000, yes, it's a leap a leap year. 2000, yes, it's a leap year. year. year. So, we're just returning true or false, So, we're just returning true or false, So, we're just returning true or false, okay? These methods don't really mean okay? These methods don't really mean okay? These methods don't really mean much. They're just here for testing. So, much. They're just here for testing. So, much. They're just here for testing. So, what I then have is I import them in the what I then have is I import them in the what I then have is I import them in the CS, I call both of those, and let's just CS, I call both of those, and let's just CS, I call both of those, and let's just run this real quick so you can see run this real quick so you can see run this real quick so you can see goodnight and false are current values. goodnight and false are current values. goodnight and false are current values. And for demo test, I created two tests. And for demo test, I created two tests. And for demo test, I created two tests. They're This is XUnit and one is time of They're This is XUnit and one is time of They're This is XUnit and one is time of day message test and that just says, day message test and that just says, day message test and that just says, "Hey, does it equal goodnight?" And also "Hey, does it equal goodnight?" And also "Hey, does it equal goodnight?" And also down here is this a leap year test, I down here is this a leap year test, I down here is this a leap year test, I say, "Does it equal false?" Okay? Now, say, "Does it equal false?" Okay? Now, say, "Does it equal false?" Okay? Now, I want to run both these tests. Let's I want to run both these tests. Let's I want to run both these tests. Let's run them real quick. run them real quick. run them real quick. And I can see it already run once and And I can see it already run once and And I can see it already run once and they both pass. they both pass. they both pass. Which is deceptive because this will Which is deceptive because this will Which is deceptive because this will only work if you're in the correct time only work if you're in the correct time only work if you're in the correct time of day and on the correct year true or of day and on the correct year true or of day and on the correct year true or false, right? So, if I would said, false, right? So, if I would said, false, right? So, if I would said, "Well, you know, let's test for true."
-
"Well, you know, let's test for true." "Well, you know, let's test for true." Well, that's going to fail test and Well, that's going to fail test and Well, that's going to fail test and let's just test for good morning. let's just test for good morning. let's just test for good morning. Well, it's going to fail test as well. Well, it's going to fail test as well. Well, it's going to fail test as well. So, I run these tests now, then we're So, I run these tests now, then we're So, I run these tests now, then we're going to get two failing tests because, going to get two failing tests because, going to get two failing tests because, you know, it's not the right time to you know, it's not the right time to you know, it's not the right time to test good morning. But, that's a problem test good morning. But, that's a problem test good morning. But, that's a problem because you want to test did the good because you want to test did the good because you want to test did the good morning message come across correctly? morning message come across correctly? morning message come across correctly? This is where what we do is we use a This is where what we do is we use a This is where what we do is we use a time provider to take in a time provider time provider to take in a time provider time provider to take in a time provider instead of using date time. So, let's do instead of using date time. So, let's do instead of using date time. So, let's do that here that here that here in our demos. Time provider in our demos. Time provider in our demos. Time provider and we'll call this uh time. and we'll call this uh time. and we'll call this uh time. And we'll do the same thing down below And we'll do the same thing down below And we'll do the same thing down below here for is this a leap year. Now, here for is this a leap year. Now, here for is this a leap year. Now, instead of datetime.now.hour, instead of datetime.now.hour, instead of datetime.now.hour, what we're going to do is say uh .hour. So, it's very, very similar. In .hour. So, it's very, very similar. In fact, if we look at what time gives us, fact, if we look at what time gives us, fact, if we look at what time gives us, time. We have the timestamp frequency, time. We have the timestamp frequency, time. We have the timestamp frequency, we have create timer, we have the local we have create timer, we have the local we have create timer, we have the local time zone, we have UTC now, as well as time zone, we have UTC now, as well as time zone, we have UTC now, as well as get timestamp, create timer, and then get timestamp, create timer, and then get timestamp, create timer, and then get local now.
-
get local now. get local now. Um so, there's a lot of stuff in here Um so, there's a lot of stuff in here Um so, there's a lot of stuff in here you can do. And once you have the get you can do. And once you have the get you can do. And once you have the get local now or, you know, UTC now, local now or, you know, UTC now, local now or, you know, UTC now, you can do all the same things, right? you can do all the same things, right? you can do all the same things, right? So, add days, hours, the offset, the So, add days, hours, the offset, the So, add days, hours, the offset, the minutes, current minutes, you know, all minutes, current minutes, you know, all minutes, current minutes, you know, all the the fun stuff you can do with the the fun stuff you can do with the the fun stuff you can do with daytime now pretty much is in here. daytime now pretty much is in here. daytime now pretty much is in here. This is a subtraction away. This is a subtraction away. This is a subtraction away. So, now with time provider, we can say So, now with time provider, we can say So, now with time provider, we can say time.getlocalnow.hour. Now, what does this do for us? Well, Now, what does this do for us? Well, time provider can be faked. So, we're time provider can be faked. So, we're time provider can be faked. So, we're going to fake it in just a minute. going to fake it in just a minute. going to fake it in just a minute. But before we do that, let's come down But before we do that, let's come down But before we do that, let's come down here and fix this as well. So, instead here and fix this as well. So, instead here and fix this as well. So, instead of saying year equals datetime.now.year, of saying year equals datetime.now.year, of saying year equals datetime.now.year, what we're going to do is say uh what we're going to do is say uh what we're going to do is say uh time.getlocalnow.year. It's basically same same thing, um but It's basically same same thing, um but we're doing the time provider instead. we're doing the time provider instead. we're doing the time provider instead. So, now if we were to Well, we've got to So, now if we were to Well, we've got to So, now if we were to Well, we've got to make some changes first. So, we'd come make some changes first. So, we'd come make some changes first. So, we'd come back over here to our program.cs and back over here to our program.cs and back over here to our program.cs and pass in values now for time provider.
-
pass in values now for time provider. pass in values now for time provider. What is that? Well, it's What is that? Well, it's What is that? Well, it's timeprovider.system. Okay? So, that that will handle Okay? So, that that will handle the current time. And if we run this the current time. And if we run this the current time. And if we run this code as it is, good night and false, code as it is, good night and false, code as it is, good night and false, same thing. So, we're back to working same thing. So, we're back to working same thing. So, we're back to working code. code. code. But now, how do we But now, how do we But now, how do we more easily test this? Well, what we can more easily test this? Well, what we can more easily test this? Well, what we can do is we can say, "You know what? do is we can say, "You know what? do is we can say, "You know what? Instead of saying Instead of saying Instead of saying um um um the the um the the um the the um d.timeofday and passing in, you know, d.timeofday and passing in, you know, d.timeofday and passing in, you know, nothing, we're going to pass in a value. nothing, we're going to pass in a value. nothing, we're going to pass in a value. But we need to pass in what value? Well, But we need to pass in what value? Well, But we need to pass in what value? Well, we're going to pass in the value of a we're going to pass in the value of a we're going to pass in the value of a fake time. So, let's create one. fake time. So, let's create one. fake time. So, let's create one. Fake time provider. Fake time provider. Fake time provider. Uh fake time. Uh fake time. Uh fake time. Now, if you're following you're like, Now, if you're following you're like, Now, if you're following you're like, "Wait, I don't have that yet." Yes, I "Wait, I don't have that yet." Yes, I "Wait, I don't have that yet." Yes, I added one NuGet package called added one NuGet package called added one NuGet package called Microsoft.Extensions.TimeProvider.Testing. So, this NuGet package right here So, this NuGet package right here is the NuGet package you want to is the NuGet package you want to is the NuGet package you want to in order to get this fake time provider.
-
in order to get this fake time provider. in order to get this fake time provider. I can say equals new and pass in a value I can say equals new and pass in a value I can say equals new and pass in a value here. So, I'm going to say date time here. So, I'm going to say date time here. So, I'm going to say date time offset offset offset .now. .now. .now. Yes, what it's looking for is a date Yes, what it's looking for is a date Yes, what it's looking for is a date time offset, right? So, date time time offset, right? So, date time time offset, right? So, date time offset.now would be right now. offset.now would be right now. offset.now would be right now. But, what I want to say is add hours. But, what I want to say is add hours. But, what I want to say is add hours. And I'm going to say And I'm going to say And I'm going to say uh let's do uh let's do uh let's do how about eight? how about eight? how about eight? Okay? So, date time offset is going to Okay? So, date time offset is going to Okay? So, date time offset is going to give me the date right now. give me the date right now. give me the date right now. Right? But, it's going to give me then Right? But, it's going to give me then Right? But, it's going to give me then add hours of eight. So, it's going to add hours of eight. So, it's going to add hours of eight. So, it's going to start from from today's date, but then start from from today's date, but then start from from today's date, but then add eight hours to it. add eight hours to it. add eight hours to it. Almost, not quite. I didn't say Almost, not quite. I didn't say Almost, not quite. I didn't say now.date. Missed that part. Okay. So, now.date. Missed that part. Okay. So, now.date. Missed that part. Okay. So, just getting a date for for right now, just getting a date for for right now, just getting a date for for right now, and that means just today's date. And and that means just today's date. And and that means just today's date. And then we're going to add eight hours. So, then we're going to add eight hours. So, then we're going to add eight hours. So, it's going to give me date as of it's going to give me date as of it's going to give me date as of midnight. And then we're going to add midnight. And then we're going to add midnight. And then we're going to add eight hours, which puts us at 8:00 a.m.
-
eight hours, which puts us at 8:00 a.m. eight hours, which puts us at 8:00 a.m. Which means that when we test this, Which means that when we test this, Which means that when we test this, we're going to pass in a time that's we're going to pass in a time that's we're going to pass in a time that's 8:00 a.m. 8:00 a.m. 8:00 a.m. Which should be good morning. Which should be good morning. Which should be good morning. So, let's test this and let's just So, let's test this and let's just So, let's test this and let's just comment out this this for right now. comment out this this for right now. comment out this this for right now. Um Um Um so we can test just this one test, and so we can test just this one test, and so we can test just this one test, and we'll run this. And we get a green passing test, because And we get a green passing test, because now we are saying good morning because now we are saying good morning because now we are saying good morning because it's 8:00 a.m. it's 8:00 a.m. it's 8:00 a.m. So, now let's do the same thing here So, now let's do the same thing here So, now let's do the same thing here where we create fake time. where we create fake time. where we create fake time. And this is a bit more complicated. So, And this is a bit more complicated. So, And this is a bit more complicated. So, we're going to say fake time provider we're going to say fake time provider we're going to say fake time provider fake time fake time fake time equals new. And it's going to When we equals new. And it's going to When we equals new. And it's going to When we say new, it's going to be asking us for say new, it's going to be asking us for say new, it's going to be asking us for um here, let's do this again. um here, let's do this again. um here, let's do this again. It asks us for a fake time provider with It asks us for a fake time provider with It asks us for a fake time provider with nothing or a date time offset, which is nothing or a date time offset, which is nothing or a date time offset, which is what we did up here. We're going to do what we did up here. We're going to do what we did up here. We're going to do the same thing inside here. So, we're the same thing inside here. So, we're the same thing inside here. So, we're going to say new for the date time going to say new for the date time going to say new for the date time offset. offset. offset. And we're going to actually spell out And we're going to actually spell out And we're going to actually spell out the entire thing. So, let's say the entire thing. So, let's say the entire thing. So, let's say um um um 20 or 2000, because that's a leap year.
-
20 or 2000, because that's a leap year. 20 or 2000, because that's a leap year. And then we're going to say And then we're going to say And then we're going to say uh month and year or January 1st, that's uh month and year or January 1st, that's uh month and year or January 1st, that's fine. fine. fine. Um Um Um hour is noon. hour is noon. hour is noon. Uh Uh Uh minutes minutes minutes uh seconds, and then we'll say time zone uh seconds, and then we'll say time zone uh seconds, and then we'll say time zone info.utc.base utc offset. That's That's current time utc offset. That's That's current time zone. zone. zone. Okay? So, Okay? So, Okay? So, in this current time zone, let's in this current time zone, let's in this current time zone, let's do our spacing right here. Um and let's do our spacing right here. Um and let's do our spacing right here. Um and let's unpin this. unpin this. unpin this. This is our fake time now saying, "Hey, This is our fake time now saying, "Hey, This is our fake time now saying, "Hey, the year 2000, January 1st at noon." the year 2000, January 1st at noon." the year 2000, January 1st at noon." So, you pass that fake time in, if I put So, you pass that fake time in, if I put So, you pass that fake time in, if I put in the right spot. in the right spot. in the right spot. And that should tell us if this is a And that should tell us if this is a And that should tell us if this is a leap year. Okay? And so, we can say leap year. Okay? And so, we can say leap year. Okay? And so, we can say actual and expected is is true now. actual and expected is is true now. actual and expected is is true now. So, if we test this, So, if we test this, So, if we test this, well, now they both pass. But, let's not well, now they both pass. But, let's not well, now they both pass. But, let's not do fact, let's do theory. I'm going to do fact, let's do theory. I'm going to do fact, let's do theory. I'm going to copy and paste this, it's a little copy and paste this, it's a little copy and paste this, it's a little easier. Um let's do theory. So, xUnit easier. Um let's do theory. So, xUnit easier. Um let's do theory. So, xUnit has an idea of theories.
-
has an idea of theories. has an idea of theories. And what a theory is And what a theory is And what a theory is and bool expected. and bool expected. and bool expected. What a theory is, we can pass data in. What a theory is, we can pass data in. What a theory is, we can pass data in. So, now we can say, "Hey, this is the So, now we can say, "Hey, this is the So, now we can say, "Hey, this is the expected value, true or false." And this expected value, true or false." And this expected value, true or false." And this year thing, um that's the the thing year thing, um that's the the thing year thing, um that's the the thing we're going to test against. So, we're we're going to test against. So, we're we're going to test against. So, we're going to say, where it says 2000, we're going to say, where it says 2000, we're going to say, where it says 2000, we're going to say year. going to say year. going to say year. So, we're going to say, "Hey, for 2020, So, we're going to say, "Hey, for 2020, So, we're going to say, "Hey, for 2020, that should be true. For 2000, that that should be true. For 2000, that that should be true. For 2000, that should be true. 1900 should be false, should be true. 1900 should be false, should be true. 1900 should be false, even though it's divisible by four, even though it's divisible by four, even though it's divisible by four, because it's a 1900 divisible by 100, because it's a 1900 divisible by 100, because it's a 1900 divisible by 100, but not 400." Okay? And we're going to but not 400." Okay? And we're going to but not 400." Okay? And we're going to do the same thing up above as well. do the same thing up above as well. do the same thing up above as well. We're going to pass in a whole bunch of We're going to pass in a whole bunch of We're going to pass in a whole bunch of theories, which let's just um theories, which let's just um theories, which let's just um I'll paste in here as well. Uh the hour I'll paste in here as well. Uh the hour I'll paste in here as well. Uh the hour and expected. So, now we're going to be and expected. So, now we're going to be and expected. So, now we're going to be testing against expected. And we'll pass in the And we'll pass in the hours here or the hour here to offset.
-
hours here or the hour here to offset. hours here or the hour here to offset. So, now I can test any of these things. So, now I can test any of these things. So, now I can test any of these things. Good early morning, good morning, good Good early morning, good morning, good Good early morning, good morning, good afternoon, good evening, good night. And afternoon, good evening, good night. And afternoon, good evening, good night. And as well as these dates. So, if we run as well as these dates. So, if we run as well as these dates. So, if we run this now, we'll see that we not only this now, we'll see that we not only this now, we'll see that we not only have two tests passing, we have 11 tests have two tests passing, we have 11 tests have two tests passing, we have 11 tests passing, and we verified all these passing, and we verified all these passing, and we verified all these different things because we can fake different things because we can fake different things because we can fake what the the time is of the test that's what the the time is of the test that's what the the time is of the test that's running. So, our code still runs the running. So, our code still runs the running. So, our code still runs the same. We still have the same values, same. We still have the same values, same. We still have the same values, good night and false. But, because of good night and false. But, because of good night and false. But, because of the fact that we are able to fake this, the fact that we are able to fake this, the fact that we are able to fake this, we can now test different scenarios in we can now test different scenarios in we can now test different scenarios in our code. Okay? So, that's how to use our code. Okay? So, that's how to use our code. Okay? So, that's how to use the time provider in C sharp.
Summary
This tech transcript focuses on utilizing C#'s time provider for easier code testing, specifically demonstrating how to test date and time-dependent logic like time-of-day messages and leap year calculations. The practical takeaway is that while the time provider facilitates testing, the presented examples can be deceptive if not run within the correct temporal context, highlighting the importance of understanding the underlying mechanisms.