How to find the remains date of a month from a date? - c#

I have a date '2015-01-25'. How to get the remains date of Jan 2015. Is there any built in function to achieve this in c#
remains days ie, '2015-01-26','2015-01-27','2015-01-28','2015-01-29','2015-01-30','2015-01-31' etc..

Get Today
var today = DateTime.Now;
Get the first day of next month
var firstDayNextMonth = new DateTime(DateTime.Now.Year, DateTime.Now.AddMonths(1).Month, 1);
Create a list of the days between today and first day of next month (Enumerable.Range) Loop through the list and turn them into dates (Select) by adding each int to today
var dates = Enumerable.Range(0, firstDayNextMonth.Subtract(today).Days + 1)
.Select(d => today.AddDays(d))
.ToList();

If you want to find remaining days till next month, then you can add a day to the current DateTime in loop and check if the month of the new DateTime is same with yours. If the new DateTime met the condition, then add it to the list. If not, then break the loop.
You will use DateTime.AddDays() method which returns a new DateTime that adds the specified number of days to the value of this instance.
DateTime myDateTime = new DateTime(2015, 1, 25);
var remainedDateTimesToNextMonth = new List<DateTime>();
var nextDay = myDateTime;
while(true)
{
nextDay = nextDay.AddDays(1);
if (nextDay.Month == myDateTime.Month)
{
remainedDateTimesToNextMonth.Add(nextDay);
}
else break;
}
And int the result there would be six item inside remainedDateTimesToNextMonth list:
2015-01-26,2015-01-27,2015-01-28,2015-01-29,2015-01-30,2015-01-31

You can use DateTime.DaysInMonth(year, month) to get total days in months, and subtract the current day of month.
DateTime someDate = new DateTime(2015,1,25);
var remaining = DateTime.DaysInMonth(2015, 1) - someDate.Day;
Then you know the amount of remaining days for that given month, and can set up remaining dates in a list using an for loop.
List<DateTime> remainingDays = new List<DateTime>();
for (int i = 1; i <= remaining; i++)
{
remainingDays.Add(someDate.AddDays(i));
}

Related

How to select weekends with an interval between them?

How can I select all weekends until the end of the year, with some criteria to be followed?
User input desired Weekend day:
18/12/2021
Software must out:
25/12/2022 (must be ignored)
01/01/2022
08/01/2022 (must be ignored)
15/01/2022
22/01/2022 (must be ignored)
29/01/2022 and so on...
What i have now:
public void GetWeekends() {
var lastWorkedWeekend = dateTimePicker1.Value;
var workedInSunday = checkBox1.Checked;
var list = new List < DateTime > ();
var weekends = GetDaysBetween(lastWorkedWeekend, DateTime.Today.AddDays(365)).Where(d => d.DayOfWeek == DayOfWeek.Saturday);
var selected = true;
for (int i = 0; i < weekends.Count(); i++) {
if (selected == false) {
list.Add(weekends.ElementAt(i));
selected = true;
} else {
selected = false;
}
}
}
I think I'd just scroll the input day forward until it was saturday (or calculate it, but i find the loop more self documenting than casting DayOfWeek to an int and factoring for sunday being 0) then add 14 days repeatedly. This skips over the 25th, etc..
var d = new DateTime(2021, 12, 18);
while(d.DayOfWeek != DayOfWeek.Saturday)
d += TimeSpan.FromDays(1);
while(d.Year == 2021){ //was your 2022 a typo? or maybe make this <= 2022.. I'm not sure what you want there..
d += TimeSpan.FromDays(14);
Console.WriteLine(d);
}
You might prefer DateTime.AddDays()..
Looks to me that you want to get the date of every second weekend from an initial date until the end of the year. In your example, you kinda bleed over to the next year.
public static void Main()
{
var dates = GetDateTimeRange(new DateTime(2021, 12, 18), new DateTime(2023, 1, 1), TimeSpan.FromDays(14));
foreach (var dateTime in dates.Skip(1))
{
Console.WriteLine(dateTime);
}
}
public static IEnumerable<DateTime> GetDateTimeRange(DateTime startingDate, DateTime endDate, TimeSpan interval)
{
var lastDate = startingDate;
while (lastDate < endDate)
{
yield return lastDate;
lastDate = lastDate.Add(interval);
}
}
This returns
01/01/2022 00:00:00
01/15/2022 00:00:00
01/29/2022 00:00:00
02/12/2022 00:00:00
02/26/2022 00:00:00
03/12/2022 00:00:00
03/26/2022 00:00:00
04/09/2022 00:00:00
04/23/2022 00:00:00
05/07/2022 00:00:00
05/21/2022 00:00:00
06/04/2022 00:00:00
06/18/2022 00:00:00
07/02/2022 00:00:00
07/16/2022 00:00:00
07/30/2022 00:00:00
08/13/2022 00:00:00
08/27/2022 00:00:00
09/10/2022 00:00:00
09/24/2022 00:00:00
10/08/2022 00:00:00
10/22/2022 00:00:00
11/05/2022 00:00:00
11/19/2022 00:00:00
12/03/2022 00:00:00
12/17/2022 00:00:00
12/31/2022 00:00:00
One approach is to use a method that creates an enumerable of dates. Once that's done you can use LINQ queries. If creating that enumerable is expensive you could just create one large range encompassing years and re-use it.
Or you might find better performance by just creating the range you need for each query.
public static class DateRanges
{
public static IEnumerable<DateOnly> GetRange(DateOnly start, DateOnly end)
{
for (var date = start; date <= end; date = date.AddDays(1))
{
yield return date;
}
}
}
It's not clear from your code what the criteria is, but this does what you described - all weekends from now to the end of the year.
var today = DateOnly.FromDateTime(DateTime.Today);
var lastDayOfYear = DateOnly.FromDateTime(new DateTime(DateTime.Today.Year, 12, 31));
var dates = DateRanges.GetRange(today, lastDayOfYear);
var weekendsOnly = dates.Where(date =>
date.DayOfWeek == DayOfWeek.Saturday);
Or if you prefer to create one date range and query it repeatedly:
// Big range of dates, 10 years into past and future.
// Create this once and re-use it
var dates = DateRanges.GetRange(
DateOnly.FromDateTime(DateTime.Today.AddYears(-10)),
DateOnly.FromDateTime(DateTime.Today.AddYears(10)));
var today = DateOnly.FromDateTime(DateTime.Today);
var lastDayOfYear = DateOnly.FromDateTime(new DateTime(DateTime.Today.Year, 12, 31));
var weekendsOnly = dates.Where(date =>
date >= today
&& date <= lastDayOfYear
&& date.DayOfWeek == DayOfWeek.Saturday);
In either case if you want every other Saturday you can add
.Where((date, i) => i % 2 == 0);
Or to maintain that readability you could put that in another extension like
public static IEnumerable<T> EveryOther<T>(this IEnumerable<T> source)
{
return source.Where((date, i) => i % 2 == 0);
}
so your query looks like
var everyOtherWeekend = dates
.Where(date =>
date >= today
&& date <= lastDayOfYear
&& date.DayOfWeek == DayOfWeek.Saturday)
.EveryOther();
I wouldn't position this as a better answer than those that iterate over a series of dates. The difference is that instead of having to write a method for any query you can start with a range of dates and then use LINQ to filter it. That makes it a little easier to read and to compose different queries.

Get all the dates of current week

Say I consider Sunday - Saturday as a week, how do I get all the dates of the current week in c#?
For example, current date is 30th March 2017, the output I need is,
26-March-2017,
27-March-2017,
28-March-2017,
29-March-2017,
30-March-2017,
31-March-2017,
01-April-2017
You can try DateTimeFormat to find out current week's starting date and Linq to generate the string:
DateTime startOfWeek = DateTime.Today.AddDays(
(int) CultureInfo.CurrentCulture.DateTimeFormat.FirstDayOfWeek -
(int) DateTime.Today.DayOfWeek);
string result = string.Join("," + Environment.NewLine, Enumerable
.Range(0, 7)
.Select(i => startOfWeek
.AddDays(i)
.ToString("dd-MMMM-yyyy")));
In case of en-US culture you'll get (week starts from Sunday)
26-March-2017, // <- starts from Sunday
27-March-2017,
28-March-2017,
29-March-2017,
30-March-2017,
31-March-2017,
01-April-2017
In case of, say, ru-RU culture you'll get (week starts from Monday)
27-марта-2017, // <- Starts from Monday
28-марта-2017,
29-марта-2017,
30-марта-2017,
31-марта-2017,
01-апреля-2017,
02-апреля-2017
Assuming that Sunday will be the start day of the week, as it is mentioned in the question I suggest following solution.
var today = DateTime.Now.Date; // This can be any date.
Console.WriteLine(today.DayOfWeek);
var day = (int)today.DayOfWeek; //Number of the day in week. (0 - Sunday, 1 - Monday... and so On)
Console.WriteLine(day);
const int totalDaysOfWeek = 7; // Number of days in a week stays constant.
for (var i = -day; i < -day + totalDaysOfWeek; i++)
{
Console.WriteLine(today.AddDays(i).Date);
}
I found this here
DayOfWeek Day = DateTime.Now.DayOfWeek;
int Days = Day - DayOfWeek.Monday; //here you can set your Week Start Day
DateTime WeekStartDate = DateTime.Now.AddDays(-Days);
DateTime WeekEndDate1 = WeekStartDate.AddDays(1);
DateTime WeekEndDate2 = WeekStartDate.AddDays(2);
DateTime WeekEndDate3 = WeekStartDate.AddDays(3);
DateTime WeekEndDate4 = WeekStartDate.AddDays(4);
DateTime WeekEndDate5 = WeekStartDate.AddDays(5);
DateTime WeekEndDate6 = WeekStartDate.AddDays(6);
In my opinion, an extension method is the most useful approach:
public static IEnumerable<DateTime> GetDatesOfWeek(this DateTime date, CultureInfo ci) {
Int32 firstDayOfWeek = (Int32) ci.DateTimeFormat.FirstDayOfWeek;
Int32 dayOfWeek = (Int32) date.DayOfWeek;
DateTime startOfWeek = date.AddDays(firstDayOfWeek - dayOfWeek);
var valuesDaysOfWeek = Enum.GetValues(typeof(DayOfWeek)).Cast<Int32>();
return valuesDaysOfWeek.Select(v => startOfWeek.AddDays(v));
}
Use as follows:
DateTime myDate = DateTime.Today;
IEnumerable<DateTime> result = myDate.GetDatesOfWeek(CultureInfo.CurrentCulture);
foreach ( DateTime d in result ) {
Console.WriteLine(d);
}

Parallel.For with date time

OK this code is a bit meta but it roughly explains how i have it now and what i want to achieve.
specialObject{
DateTime date;
int number;
}
var startDate = Lowest date in the list;
var endDate = Hightest date int the list;
List<SpecialObject> objs = (list from database where date > startDate and date < endDate)
//A list with alot of dates and numbers, most of the dates are the same. List contains roughly 1000 items, but can be more and less.
for(var date = startDate; date < endDate; date = date.AddDay(1){
listItem = objs.Where(x => x.Day = date).Sum(x => x.alotOfNUmbers);
}
Now since i don't care what day i calculate first, i thought i could do this.
Parallel.For(startDate, endDate, day => {
listItem = objs.Where(x => x.Day = date).Sum(x => x.alotOfNUmbers);
}
But how do i make it step dates ?
You can make a Range and iterate over it with Parallel.ForEach :
// not tested
var days = Enumerable
.Range(0, (endDate-startDate).Days) // check the rounding
.Select(i => startDate.AddDays(i));
Parallel.ForEach(days, day => ....)
Alternatively, you could use PLinq over the original source, probably faster. Roughly:
// not tested
var sums = objs.AsParallel().GroupBy(x => x.date).Select(g => g.Sum(i => i.number));
All the overloads of Parallel.For take two integer variables for start and end. I also don't see any version which would support something like a step so you can't just use the tick count of a DateTime as the loop variable.
But it should be easy to use a Parallel.ForEach instead, when you create an IEnumerable<DateTime> as the source sequence.
var source = Enumerable.Range(0, (endDate - startDate).Days)
.Select(t => startDate.AddDays(t));
Add +1 to the count parameter if the endDate is inclusive.
Ok after a few days search i figured if i placed all days in an array and "whiled" through it. It gives a pretty good result. With code easy to read
var start = new DateTime(2014, 09, 09);
var end = new DateTime(2014, 10, 01);
var listOfDays = new List<DateTime>();
int i = 0;
for (var day = start; day < end; day = day.AddDays(1))
{
listOfDays.Add(day);
}
Parallel.ForEach(listOfDays.ToArray(), currentDay =>
{
for (var d = new DateTime(currentDay.Year, currentDay.Month, currentDay.Day, 0, 0, 0); d < new DateTime(currentDay.Year, currentDay.Month, currentDay.Day, 23, 59, 59); d = d.AddSeconds(5))
{
var str = "Loop: " + i + ", Date: " + d.ToString();
Console.WriteLine(str);
}
i++;
});
Console.Read();

How to get All Dates in a given month in C#

I want to make a function that take month and year and return List<DateTime> filled with all dates in this month.
any help will be appreciated
Thanks in Advance
Here's a solution with LINQ:
public static List<DateTime> GetDates(int year, int month)
{
return Enumerable.Range(1, DateTime.DaysInMonth(year, month)) // Days: 1, 2 ... 31 etc.
.Select(day => new DateTime(year, month, day)) // Map each day to a date
.ToList(); // Load dates into a list
}
And one with a for-loop:
public static List<DateTime> GetDates(int year, int month)
{
var dates = new List<DateTime>();
// Loop from the first day of the month until we hit the next month, moving forward a day at a time
for (var date = new DateTime(year, month, 1); date.Month == month; date = date.AddDays(1))
{
dates.Add(date);
}
return dates;
}
You might want to consider returning a streaming sequence of dates instead of List<DateTime>, letting the caller decide whether to load the dates into a list or array / post-process them / partially iterate them etc. For the LINQ version, you can accomplish this by removing the call to ToList(). For the for-loop, you would want to implement an iterator. In both cases, the return-type would have to be changed to IEnumerable<DateTime>.
Sample for pre-Linq Framework versions, using February 1999.
int year = 1999;
int month = 2;
List<DateTime> list = new List<DateTime>();
DateTime date = new DateTime(year, month, 1);
do
{
list.Add(date);
date = date.AddDays(1);
while (date.Month == month);
I am sure there might be better ways to do this. But, you could use this:
public List<DateTime> getAllDates(int year, int month)
{
var ret = new List<DateTime>();
for (int i=1; i<=DateTime.DaysInMonth(year,month); i++) {
ret.Add(new DateTime(year, month, i));
}
return ret;
}
Here you go:
public List<DateTime> AllDatesInAMonth(int month, int year)
{
var firstOftargetMonth = new DateTime(year, month, 1);
var firstOfNextMonth = firstOftargetMonth.AddMonths(1);
var allDates = new List<DateTime>();
for (DateTime date = firstOftargetMonth; date < firstOfNextMonth; date = date.AddDays(1) )
{
allDates.Add(date);
}
return allDates;
}
Iterates through the dates from the first of the month you want through to the last date that's less than the first of the next month.
PS: If this is homework, please tag it with "homework"!

Get the previous month's first and last day dates in c#

I can't think of an easy one or two liner that would get the previous months first day and last day.
I am LINQ-ifying a survey web app, and they squeezed a new requirement in.
The survey must include all of the service requests for the previous month. So if it is April 15th, I need all of Marches request ids.
var RequestIds = (from r in rdc.request
where r.dteCreated >= LastMonthsFirstDate &&
r.dteCreated <= LastMonthsLastDate
select r.intRequestId);
I just can't think of the dates easily without a switch. Unless I'm blind and overlooking an internal method of doing it.
var today = DateTime.Today;
var month = new DateTime(today.Year, today.Month, 1);
var first = month.AddMonths(-1);
var last = month.AddDays(-1);
In-line them if you really need one or two lines.
The way I've done this in the past is first get the first day of this month
dFirstDayOfThisMonth = DateTime.Today.AddDays( - ( DateTime.Today.Day - 1 ) );
Then subtract a day to get end of last month
dLastDayOfLastMonth = dFirstDayOfThisMonth.AddDays (-1);
Then subtract a month to get first day of previous month
dFirstDayOfLastMonth = dFirstDayOfThisMonth.AddMonths(-1);
using Fluent DateTime https://github.com/FluentDateTime/FluentDateTime
var lastMonth = 1.Months().Ago().Date;
var firstDayOfMonth = lastMonth.FirstDayOfMonth();
var lastDayOfMonth = lastMonth.LastDayOfMonth();
DateTime LastMonthLastDate = DateTime.Today.AddDays(0 - DateTime.Today.Day);
DateTime LastMonthFirstDate = LastMonthLastDate.AddDays(1 - LastMonthLastDate.Day);
I use this simple one-liner:
public static DateTime GetLastDayOfPreviousMonth(this DateTime date)
{
return date.AddDays(-date.Day);
}
Be aware, that it retains the time.
An approach using extension methods:
class Program
{
static void Main(string[] args)
{
DateTime t = DateTime.Now;
DateTime p = t.PreviousMonthFirstDay();
Console.WriteLine( p.ToShortDateString() );
p = t.PreviousMonthLastDay();
Console.WriteLine( p.ToShortDateString() );
Console.ReadKey();
}
}
public static class Helpers
{
public static DateTime PreviousMonthFirstDay( this DateTime currentDate )
{
DateTime d = currentDate.PreviousMonthLastDay();
return new DateTime( d.Year, d.Month, 1 );
}
public static DateTime PreviousMonthLastDay( this DateTime currentDate )
{
return new DateTime( currentDate.Year, currentDate.Month, 1 ).AddDays( -1 );
}
}
See this link
http://www.codeplex.com/fluentdatetime
for some inspired DateTime extensions.
The canonical use case in e-commerce is credit card expiration dates, MM/yy. Subtract one second instead of one day. Otherwise the card will appear expired for the entire last day of the expiration month.
DateTime expiration = DateTime.Parse("07/2013");
DateTime endOfTheMonthExpiration = new DateTime(
expiration.Year, expiration.Month, 1).AddMonths(1).AddSeconds(-1);
If there's any chance that your datetimes aren't strict calendar dates, you should consider using enddate exclusion comparisons...
This will prevent you from missing any requests created during the date of Jan 31.
DateTime now = DateTime.Now;
DateTime thisMonth = new DateTime(now.Year, now.Month, 1);
DateTime lastMonth = thisMonth.AddMonths(-1);
var RequestIds = rdc.request
.Where(r => lastMonth <= r.dteCreated)
.Where(r => r.dteCreated < thisMonth)
.Select(r => r.intRequestId);
DateTime now = DateTime.Now;
int prevMonth = now.AddMonths(-1).Month;
int year = now.AddMonths(-1).Year;
int daysInPrevMonth = DateTime.DaysInMonth(year, prevMonth);
DateTime firstDayPrevMonth = new DateTime(year, prevMonth, 1);
DateTime lastDayPrevMonth = new DateTime(year, prevMonth, daysInPrevMonth);
Console.WriteLine("{0} {1}", firstDayPrevMonth.ToShortDateString(),
lastDayPrevMonth.ToShortDateString());
This is a take on Mike W's answer:
internal static DateTime GetPreviousMonth(bool returnLastDayOfMonth)
{
DateTime firstDayOfThisMonth = DateTime.Today.AddDays( - ( DateTime.Today.Day - 1 ) );
DateTime lastDayOfLastMonth = firstDayOfThisMonth.AddDays (-1);
if (returnLastDayOfMonth) return lastDayOfLastMonth;
return firstDayOfThisMonth.AddMonths(-1);
}
You can call it like so:
dateTimePickerFrom.Value = GetPreviousMonth(false);
dateTimePickerTo.Value = GetPreviousMonth(true);
var lastMonth = DateTime.Today.AddMonths(-1);
dRet1 = new DateTime(lastMonth.Year, lastMonth.Month, 1);
dRet2 = new DateTime(lastMonth.Year, lastMonth.Month, DateTime.DaysInMonth(lastMonth.Year, lastMonth.Month));

Categories

Resources