Get the week number from a date time [duplicate] - c#

This question already has answers here:
Get the correct week number of a given date
(20 answers)
Closed 4 years ago.
I am trying to get the week number from a date time and in my case, the first day of the week is Monday and I want to follow the FirstFourDays convention.
To check the results, I am checking this webpage:
https://espanol.epochconverter.com/semanas/2020
To get the week number, I using the method:
System.Globalization.CultureInfo.InvariantCulture.Calendar.GetWeekOfYear();
So I am trying to get the week number of the date 2019-12-29, so I use this code:
System.Globalization.CultureInfo.InvariantCulture.Calendar.GetWeekOfYear(new DateTime(2019, 12, 29), System.Globalization.CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Monday);
The result is week 52. It is correct.
Now I am trying to get the week number of the 2019-12-30, the week number that I get is 53, it is wrong, because 2019 has only 52 weeks. In fact, 2019-12-30 belongs to the same week than 2020-01-01, that it is week 1, that is correct, so I don't understand why I can get two different results for the same date.
How I could get the correct result always? Or how would it be the correct way to get the week number of any date?

There's a blog article explaining this behavior and proposing a solution.
The issue:
Several people have noticed that Calendar.GetWeekOfYear() is almost like the ISO 8601 week when passed CalendarWeekRule.FirstFourDayWeek and DayOfWeek.Monday, however it is a little bit different. Specifically ISO 8601 always has 7 day weeks. If the first partial week of a year doesn't contain Thursday, then it is counted as the last week of the previous year. Likewise, if the last week of the previous year doesn't contain Thursday then its treated like the first week of the next year. GetWeekOfYear() has the first behavior, but not the second.
The proposed solution would be this:
A simple workaround to consistently get the ISO 8601 week is to realize that consecutive days Monday through Sunday in ISO 8601 weeks all have the same week #. So Monday has the same week # as Thursday. Since Thursday is the critical day for determining when the week starts each year my solution is to add 3 days if the day is Monday, Tuesday or Wednesday. The adjusted days are still in the same week, and use values that GetWeekOfYear and ISO 8601 agree on.
// This presumes that weeks start with Monday.
// Week 1 is the 1st week of the year with a Thursday in it.
public static int GetIso8601WeekOfYear(DateTime time)
{
// Seriously cheat. If its Monday, Tuesday or Wednesday, then it'll
// be the same week# as whatever Thursday, Friday or Saturday are,
// and we always get those right
DayOfWeek day = cal.GetDayOfWeek(time);
if (day >= DayOfWeek.Monday && day <= DayOfWeek.Wednesday)
{
time = time.AddDays(3);
}
// Return the week of our adjusted day
return cal.GetWeekOfYear(time, CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Monday);
}
All credits for this go to Shawn Steele.

Related

How to Calculate DayOfWeek in Ms Excel

In MS Excel with US English culture, while checking the Day of the week for the Date "1/1/1900", it returns SUNDAY, whereas in DayofWeek property of DateTime, it returns MONDAY. Also, checked with the Calender, it shows DayOFWeek for the Date "1/1/1900" is Monday. Hence, can any one please explain the behavior of DayOfWeek in Excel?
January 1, 1990 was a Monday (https://en.wikipedia.org/wiki/January_1900#January_1,1900(Monday))
The "WEEKDAY" Excel function returns a number from 1 (Sunday) to 7 (Saturday) representing the day of the week of a date.
System.DayOfWeek is an enumeration going from 0 (Sunday) to 6 (Saturday) (https://learn.microsoft.com/en-us/dotnet/api/system.datetime.dayofweek?view=netframework-4.8)
You pointed out a well known problem. As explained here, https://support.microsoft.com/en-us/help/214326/excel-incorrectly-assumes-that-the-year-1900-is-a-leap-year
"The WEEKDAY function returns incorrect values for dates before March 1, 1900. Because most users do not use dates before March 1, 1900, this problem is rare."
See also this answer: https://superuser.com/a/481499

Get full date when DateTime.DayOfYear and Year is given

Is there a possibility to get the full date out of the year and the dayOfYear value?
For example: today is Thursday, 19th of february 2015.
The dayOfYear-Value of today is 50.
If I have the value 75 and the year 2010, how am I able to get the matching date?
It could be displayed in a textBox, dateTimePicker, whatever.
But you only have the information year & dayOfYear.
Thanks
You can use the following code:
DateTime day = New DateTime(2010, 1, 1).AddDays(75 - 1);
First get the first day of the year, then add necessary day count minus one (you are already on the first date of the year) days to the first day and you are there.

Get week number for the given date c#

I have tried searching for a solution which gives the correct week number for the date value.
link1, link2,link3
Followed the methods in the above links, but for the date 30/12/2014, I get the week number as 53. but it falls as 1st week of 2015 year.
I tried the below methods to get the week number of the year for the specific date.
private int GetWeekNumberOfTheYear() {
var currentCulture = CultureInfo.CurrentCulture;
// option 1
var weekNo = currentCulture.Calendar.GetWeekOfYear(DateTime.Now,currentCulture.DateTimeFormat.CalendarWeekRule, currentCulture.DateTimeFormat.FirstDayOfWeek);
// option 2
var weekNo = CultureInfo.InvariantCulture.Calendar.GetWeekOfYear(DateTime.Now, CalendarWeekRule.FirstDay, DayOfWeek.Monday);
return weekNo; }
Is the method above is correct to return 53 as week number or it should be 1 ?
Is there any mistake in the above code. Suggestions please.
EDIT :
Found many searches specified, Dec 29th 2014 to 4th Jan 2015 as 1st week of year 2015.
So my confusion is the present week must be taken as 53rd Week or 1st Week.
http://week-number.net/calendar-with-week-numbers-2014.html
http://www.epochconverter.com/date-and-time/weeknumbers-by-year.php
If you're looking for the ISO-8601 week-of-week-year, you could use my Noda Time project:
var date = new LocalDate(2014, 12, 30);
var week = date.WeekOfWeekYear; // 1
var weekYear = date.WeekYear; // 2015
You can get a LocalDate from a DateTime via a LocalDateTime, but ideally you'd use the Noda Time times as widely as possible through your project. (That's the way I'd hope you'd get the maximum benefit, anyway.)

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.

Best pattern for a monthly billing cycle

I wrote some code for my new billing system. The purpose is to bill the customer on the same day each month. (not the 1st or last day of the month)
static bool NeedToBill(DateTime planLastBilled, DateTime cycleDate)
{
// is today the same date as the cycleDate AND is was the planLastBilled not the same day as today?
if (DateTime.UtcNow.Day.Equals(cycleDate.Day) && !DateTime.UtcNow.Day.Equals(planLastBilled))
return true;
else
return false;
}
The 2 pitfalls are:
If his cycleDate.Day is the 31 and the current month only has 29 days
cycleDate is Feb 29 2012 - he will only get billed on leap years
Is there a common best practice here?
so it seems like there's a bunch things to check
has this account already been billed this month?
does the cycle day exists in the current month
is the cycle day greater than or equal to the current date (this is ideal if
the transaction failed the day before)
Thanks!
Only allow the choice of a billing day between 1 - 28. In my experience this is how most credit card / loan companies deal with it when given a choice.
What does the same day each month mean?
If I am a customer, I want to be billed on the 16th each month. No problem. If I want to be billed on the 31st on each month the obvious issue is not all months have 31 days as you've pointed out in your question.
Why not check the current month for the number of days. If it has less than 31 days, make the last day of the month the bill date.
Is there more to the problem?
I'd say make him choose between 1-28, or any day but charge on the last day on the month if the current month has less days than the chosen day of month.
Ok, I believe I have been totally over-thinking this.
This is simple and covers everything:
bool NeedToBill = ((DateTime.UTCNow – LastBillDate) >= 30 Days)
It will not necessarily bill on the exact same day, however it's close enough.
This also adds flexibility if the transaction was denied for a day, or if the scheduled task was not ran for 1 day the next time it runs it will pick it up.

Categories

Resources