First I searched for an Xamarin.iOS equivalent for rangeOfUnit:inUnit:forDate:, but it seems there is none. I want to translate this code
NSRange rangeOfWeeks = [self.calendar rangeOfUnit:NSWeekCalendarUnit inUnit:NSMonthCalendarUnit forDate:firstOfMonth];
but there is no rangeOfUnit:inUnit:forDate in Xamarin.iOS. There are implementations like this
public static int Weeks(int year, int month)
{
DayOfWeek wkstart = DayOfWeek.Monday;
DateTime first = new DateTime(year, month, 1);
int firstwkday = (int)first.DayOfWeek;
int otherwkday = (int)wkstart;
int offset = ((otherwkday + 7) - firstwkday) % 7;
double weeks = (double)(DateTime.DaysInMonth(year, month) - offset) / 7d;
return (int)Math.Ceiling(weeks);
}
, but here partial weeks are not counted. I also think that you loss a part of the localization (no NSCalendar, ...), but that is another story.
How can I calculate the number of weeks in a month? If the month starts in the mid of a week it should count as full week. It should also counts as full week if the month ends in the mid of a week.
Looks like you are after the week number. If that is the case the below code gets it.
nint era, year, weekOfYear, weekday;
NSCalendar.CurrentCalendar.GetComponentsFromDateForWeekOfYear(out era, out year, out weekOfYear, out weekday, NSDate.Now);
System.Diagnostics.Debug.WriteLine(weekOfYear);
var weekOfMonth = NSCalendar.CurrentCalendar.GetComponentFromDate(NSCalendarUnit.WeekOfMonth, NSDate.Now);
System.Diagnostics.Debug.WriteLine(weekOfMonth);
Today's week is #11 and it's the 2nd week of the month.
Related
so the problem is this: I managed to get the number of weeks that make up a month (for example: May 2022 is made up of 6 weeks counting from day 1 to day 31 without exception). So having the number of weeks that make up a month I need to know, knowing also the number of the month and the year, which will be the first and last day of the selected week.
I tried to do some research but I only find solutions that use the Calendar.GetWeekOfYear method but, as I said before, I have the week number for the single month not the total for the year.
I hope you can help me. Thanks in advance.
If I understood correctly it should look something like this
var week = 2;
var month = 5;
var year = 2022;
var firstDayOfMonth = new DateTime(year, month, 1);
var dayOfWeek = firstDayOfMonth.DayOfWeek;
var diffToMonday = (7 + (dayOfWeek - DayOfWeek.Monday)) % 7;
var firstMonday = firstDayOfMonth.AddDays(-diffToMonday);
var requestedMonday = firstMonday.AddDays(7 * (week - 1));
var requestedSunday = firstMonday.AddDays(7 * week - 1);
In Windows 10 calendar, as an example, we find an grid of 7x6 days that represents each day of the month, but is obvious that no month has 42 days, so "overflowed" days, by any means, the days that show in the grid but isn't of current month is greyed out as a day of another month. Is there some easy way to get these days on C# with DateTime class?
For example, in 2020/08, the "greyed days" is: 26, 27, 28, 29, 30, 31 (days of the previous month) and 1, 2, 3, 4, 5 (days of the next month).
In case that isn't clear, this is a screenshot showing the days that i'm referring
I couldn't find any question that relates my question.
Edit:
The best answer is by #ChilliPenguin, this is my implementation:
public static MonthGrayDays GrayDays(this DateTime time) {
List<DateTime> before = new List<DateTime>();
List<DateTime> after = new List<DateTime>();
DateTime firstDay = new DateTime(time.Year, time.Month, 1);
DateTime prevMonth = firstDay.AddDays(-1);
DateTime nextMonth = firstDay.AddMonths(1);
int daysInMonth = DateTime.DaysInMonth(time.Year, time.Month);
for (int a = 0; a < (int)firstDay.DayOfWeek; a++)
{
before.Add(prevMonth.AddDays(-a));
}
before.Reverse();
int count = before.Count();
for (int b = 0; b < 42 - count - daysInMonth; b++)
{
after.Add(nextMonth.AddDays(b));
}
return new MonthGrayDays {previousMonth = before, nextMonth = after};
}
This is an Extension method of DateTime class, it returns a custom class that returns the dates before and after the month, the class is implemented as follow:
public class MonthGrayDays {
public List<DateTime> previousMonth;
public List<DateTime> nextMonth;
}
To use the extension method, just call:
DateTime now = new DateTime(2020, 8, 1);
foreach (DateTime date in now.GrayDays().previousMonth) {
Console.WriteLine(date.Day);
}
Console.WriteLine("/");
foreach (DateTime date in now.GrayDays().nextMonth) {
Console.WriteLine(date.Day);
}
I don't think there's an automatic solution, but the logic is simple enough to step through. The most important thing is the DateTime.DayOfWeek property. It returns a DayOfWeek enum value corresponding to Sunday through Saturday which can be cast to an int ranging from 0 to 6 accordingly.
Take your month and construct a DateTime object corresponding to the 1st of the month. Now take its DayOfWeek and cast to int, and now you have the number of grey days at the top of the calendar. Getting the number from the end of the month is equally simple. Build a DateTime object for the last day of the month and cast its DayOfWeek to an int and subtract from 6 to get the number of grey days.
If you need to dates for those grey days, start at first day of the month and subtract 24 hours to get the last day of the previous month. The grey days for the end of the calendar can be assumed to start at 1.
Using the DateTime and DateTimeOffset Structs you could calculate for the first day of the month's type of day using the Day of week function. This would return an enum. If you convert the enum to an int(note, 0 = sunday, which does correlate with the windows calender) you would be able to loop back to get those dates. I would recommend using a List to store these dates, but I do not know your current situation :)
for (int a = 0; a < (int)FirstDay.DayOfWeek; a++)
{
graydays.Add(prevmonth.AddDays(-a));
}
To get the dates after the current month we could get the count of the days listed, the number of days in the month, and the grid area(42 in this case) to calculate the amount of days after the month that we need to consider.
int count = graydays.Count();
for (int b = 0; b < 42 - count - daysinmonth; b++)
{
graydays.Add(LastDayOfMonth.AddDays(b));
}
Note, To get the daysinmonth, you need to use the DateTime.DaysInMonth() function, and to get the Last day, just add 1 month to the first day, and then subtract a day.
This question already has answers here:
C# - How to calculate the current day-of-year?
(5 answers)
Closed 5 years ago.
I have an application that requires me to get the following:
int doy // Day of the year
int yr // Two digit year
int mon // Two digit month (zero on left for small numbers)
int day // Two digit day (zero on left for small numbers)
Can anyone tell me how I can get these numbers using C#?
System.DateTime moment = new System.DateTime.Now;
int year = moment.Year;
int month = moment.Month;
int day = moment.Day;
int hour = moment.Hour;
int minute = moment.Minute;
int second = moment.Second;
int millisecond = moment.Millisecond;
Have a look here: MSDN Documentation - DateTime
like this
Console.WriteLine(DateTime.Now.DayOfYear); // day of year
Console.WriteLine(DateTime.Now.Month); // month of year
Console.WriteLine(DateTime.Now.Year); // year
Calculate week of year based on culture if the week start on Monday because other culture does not start on Monday like Arabic
int day = DateTime.Now.DayOfYear;
var week = CultureInfo.CurrentCulture.Calendar.GetWeekOfYear(DateTime.Now, CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Monday);
easy way to get week number is
Console.WriteLine( System.Globalization.DateTimeFormatInfo.CurrentInfo.Calendar.GetWeekOfYear(DateTime.Now, CalendarWeekRule.FirstDay, DayOfWeek.Monday));
To get the numbers with 0 padded on left, you will have to use string format.
int doy = DateTime.Now.DayOfYear;// Day of the year
string yr = DateTime.Now.ToString("yy");// Two digit year
string mon = DateTime.Now.Month.ToString("d2"); // Two digit month (zero on left for small numbers)
string day = DateTime.Now.Day.ToString("d2"); // Two digit day (zero on left for small numbers)
Console.WriteLine(doy);
Console.WriteLine(yr);
Console.WriteLine(mon);
Console.WriteLine(day);
I am looking for some logic to get the date after N months having same day(Ex:Wednesday) and same week(ex: first or second...) of a given date.
ex: 12-06-2013(Wednesday & 3rd week of June) is the given date.
here I am adding 3 months to the given date.
the result should be is 14-Aug-2013(Wednesday & 3rd week of Aug).
please let me know if you need more clarification.
Thanks In advance.
Okay, so I'd personally use my Noda Time library to do this. It's entirely possible to do this with DateTime, but I'd personally find it harder. I'd also encourage you to use Noda Time in general, of course, as a better date/time API. So I'd have something like:
static LocalDate AddMonthsPreserveWeekDayAndWeek(LocalDate start, int months)
{
// This isn't the week of month in the "normal" sense; it's the nth
// occurrence of this weekday.
int week = ((start.DayOfMonth - 1) / 7) + 1;
// This will usually give the same day of month, but truncating where
// necessary
LocalDate monthsAdded = start.AddMonths(months);
LocalDate endOfPreviousMonth = monthsAdded.AddDays(-monthsAdded.Day);
// Get to the first occurrence of the right day-of-week
LocalDate firstRightDay = endOfPreviousMonth.Next(start.IsoDayOfWeek);
// Usually this will be right - but it might overflow to the next month,
// in which case we can just rewind by a week.
LocalDate candidate = firstRightDay.PlusWeeks(week - 1);
return candidate.Month == firstRightDay.Month ? candidate
: candidate.PlusWeeks(-1);
}
This is completely untested though - you should absolutely have a bunch of unit tests (ideally which you write before even including this code) which test all kinds of edge cases you're interested in.
Using standard MDSN year = 2013 month = 06 date = 12
1) Get day of the week from the specific date (Sunday is 0)
DateTime dateValue = new DateTime(year, month, date);
Console.WriteLine((int) dateValue.DayOfWeek); // Displays 3 implying it is Wed
2) Get the week of the month from the specific date
DayofWeek = 3 (from previous calculation)
Day = 12
EndOfWeek = Day + (6 - DayOfWeek) = 12 + 4 = 16
NoWeek = 0
while (EndOfWeek > 0)
{
EndOfWeek -= 7;
NoWeek++;
}
=> NoWeek = 3
3) Get first date after N month
DateTime newDate = new DateTime(year, month, 1)
newDate.AddMonths(N); // Let it be 2 => August 1, 2013
4) Get the day of the week for the new date
newDay = newDate.DayOfWeek // Return 4 implying Thursday
5) Get the last day after NoWeek
newDate.AddDays(6-newDay) => newDate.AddDays (6-4) => August 3,2013
NoWeek--;
while (NoWeek > 1)
{
newDate.AddDays(7);
NoWeek--;
}
=> newDate will be Augus 10,2013
6) Calculte required date
newDate.AddDays(DayofWeek) =>newDate will be August 14,2013
I am currently writing a small calendar in ASP.Net C#. Currently to produce the rows of the weeks I do the following for loop:
var iWeeks = 6;
for (int w = 0; w < iWeeks; w++) {
This works fine, however, some month will only have 5 weeks and in some rare cases, 4.
How can I calculate the number of rows that will be required for a particular month?
This is an example of what I am creating:
As you can see for the above month, there are only 5 rows required, however. Take the this month (August 2008) which started on a Saturday and ends on a Monday on the 6th Week/Row.
Image found on google
This is an example of what I am creating:
As you can see for the above month, there are only 5 rows required, however. Take the this month (August 2008) which started on a Saturday and ends on a Monday on the 6th Week/Row.
Image found on google
Here is the method that does it:
public int GetWeekRows(int year, int month)
{
DateTime firstDayOfMonth = new DateTime(year, month, 1);
DateTime lastDayOfMonth = new DateTime(year, month, 1).AddMonths(1).AddDays(-1);
System.Globalization.Calendar calendar = System.Threading.Thread.CurrentThread.CurrentCulture.Calendar;
int lastWeek = calendar.GetWeekOfYear(lastDayOfMonth, System.Globalization.CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Monday);
int firstWeek = calendar.GetWeekOfYear(firstDayOfMonth, System.Globalization.CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Monday);
return lastWeek - firstWeek + 1;
}
You can customize the calendar week rule by modifying the System.Globalization.CalendarWeekRule.FirstFourDayWeek part. I hope the code is self explanatory.
Well, it depends on the culture you're using, but let's assume you can use Thread.CurrentThread.CurrentCulture, then the code to get the week of today would be:
Culture culture = Thread.CurrentThread.CurrentCulture;
Calendar cal = culture.Calendar;
Int32 week = cal.GetWeekOfYear(DateTime.Today,
culture.DateTimeFormat.CalendarWeekRule,
culture.DateTimeFormat.FirstDayOfWeek);
How about checking which week the first and last days will be in?
you can get the days of a month by using DateTime.DaysInMonth(int WhichYear,int WhichMonth);
The months in the Julian / Gregorian calendar have the same number of days each year, except February who can have 28 or 29 days depending on the leapness of the year. You can find the number of days in the Description section at http://en.wikipedia.org/wiki/Gregorian_calendar.
As #darkdog mentioned you have DateTime.DaysInMonth. Just do this:
var days = DateTime.DaysInMonth(year, month) +
WhatDayOfWeekTheMonthStarts(year, month);
int rows = (days / 7);
if (0 < days % 7)
{
++rows;
}
Take into consideration the fact that for globalization / localization purposes, some parts of the world use different calendars / methods of organization of the year.
The problem isn't the number of days in the month, it's how many weeks it spans over.
February in a non-leap year will have 28 days, and if the first day of the month is a monday, february will span exactly 4 week numbers.
However, if the first day of the month is a tuesday, or any other day of the week, february will span 5 week numbers.
A 31 day month can span 5 or 6 weeks the same way. If the month starts on a monday, the 31 days gives you 5 week numbers. If the month starts on saturday or sunday, it will span 6 week numbers.
So the right way to obtain this number is to find the week number of the first and last days of the month.
Edit #1: Here's how to calculate the number of weeks a given month spans:
Edit #2: Fixed bugs in code
public static Int32 GetWeekForDateCurrentCulture(DateTime dt)
{
CultureInfo culture = Thread.CurrentThread.CurrentCulture;
Calendar cal = culture.Calendar;
return cal.GetWeekOfYear(dt,
culture.DateTimeFormat.CalendarWeekRule,
culture.DateTimeFormat.FirstDayOfWeek);
}
public static Int32 GetWeekSpanCountForMonth(DateTime dt)
{
DateTime firstDayInMonth = new DateTime(dt.Year, dt.Month, 1);
DateTime lastDayInMonth = firstDayInMonth.AddMonths(1).AddDays(-1);
return
GetWeekForDateCurrentCulture(lastDayInMonth)
- GetWeekForDateCurrentCulture(firstDayInMonth)
+ 1;
}
Try this,
DateTime.DaysInMonth
First Find out which weekday the first day of the month is in. Just new up a datetime with the first day, always 1, and the year and month in question, there is a day of week property on it.
Then from here, you can use the number of days in the month, DateTime.DaysInMonth, in order to determine how many weeks when you divide by seven and then add the number of days from 1 that your first day falls on. For instance,
public static int RowsForMonth(int month, int year)
{
DateTime first = new DateTime(year, month, 1);
//number of days pushed beyond monday this one sits
int offset = ((int)first.DayOfWeek) - 1;
int actualdays = DateTime.DaysInMonth(month, year) + offset;
decimal rows = (actualdays / 7);
if ((rows - ((int)rows)) > .1)
{
rows++;
}
return rows;
}
Check Calendar.GetWeekOfYear. It should do the trick.
There is a problem with it, it does not follow the 4 day rule by ISO 8601, but otherwise it is neat.