Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 4 years ago.
Improve this question
In a C# windows form based application. I used two dateTime pickers,one for From and another for To.
if a employee selecting his leave from may 30 in dateTime picker1 and selecting june 2 in datetime picker2, that makes 4 days of leave.
My question is how can i findout how many days he took leave in may and how many days he took leave in june?
Update
I know this, and stuck further
DateTime start = dateTimePicker1.Value.Date;
DateTime end = dateTimePicker2.Value.Date;
int a = int.Parse(Convert.ToInt32(end.Subtract(start).Days).ToString());
you can try this code,
here at the end you will get a Dictionary (tabular form) where key will be month number and value is days of in month (here in your question, how many days employee has taken leave)
DateTime startDate = new DateTime(2018, 06, 25); //date time picker's date
DateTime endDate = new DateTime(2018, 07, 05); //date time picker's date
Dictionary<int, int> daysInMonth = new Dictionary<int, int>();
while(true)
{
DateTime thisMonthEndDate = new DateTime(startDate.Year, startDate.Month, DateTime.DaysInMonth(startDate.Year, startDate.Month));
if (thisMonthEndDate > endDate)
{
thisMonthEndDate = endDate;
daysInMonth.Add(startDate.Month, (int)(thisMonthEndDate - startDate).TotalDays + 1);
break;
}
daysInMonth.Add(startDate.Month, (int)(thisMonthEndDate - startDate).TotalDays + 1);
startDate = thisMonthEndDate.AddDays(1);
}
and output printing will be
foreach(KeyValuePair<int, int> keyVal in daysInMonth)
{
Console.WriteLine("For Month:" + keyVal.Key + " leave count:" + keyVal.Value);
}
To get days per month in a timespan.
for (DateTime date = start; date < end; date = date.AddMonths(1))
{
DateTime this_date_start = new DateTime(date.Year, date.Month, 1);
DateTime this_date_end = this_date_start.AddMonths(1).AddDays(-1);
TimeSpan duration = this_date_end.Subtract(date);
Console.WriteLine("duration " + date.Month + " = " + duration.Days + "days");
}
NB: this loop is incomplete: then you have to do this once again outside the loop (this will also catch any shorter than one month spans)
LINQ make it simple and readable:
var from = new DateTime(2018, 5, 28);
var to = new DateTime(2018, 6, 4);
var result = Enumerable.Range(0, int.MaxValue)
.Select(i => from.Date.AddDays(i))
.TakeWhile(date => date <= to.Date)
.GroupBy(date => date.Month)
.Select(range => (Month: range.Key, Days: range.Count()));
foreach (var month in result)
{
Console.WriteLine($"Month: {month.Month}, Seek days: {month.Days}");
}
// result:
// Month: 5, Seek days: 4
// Month: 6, Seek days: 4
If you need amount of seek days for specific month, make it Dictionary
var seekDays = result.ToDictionary(month => month.Month, month => month.SeekDays);
var seekDaysOfMay = seekDays.GetValueOrDefault(5, 0);
Related
How do I get built-up start hours and end hours that if a user just wants to have done several tasks eg every Monday from 08 to 11 the next x number of weeks.
So how can I just do it in a smart way.
I have MoreAdd which tells how many weeks ahead it should make that way.
When I just create a single task. Then it looks like this.
var sTimer = model.StartTime;
var eTimer = model.EndTime;
SignUpInfo addSignUpInfo = new SignUpInfo
{
CompanyId = companyId,
Title = model.Title,
Info = model.Info,
StartTime = sTimer,
EndTimer = eTimer,
Closed = false,
Pay = PayValue,
TaskDone = false,
CreateTime = DateTime.Now,
CategoriId = model.SelectedKategori
};
_db.SignUpInfo.Add(addSignUpInfo);
_db.SaveChanges();
But how will I only do that if I write 5 then make it one from the next Monday and 5 times forward.
I guess you are struggling with determining the start- and end DateTimes for the next 5 weeks from the next Monday. You could use this method:
static IEnumerable<(DateTime start, DateTime end)> GetTimes(DateTime startTime, DateTime endTime, DayOfWeek startDay, int countWeeks)
{
if(endTime < startTime) throw new ArgumentException("TODO");
TimeSpan diff = endTime - startTime;
int daysUntilWeekDay = ((int) startDay - (int) startTime.DayOfWeek + 7) % 7;
DateTime beginningDate = startTime.AddDays(daysUntilWeekDay);
for (int i = 0; i <= countWeeks; i++)
{
DateTime date = beginningDate.AddDays(7 * i);
yield return (start: date, end:date.Add(diff));
}
}
Example:
DateTime dt = new DateTime(2019, 01, 20, 8, 0, 0); //yesterday, sunday, 8 o clock in the morning
foreach(var x in GetTimes(dt, dt.AddHours(3), DayOfWeek.Monday, 5))
Console.WriteLine("Start:{0} End:{1}", x.start, x.end);
With this method it's easy to build a loop that uses your existing code to save the tasks.
I need to find the week numbers of a given date rage in C#.
Ex: date between 01/01/2014 and 14/01/2014
Week numbers are 1st,2nd and 3rd weeks, likewise.
Thanks.
Not the smartest way, but works!
var d1 = new DateTime(2014, 1, 1);
var d2 = new DateTime(2014, 1, 14);
var currentCulture = CultureInfo.CurrentCulture;
var weeks = new List<int>();
for (var dt = d1; dt < d2; dt =dt.AddDays(1))
{
var weekNo = currentCulture.Calendar.GetWeekOfYear(
dt,
currentCulture.DateTimeFormat.CalendarWeekRule,
currentCulture.DateTimeFormat.FirstDayOfWeek);
if(!weeks.Contains(weekNo))
weeks.Add(weekNo);
}
This should work:
public List<int> Weeks(DateTime start, DateTime end)
{
List<int> weeks=new List<int>();
var Week=(int)Math.Floor((double)start.DayOfYear/7.0); //starting week number
for (DateTime t = start; t < end; t = t.AddDays(7))
{
weeks.Add(Week);
Week++;
}
return weeks;
}
All this does is get the week of the start date, then loops through one week at a time until you get to the end date, incrementing the week and adding it to the list of weeks.
OK, let's start with a simple, unoptimized example. We'll simply examine every date between those dates and check what week of the year it is.
We can do that with a simple loop:
var end = new DateTime(2014, 1, 14);
for (var date = new DateTime(2014, 1, 1); date <= end; date = date.AddDays(1))
{
}
This will simply loop over every day between two dates. Now we need to examine those days to determine their day of week. To do this you need to consider a few things: What is the first day of a week? Sunday? Monday? Are we assuming gregorian calendar?
For our example, let's assume the first day of the week is a Sunday and we are indeed using the Gregorian calendar. Then we will check each date, and keep a list of unique weeks of the year using a HashSet:
var weekNumber = new HashSet<int>();
var end = new DateTime(2014, 1, 14);
var calendar = new GregorianCalendar();
for (var date = new DateTime(2014, 1, 1); date <= end; date = date.AddDays(1))
{
weekNumber.Add(calendar.GetWeekOfYear(date, CalendarWeekRule.FirstDay, DayOfWeek.Sunday));
}
The weekNumber Hashset now contains the weeks of the year.
Is this optimized? No. It checks far more dates than it needs to, but the implementation is simple and fast enough. Optimizing can be done as a separate task.
Easy. Here's the code that determines the week of the year for a single date. This should get you going:
int WeekOfYear(DateTime date, DayOfWeek dayOfWeekStart) {
//Find the first day of the year that's the start of week day. If it's not 1/1,
//then we have a first partial week.
bool firstPartialWeek = false;
DateTime firstFullWeekStart = new DateTime(date.Year, 1, 1);
while(firstFullWeekStart.DayOfWeekDay != dayOfWeekStart) {
firstFullWeekStart = firstOfWeek.AddDays(1);
firstPartialWeek = true;
}
//Return the week by integer dividing the date difference by seven,
//and adding in the potential first partial week
return (firstPartialWeek ? 1 : 0) + ((date - firstFullWeekStart).TotalDays / 7);
}
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
I have string[] WeekDayNames that represents the array of week day names (like 'Monday', 'Wednesday')
I need Date for all day names in WeekDayNames for a specific Date Range.
Example: Wednesday between 19 Nov 2013 and 28 Nov 2013 has days: 20.11.2013 and 27.11.2013
Thanks!
First i would convert your strings to real DayOfWeeks ...
string[] WeekDayNames = new[] { "Monday","Wednesday" };
DayOfWeek[] days = WeekDayNames
.Select(s => (DayOfWeek)Enum.Parse(typeof(DayOfWeek), s))
.ToArray();
DateTime start = new DateTime(2013, 11, 19);
DateTime end = new DateTime(2013, 11, 28);
... then you can use this LINQ query:
IEnumerable<DateTime> range = Enumerable.Range(0, (end - start).Days + 1)
.Select(d => start.AddDays(d))
.Where(dt => days.Contains(dt.DayOfWeek));
You can do that with a simple loop like:
DateTime startDate = new DateTime(2013, 11, 19);
DateTime endDate = new DateTime(2013, 11, 28);
List<DateTime> list = new List<DateTime>();
while (startDate <= endDate)
{
if (startDate.DayOfWeek == DayOfWeek.Wednesday)
{
list.Add(startDate);
}
startDate = startDate.AddDays(1);
}
Its better if you use DayOfWeek enum instead of storing string values.
If you want to get dates for each element of your string array WeekDayNames then:
DateTime startDate = new DateTime(2013, 11, 19);
DateTime endDate = new DateTime(2013, 11, 28);
string[] WeekDayNames = new[] { "Wednesday" };
List<DateTime> list = new List<DateTime>();
while (startDate <= endDate)
{
if (WeekDayNames.Any(r=> r== startDate.DayOfWeek.ToString()))
{
list.Add(startDate);
}
startDate = startDate.AddDays(1);
}
This question already has answers here:
How can I calculate the age of a person in year, month, days?
(13 answers)
Closed 9 years ago.
If i have Two dates then i get the difference between them in days Like this Post.
How to detail that in the following view :
convert the days to (number of years,number of months and the rest in the number of days)
There is no out-of-the-box solution for this. The problem is the data isn't "fixed" e.g. not all years are 365 days (366 on a leap year) and not every month can be assumed to be standard 30 days.
It's very difficult to calculate this sort of information without context. You have a duration in days, however, to accurately calculate the number of years/months you need to know exactly when these days fall i.e. on what month and of what year - this would allow you to determine the exact days in the month and/or year.
Based on your comments and the following conditions
1 year = 365 days
1 month = 30 days
Then the following code would do the job
DateTime startDate = new DateTime(2010, 1, 1);
DateTime endDate = new DateTime(2013, 1, 10);
var totalDays = (endDate - startDate).TotalDays;
var totalYears = Math.Truncate(totalDays / 365);
var totalMonths = Math.Truncate((totalDays % 365) / 30);
var remainingDays = Math.Truncate((totalDays % 365) % 30);
Console.WriteLine("Estimated duration is {0} year(s), {1} month(s) and {2} day(s)", totalYears, totalMonths, remainingDays);
You can't because it depends on the start date
i.e. 30 days may be 1 month 1 day, or 1 month 2 days, or less than a month or
365 days will be less than a year if it's a leap year
As mentioned in previous answers, it is very difficult to work this out from just a number of days. There is problems with leap years, and the number of days in months. If you start with the original two datetimes you can use code similar to the following:
DateTime date1 = new DateTime(2010, 1, 18);
DateTime date2 = new DateTime(2013, 2, 22);
int oldMonth = date2.Month;
while (oldMonth == date2.Month)
{
date1 = date1.AddDays(-1);
date2 = date2.AddDays(-1);
}
int years = 0, months = 0, days = 0, hours = 0, minutes = 0, seconds = 0, milliseconds = 0;
// getting number of years
while (date2.CompareTo(date1) >= 0)
{
years++;
date2 = date2.AddYears(-1);
}
date2 = date2.AddYears(1);
years--;
// getting number of months and days
oldMonth = date2.Month;
while (date2.CompareTo(date1) >= 0)
{
days++;
date2 = date2.AddDays(-1);
if ((date2.CompareTo(date1) >= 0) && (oldMonth != date2.Month))
{
months++;
days = 0;
oldMonth = date2.Month;
}
}
date2 = date2.AddDays(1);
days--;
TimeSpan difference = date2.Subtract(date1);
Console.WriteLine("Difference: " +
years.ToString() + " year(s)" +
", " + months.ToString() + " month(s)" +
", " + days.ToString() + " day(s)");
Output is:Difference: 3 year(s), 1 month(s), 4 day(s)
When given a start date a need to do various calculations on it to produce 3 other dates.
Basically I need to work out what date the user has been billed up to for different frequencies based on the current date.
Bi-Annually (billed twice a year),
Quarterly (billed 4 times a year),
and Two Monthly (billed ever other month).
Take the date 26/04/2008
- BiAnnually: This date would have been last billed on 26/10/2010 and should give the date 26/04/2011.
- Quarterly: This date would have been last billed on 26/01/2011 and should give the date 26/04/2011.
- Two Month: This date would have been last billed on 26/12/2010 and should give the date 26/02/2011.
Assistance is much appreciated.
I think that you can just do like this:
public void FindNextDate(DateTime startDate, int interval);
DateTime today = DateTime.Today;
do {
startDate = startDate.AddMonths(interval);
} while (startDate <= today);
return startDate;
}
Usage:
DateTime startDate = new DateTime(2008, m4, 26);
DateTime bi = FindNextDate(startDate, 6);
DateTime quarterly = FindNextDate(startDate, 3);
DateTime two = FindNextDate(startDate, 2);
I think all you want is something like
DateTime x = YourDateBasis;
y = x.AddMonths(6);
y = x.AddMonths(3);
y = x.AddMonths(2);
Then to edit from comment,
Date Math per the period cycle of the person's account, you would simply need the start and end date and keep adding respective months until you've created all expected months. Almost like that of a loan payment that's due every month for 3 years
DateTime CurrentDate = DateTime.Now;
while( CurrentDate < YourFinalDateInFuture )
{
CurrentDate = CurrentDate.AddMonths( CycleFrequency );
Add Record into your table as needed
Perform other calcs as needed
}
enum BillPeriod
{
TwoMonth = 2,
Quarterly = 3,
SemiAnnually = 6,
BiAnnually = 24
}
public Pair<Datetime, Datetime> BillDates(Datetime currentBillDate, BillPeriod period)
{
Datetime LastBill = currentBillDate.AddMonths(-1 * (int)period);
Datetime NextBill = currentBillDate.AddMonths((int)period);
return new Pair<Datetime,Datetime>(LastBill, NextBill);
}
This is a terrible solution, but it works. Remember, red-light, green-light, refactor. Here, we're at green-light:
namespace ConsoleApplication1 {
class Program {
static void Main(string[] args) {
Console.WriteLine(GetLastBilled(new DateTime(2008, 4, 26), 6));
Console.WriteLine(GetNextBilled(new DateTime(2008, 4, 26), 6));
Console.WriteLine(GetLastBilled(new DateTime(2008, 4, 26), 4));
Console.WriteLine(GetNextBilled(new DateTime(2008, 4, 26), 4));
Console.WriteLine(GetLastBilled(new DateTime(2008, 4, 26), 2));
Console.WriteLine(GetNextBilled(new DateTime(2008, 4, 26), 2));
Console.WriteLine("Complete...");
Console.ReadKey(true);
}
static DateTime GetLastBilled(DateTime initialDate, int billingInterval) {
// strip time and handle staggered month-end and 2/29
var result = initialDate.Date.AddYears(DateTime.Now.Year - initialDate.Year);
while (result > DateTime.Now.Date) {
result = result.AddMonths(billingInterval * -1);
}
return result;
}
static DateTime GetNextBilled(DateTime initialDate, int billingInterval) {
// strip time and handle staggered month-end and 2/29
var result = initialDate.Date.AddYears(DateTime.Now.Year - initialDate.Year);
while (result > DateTime.Now.Date) {
result = result.AddMonths(billingInterval * -1);
}
result = result.AddMonths(billingInterval);
return result;
}
}
}
This is really tricky. For example, you need to take into account that the date you billed could have been 2/29 on a leap year, and not all months have the same number of days. That's why I did the initialDate.Date.AddYears(DateTime.Now.Year - initialDate.Year); call.