Date difference from Noda Time is correct? - c#

DateTime dtStart = new DateTime(2015,7,28);
LocalDate ldtStart = LocalDate.FromDateTime(dtStart);
DateTime dtEnd = new DateTime(2017, 2, 1);
LocalDate ldtEnd = LocalDate.FromDateTime(dtEnd);
Period period = Period.Between(ldtStart, ldtEnd, PeriodUnits.YearMonthDay);
Result for above:
period.Years -> 1
period.Months -> 6
period.Days -> 4
As you can see the difference i got from Noda Time library.
But i get different result for https://www.easycalculation.com/date-day/age-calculator.php
Result for above link:
1 years, 6 months, and 1 days
Start Date: 28th July 2015
End Date: 1st Feb 2017
Can someone please tell me that the result i got from noda time plugin is more accurate then the link I provided?

"More accurate" requires a specification of how you want to compute the difference. There's no single right answer here. As documented, Noda Time works element-wise. So if you add 1 year, 6 months and 4 days to 28th July 2015 you get:
Adding 1 year: 28th July 2016
Adding 6 months: 28th January 2017
Adding 4 days: 1st February 2017
The code used for the site is available on the site itself. It looks like that's taking a rather more naïve approach.
In particular, if you ask it how old someone born on January 31st 2017 is on February 1st 2017, they'll say they're -2 days old. I don't think that's right...

From 28th July 2015 to 1st August 2015 is 4 days and from 1st August 2015 to 1st Feb 2017 is exactly one and a half year.
NodaTime shows you correct information. You also could check with this link.
You could try to change in your link date from 28th July 2015 to 29th July 2015 or 30th July 2015 and you will see invalid input.

Related

How to get 29 Feb using AddYears method in c#

We use a job which runs every day and perform some action for a day one year ahead.
Actually we just use something like: DateTime.UtcNow.AddYears(1).
But it seems not possible to get a 29 February(e.g for 2020) using this technique:
var target = new DateTime(2020, 2, 29);
bool result = (target == target.AddYears(-1).AddYears(1));//false
So is it possible to target a 29 February in future somehow?
No. The Documentation states:
If value + DateTime.Year is also a leap year, the return value represents the leap day in that year. For example, if four years is added to February 29, 2012, the date returned is February 29, 2016.
If value + DateTime.Year is not a leap year, the return value represents the day before the leap day in that year. For example, if one year is added to February 29, 2012, the date returned is February 28, 2013.
This means if you add a year you will always get Feb 28th. The only way to get 29th via AddYears is if you add a multiple of 4.
No, this is by design.
If the current instance represents the leap day in a leap year, the
return value depends on the target date:
If value + DateTime.Year is also a leap year, the return value
represents the leap day in that year. For example, if four years is
added to February 29, 2012, the date returned is February 29, 2016.
If value + DateTime.Year is not a leap year, the return value
represents the day before the leap day in that year. For example, if
one year is added to February 29, 2012, the date returned is February
28, 2013.
1 year after 29th Feb 2020 should be 28th Feb 2021 since it is not a leap year. But in such a case, all the years after 2021 will work as a 28th February.
Other than this, ask yourself, what is the meaning of a "year" for you? How many days in a month? How many days in a year? Is it 365? 366? Or as wikipedia stated 365.2425? Also, which calendar we are talking about?
Frameworks, libraries etc.. does not work like people think. They work based on a set of rules that defined before. .NET Framework defined this rule as such. So, when you add a year to a DateTime instance, what they decide is month part has to stay same, year part will change for how many years will be added, and the day part must be a valid one.
You could cheat the system a bit by taking "the day before march 1st" instead.
stub:
DateTime today = DateTime.UtcNow
if (today.month == 2)
{
if(today.day == 28 || today.day == 29)
{
today.AddDays(1).AddYears(1).AddDays(-1)
}
}
this converts your feb 28 on non-leapyears in march 1st, adds a year, and goes to the day before that.
If the next year also is not a leapyear, you will still get feb 28, but if next year is a leapyear, the result will be feb 29.
this does not deal yet with the situation that this year is a leapyear, as this code will then return febuary 27th instead though
Function that return the next 29. feb. Maybe it helps.
using System;
public class Program
{
public static DateTime NextTwentyNineFeb()
{
int year = DateTime.Now.Year;
while(true){
try{
var target = new DateTime(year, 2, 29);
Console.WriteLine(target);
return target;
}
catch
{
year++;
}
}
}
}
As NibblyPig stated, this isn't possible. However, if you are actually just looking for the end of the month, then you can use new DateTime(year, month + 1, 0).AddDays(-1)

C# DateTime AddDays off by one

Can anyone explain to me why this unit test is failing?
I scoured through MSDN expecting to find an explanation, for example I was expecting to find something like, "the starting day is not inclusive" etc. but I found no such statement. Therefore I am confused as to why this seems to be off by one day.
The following will result in Sept 29th. I am expecting Sept 30th.
[Test]
public void AddDaysBug_OffByOne()
{
DateTime end = new DateTime(2018,10,3);
DateTime fourDaysEarlier = end.AddDays(-4);
// this fails. 29!=30
Assert.AreEqual(fourDaysEarlier.Day,30, "four days prior to October 3 is Sept 30");
}
Lets take these days one at a time for illustration...
3rd - 1 = 2nd
2nd - 1 = 1st
1st - 1 = 30th
30th - 1 = 29th
There is no zero day in months as with "normal" numbers.
Setp: 28, 29, 30
Oct: 1, 2, 3
So: (3 Oct - 4 day) is equal to 29
Sept 29th seems to be correct answer.
It's easy to see if you subtracting one day at a time.
-1 day, 10/02/2018
-2 day, 10/01/2018
-3 day, 09/30/2018
-4 day, 09/29/2018

Windows form setting datetimepicker to 31st march of every year

private void dateTimePicker1_ValueChanged(object sender, EventArgs e)
{
}
Right now the code display current date in the date time picker.
How do I display 31st March in 2017 and once it is 2018, it will display 31st March 2018 and so on and so forth as the year progress
Anyone help would be greatly appreciated
int currentYear = DateTime.Today.Year;
DateTime desiredDate = new DateTime(currentYear, 3, 31);
Additional info: apparently Asker doesn't know class DateTime
You asked:
How do I display 31st March in 2017 and once it is 2018, it will
display 31st March 2018 and so on and so forth as the year progress
This is a difficult way to say that you want 31 march of the current year (= the year of Today)
DateTime.Today fetches the date of Today (surprise, surprise!)
Property Year contains the Year of Today
On 15th November 2017, Year was 2017
new DateTime(currentYear, 3, 31) will make the date of 31st March of the current year (which in my example was 2017
Surely you did read the documentation of the DateTime structure, didn't you?

DateTimePicker updown February missing

I have a dateTimePicker created, and I only want to select month and year. So, I put the following code:
dateTimePicker2.Format = DateTimePickerFormat.Custom;
dateTimePicker2.CustomFormat = "MM yyyy";
dateTimePicker2.ShowUpDown = true;
Whenever I scroll with the arrow through the months, once it gets to February, the value is blank, instead of February.
I also tried customformats MMM and MMMM, but retain the same problem. I tried different years, but every year does not show February. I also tried to put a new datetimepicker, but continue having the same problem.
I can only select, without showUpDown = true, in the calendar, but still not with arrow up/down. It works without custom format, but I do not want to see the day, I only want to select month and year.
I'm using Visual Studio 2010 Ultimate (10.0.40219.1.SP1). .NET Framework 4.0.30319 SP1.
When the user select value by the up-down buttons or arrow keys, the DateTimePicker won't change the value of the element which is not included in its custom format.
I guess your dateTimePicker2 initially has the value of Now whose day of month is 29 or 30, hence the error on February.
I recommend you set 1 to dateTimePicker2.Value.Day beforehand.
Well, the problem really has to do with the fact that 02/29 will only be valid date on leap years. To prove this, scroll to 2012 and then scroll to 02. You'll have to implement code to catch an invalid value and either notify a user or move to 03/01.
DateTime has a method that lets you find out if a year is a leap year, so that you wouldn't have to jump through hoops: DateTime.IsLeapYear(year), where year is an int.
Here's a short list of leap years for your reference:
Leap Years (1800 - 2400)
1804 1808 1812 1816 1820 1824 1828 1832 1836 1840 1844 1848 1852 1856
1860 1864 1868 1872 1876 1880 1884 1888 1892 1896 1904 1908 1912 1916
1920 1924 1928 1932 1936 1940 1944 1948 1952 1956 1960 1964 1968 1972
1976 1980 1984 1988 1992 1996 2000 2004 2008 2012 2016 2020 2024 2028
2032 2036 2040 2044 2048 2052 2056 2060 2064 2068 2072 2076 2080 2084
2088 2092 2096 2104 2108 2112 2116 2120 2124 2128 2132 2136 2140 2144
2148 2152 2156 2160 2164 2168 2172 2176 2180 2184 2188 2192 2196 2204
2208 2212 2216 2220 2224 2228 2232 2236 2240 2244 2248 2252 2256 2260
2264 2268 2272 2276 2280 2284 2288 2292 2296 2304 2308 2312 2316 2320
2324 2328 2332 2336 2340 2344 2348 2352 2356 2360 2364 2368 2372 2376
2380 2384 2388 2392 2396 2400
If you think about it, you got really lucky with that bug. What are the odds that you'll be testing that control on 29, which is not a valid day for February of this year... You'll be able to fix it now and not when a user sends a report.

GetWeekOfYear returns wrong result?

Week 1 of 2013 starts 31-12-2012 since it's a monday.
A call to GetWeekOfYear with culture nl-NL, FirstDayOfWeek.Monday and CalendarWeekRule.FirstFourDayWeek returns week number 53 for monday 31-12-2012 and week 1 for tuesday 1-1-2013. How can that monday have a different week number than tuesday?
Am i missing something?
Because it's week 53 of 2012. It will return the week of the year passed in, based on the date you use (31-12-2012). Week 1 of 2013 is the same week as week 53 of 2012.
The year you have passed in your first example is 2012. Not 2013. It's returning the week of the year you have passed in your date.

Categories

Resources