The problem is that I need to find each Saturday and Friday night and charge them $140 on Friday or Saturday. Should I use a while loop?
DateTime ArrivalDate = DateTime.Parse(txtArrivalDate.Text);
DateTime DepartureDate = DateTime.Parse(txtDepartureDate.Text);
TimeSpan numberOfNights = DepartureDate.Subtract(ArrivalDate);
decimal nights = numberOfNights.Days;
txtNights.Text = nights.ToString();
//txtTotalPrice
decimal pricePerNight = 120.00m;
decimal totalNight = nights * pricePerNight;
txtTotalPrice.Text = "$" + totalNight.ToString();
txtAvgPrice.Text = "$" + pricePerNight.ToString();
// finds the fridays
decimal morePricePerNight = 140.00m;
int i = 0;
// while loop
while (ArrivalDate.DayOfWeek != DayOfWeek.Friday)
{
ArrivalDate = ArrivalDate.AddDays(1);
}
while (DepartureDate.DayOfWeek != DayOfWeek.Friday)
{
DepartureDate = DepartureDate.AddDays(1);
}
Why not to use just a one while loop?
I guess you can write the following code:
var date = DepartureDate;
while (date < ArrivalDate)
{
if (date.DayOfWeek == DayOfWeek.Friday || date.DayOfWeek == DayOfWeek.Saturday)
{
totalNight += 140.00m;
}
date = date.AddDays(1);
}
Related
I have to selected the based dates for days calculation based on Working days (eg: 5.0, 5.5, 6.0).
when i select based on 5.5 days, I would like to calculate automatically.
Kindly help me to solve this issues.
private void SelectionChanged(SelectionChangedEventArgs obj)
{
if(Settings.WorkingDay == "5.0")
{
// Code is working fine
}
else if(Settings.WorkingDay == "5.5")
{
startDate = SelectedRange.StartDate.Date;
endDate = SelectedRange.EndDate.Date;
startDate.AddDays(1);
int days = 0;
for (DateTime date = startDate; date <= endDate; date = date.AddDays(1))
{
if (startDate.DayOfWeek != DayOfWeek.Sunday)
{
days++;
}
startDate = startDate.AddDays(1);
}
if(startDate.DayOfWeek != DayOfWeek.Saturday && endDate.DayOfWeek != DayOfWeek.Saturday)
{
Quantity = (days) - (Convert.ToDecimal(0.5));
}
else if(startDate.DayOfWeek != DayOfWeek.Saturday)
{
Quantity = (days);
}
Debug.WriteLine(Quantity.ToString());
}
else if(Settings.WorkingDay == "6.0")
{
// Code is working fine
}
}
try this
double qty = 0.0;
for (DateTime date = startDate; date <= endDate; date = date.AddDays(1))
{
if (date.DayOfWeek == DayOfWeek.Sunday)
{
// do nothing
}
elseif (date.DayOfWeek == DayOfWeek.Saturday)
{
qty += 0.5;
}
else
{
qty ++ 1;
}
}
i want c# code for getting Last Date of week for given month and year.
suppose given month is 1 and year is 2016 then method should return me
--01/02/2016
--01/09/2016
--01/16/2016
--01/23/2016
--01/30/2016
--02/06/2016
So you want a method which takes a year and a month as parameter and returns dates. Those dates should be the last dates of all weeks in that month, optionally also of following months.
This should work then:
public static IEnumerable<DateTime> GetLastWeekDatesOfMonth(int year, int month, DayOfWeek firstDayOfWeek = DayOfWeek.Monday, bool includeLaterMonths = false)
{
DateTime first = new DateTime(year, month, 1);
int daysOffset = (int)firstDayOfWeek - (int)first.DayOfWeek;
if (daysOffset < 0)
daysOffset = 7 - Math.Abs(daysOffset);
DateTime firstWeekDay = first.AddDays(daysOffset);
DateTime current = firstWeekDay.AddDays(-1); // last before week start
if (current.Month != month)
current = current.AddDays(7);
yield return current;
if (includeLaterMonths)
{
while (true)
{
current = current.AddDays(7);
yield return current;
}
}
else
{
while((current = current.AddDays(7)).Month == month)
yield return current;
}
}
Your sample:
var lastDates = GetLastWeekDatesOfMonth(2016, 1, DayOfWeek.Sunday, true);
foreach (DateTime dt in lastDates.Take(6))
Console.WriteLine(dt.ToShortDateString());
public static DateTime GetLastDateofWeek(int yr, int mnth, int week)
{
DateTime dt = new DateTime(yr, mnth, 1);
DateTime newdate = new DateTime();
if (dt.DayOfWeek == DayOfWeek.Monday)
{
newdate = dt.AddDays(((week - 1) * 7) + 5);
}
else
{
newdate = dt.AddDays((8 - (int)dt.DayOfWeek) % 7 + ((week - 2) * 7) + 5);
}
return newdate;
}
First get month and year, example:
int year = 2016;
int month = 1;
And then create a new instance of the DateTime class that represents the first saturday.
DateTime firstsaturday = new DateTime(year,month,1);
while(firstsaturday.DayOfWeek != DayOfWeek.Saturday)
{
firstsaturday = firstsaturday.AddDays(1);
]
Then create a List of DateTime values.
List<DateTime> saturdays = new List<DateTime>();
saturdays.Add(firstsaturday);
And then cycle through all saturdays using a loop.
DateTime CurrentSaturday = firstsaturday;
while(CurrentSaturday.AddDays(7).Month == month)
{
CurrentSaturday = CurrentSaturday.AddDays(7);
Saturdays.Add(CurrentSaturday);
}
You may try this code.
using System;
public class Program
{
public static void Main()
{
DateTime thisMonthInLastYear = DateTime.Now.AddYears(-1);
DateTime endOfMonth = new DateTime(thisMonthInLastYear.Year,
thisMonthInLastYear.Month,
DateTime.DaysInMonth(thisMonthInLastYear.Year,
thisMonthInLastYear.Month));
Console.WriteLine("Today : "+DateTime.Now.ToString("dd-MM-yyyy"));
Console.WriteLine("This Month in last years : "+endOfMonth.ToString("dd-MM-yyyy"));
Console.WriteLine("Next month in last years : "+endOfMonth.AddMonths(1).ToString("dd-MM-yyyy"));
}
}
I need to check if DateTime.Now is in the first 3 business days of each month (from Mon - Fri). I also need to provide a List<DateTime> with national holidays and these should be handled accordingly.
If DateTime.Now is Saturday and is 1 of the month, first 3 business days are Monday, Tuesday, Wednesday (3, 4, 5 of the month).
public bool IsBusinessDay()
{
DateTime now = DateTime.Now;
DateTime fbd = new DateTime();
DateTime sbd = new DateTime();
DateTime tbd = new DateTime();
DateTime fm = new DateTime(now.Year, now.Month, 1);
DateTime sm = new DateTime(now.Year, now.Month, 2);
DateTime tm = new DateTime(now.Year, now.Month, 3);
// first business day
if (fm.DayOfWeek == DayOfWeek.Sunday)
{
fbd = fm.AddDays(1);
}
else if (fm.DayOfWeek == DayOfWeek.Saturday)
{
fbd = fm.AddDays(2);
}
else
{
fbd = fm;
}
//second business day
if (sm.DayOfWeek == DayOfWeek.Sunday)
{
sbd = sm.AddDays(1);
}
else if (sm.DayOfWeek == DayOfWeek.Saturday)
{
sbd = sm.AddDays(2);
}
else
{
sbd = sm;
}
//third business day
if (tm.DayOfWeek == DayOfWeek.Sunday)
{
tbd = tm.AddDays(1);
}
else if (tm.DayOfWeek == DayOfWeek.Saturday)
{
tbd = tm.AddDays(2);
}
else
{
tbd = tm;
}
if (now == fdb || now == sbd || now == tbd)
{
return true;
}
return false;
}
Is this a good approach? How can I add a List<DateTime> with holidays and check that the current date is not holiday?
I have a feeling I'm over thinking this, and thinking it in a bad way. I don't know why but same feeling tells me there is an easier way to do it.
This should do what you want. You'll have to supply the set of holidays.
public static bool IsFirstThreeBusinessDays(DateTime date, HashSet<DateTime> holidays)
{
DateTime dt = new DateTime(date.Year, date.Month, 1);
int businessDaysSeen = 0;
while (businessDaysSeen < 3)
{
if (dt.DayOfWeek != DayOfWeek.Saturday &&
dt.DayOfWeek != DayOfWeek.Sunday &&
!holidays.Contains(dt))
{
if (dt == date.Date)
{
return true;
}
businessDaysSeen++;
}
dt = dt.AddDays(1);
}
return false;
}
You can also do this using LINQ.
public static bool IsFirstThreeBusinessDays(DateTime date, HashSet<DateTime> holidays)
{
var query =
Enumerable.Range(1, DateTime.DaysInMonth(date.Year, date.Month))
.Select(o => new DateTime(date.Year, date.Month, o))
.Where(o => o.DayOfWeek != DayOfWeek.Saturday && o.DayOfWeek != DayOfWeek.Sunday
&& !holidays.Contains(o))
.Take(3);
return query.Contains(date);
}
EDIT: I didn't read the question carefully enough, although parts of my old answer are still applicable. The approach I would take here is to create a method that enumerates the business days of the month, then take 3 from that.
Here's how:
public static IEnumerable<DateTime> BusinessDaysOfMonth(DateTime time)
{
var month = new DateTime(time.Year, time.Month, 1);
var nextMonth = month.AddMonths(1);
var current = month;
while(current < nextMonth)
{
if (IsWeekday(current) && !IsHoliday(current))
{
yield return current;
}
current = current.AddDays(1);
}
}
(note that some methods are taken from below). Then, all you need where you want to use this is:
// Get first three business days
var firstThreeBizDays = BusinessDaysOfMonth(DateTime.Now).Take(3);
// Check if today is one of them
var result = firstThreeBizDays.Contains(DateTime.Today);
OLD ANSWER:
Ok, so it looks like there's three conditions you need to ensure. They are:
It is the 1st, 2nd, or 3rd day of the month
It is not Saturday or Sunday
The current date is not contained in some set of dates representing holidays
This translates fairly straightforwardly to code:
public static bool IsFirstThreeDays(DateTime time) => time.Day < 4;
public static bool IsWeekday(DateTime time)
{
var dow = time.DayOfWeek;
return dow != DayOfWeek.Saturday && dow != DayOfWeek.Sunday;
}
public bool IsHoliday(DateTime time)
{
ISet<DateTime> holidays = ??; // Decide whether this is a member or an arg
return holidays.Contains(time.Date);
}
Note that the holidays set needs to contain the Day component of any DateTime from each holiday.
Now your method is presumably just:
public static bool IsDayWhatYouWant()
{
var now = DateTime.UtcNow;
return IsFirstThreeDays(now) && IsWeekday(now) && !IsHoliday(now);
}
I need to create a midnight DateTime
I've just done this:
DateTime endTime = DateTime.Now;
endTime.Subtract(endTime.TimeOfDay);
Haven't test it yet, I'm assuming it works but is there a better/cleaner way?
Just use foo.Date, or DateTime.Today for today's date
DateTime endTime = DateTime.Now.Date;
Now endTime.TimeOfDay.ToString() returns "00:00:00"
DateTime.Now . AddDays(1) . Date
DateTime.Today
You can use DateTime.Today with exact seconds of the midnight.
DateTime today = DateTime.Today;
DateTime mid = today.AddDays(1).AddSeconds(-1);
Console.WriteLine(string.Format("Today: {0} , Mid Night: {1}", today.ToString(), mid.ToString()));
Console.ReadLine();
This should print :
Today: 11/24/2016 10:00:00 AM , Mid Night: 11/24/2016 11:59:59 PM
var dateMidnight = DateTime.ParseExact(DateTime.Now.ToString("yyyyMMdd"), "yyyyMMdd", CultureInfo.InvariantCulture);
private bool IsServiceDatabaseProcessReadyToStart()
{
bool isGoodParms = true;
DateTime currentTime = DateTime.Now;
//24 Hour Clock
string[] timeSpan = currentTime.ToString("HH:mm:ss").Split(':');
//Default to Noon
int hr = 12;
int mn = 0;
int sc = 0;
if (!string.IsNullOrEmpty(timeSpan[0]))
{
hr = Convert.ToInt32(timeSpan[0]);
}
else
{
isGoodParms = false;
}
if (!string.IsNullOrEmpty(timeSpan[1]))
{
mn = Convert.ToInt32(timeSpan[1]);
}
else
{
isGoodParms = false;
}
if (!string.IsNullOrEmpty(timeSpan[2]))
{
sc = Convert.ToInt32(timeSpan[2]);
}
else
{
isGoodParms = false;
}
if (isGoodParms == true )
{
TimeSpan currentTimeSpan = new TimeSpan(hr, mn, sc);
TimeSpan minTimeSpan = new TimeSpan(0, 0, 0);
TimeSpan maxTimeSpan = new TimeSpan(0, 04, 59);
if (currentTimeSpan >= minTimeSpan && currentTimeSpan <= maxTimeSpan)
{
return true;
}
else
{
return false;
}
}
else
{
return false;
}
}
I need to get a list of weeks for a given month, with Monday as the start day.
So for example, for the month of February 2009, this method would return:
2/2/2009
2/9/2009
2/16/2009
2/23/2009
// Get the weeks in a month
DateTime date = DateTime.Today;
// first generate all dates in the month of 'date'
var dates = Enumerable.Range(1, DateTime.DaysInMonth(date.Year, date.Month)).Select(n => new DateTime(date.Year, date.Month, n));
// then filter the only the start of weeks
var weekends = from d in dates
where d.DayOfWeek == DayOfWeek.Monday
select d;
public static List<DateTime> GetWeeks(
this DateTime month, DayOfWeek startOfWeek)
{
var firstOfMonth = new DateTime(month.Year, month.Month, 1);
var daysToAdd = ((Int32)startOfWeek - (Int32)month.DayOfWeek) % 7;
var firstStartOfWeek = firstOfMonth.AddDays(daysToAdd);
var current = firstStartOfWeek;
var weeks = new List<DateTime>();
while (current.Month == month.Month)
{
weeks.Add(current);
current = current.AddDays(7);
}
return weeks;
}
Here's a solution (effectively one line) using C# 3.0/LINQ, in case you're interested:
var month = new DateTime(2009, 2, 1);
var weeks = Enumerable.Range(0, 4).Select(n => month.AddDays(n * 7 - (int)month.DayOfWeek + 1)).TakeWhile(monday => monday.Month == month.Month);
int year = 2009;
int month = 2;
DateTime startDate = new DateTime(year, month, 1);
DateTime endDate = startDate.AddMonths(1);
while (startDate.DayOfWeek != DayOfWeek.Monday)
startDate = startDate.AddDays(1);
for (DateTime result = startDate; result < endDate; result = result.AddDays(7))
DoWhatYouWant(result);
How about this?
public IEnumerable<DateTime> GetWeeks(DateTime date, DayOfWeek startDay)
{
var list = new List<DateTime>();
DateTime first = new DateTime(date.Year, date.Month, 1);
for (var i = first; i < first.AddMonths(1); i = i.AddDays(1))
{
if (i.DayOfWeek == startDay)
list.Add(i);
}
return list;
}
Something like the following pseudo-code should work:
Determine the start date of the month (use month and year from a date and set the day to 1
Determine the end date of the month (start date + 1 month)
Determine the first date that is a monday (this is your first item in the list)
Add 7 days to find the next date and repeat until you read or pass the month end
Just change the response line to what ever you need to do with it
protected void PrintDay(int year, int month, DayOfWeek dayName)
{
CultureInfo ci = new CultureInfo("en-US");
for (int i = 1 ; i <= ci.Calendar.GetDaysInMonth (year, month); i++)
{
if (new DateTime (year, month, i).DayOfWeek == dayName)
Response.Write (i.ToString() + "<br/>");
}
}
Quick solution: i don't think there is a built in function for it....
I see you got your answer, but I wanted to share with you a helper class I created for one of my projects. It's far to be a comprehansive class, but might help...
public static class WeekHelper {
#region Public Methods
public static DateTime GetWeekStart(DateTime date) {
DateTime weekStart;
int monday = 1;
int crtDay = (int)date.DayOfWeek;
if (date.DayOfWeek == DayOfWeek.Sunday)
crtDay = 7;
int difference = crtDay - monday;
weekStart = date.AddDays(-difference);
return weekStart;
}
public static DateTime GetWeekStop(DateTime date) {
DateTime weekStart;
int sunday = 7;
int crtDay = (int)date.DayOfWeek;
if (date.DayOfWeek == DayOfWeek.Sunday)
crtDay = 7;
int difference = sunday - crtDay;
weekStart = date.AddDays(difference);
return weekStart;
}
public static void GetWeekInterval(int year, int weekNo,
out DateTime weekStart, out DateTime weekStop) {
GetFirstWeekOfYear(year, out weekStart, out weekStop);
if (weekNo == 1)
return;
weekNo--;
int daysToAdd = weekNo * 7;
DateTime dt = weekStart.AddDays(daysToAdd);
GetWeekInterval(dt, out weekStart, out weekStop);
}
public static List<KeyValuePair<DateTime, DateTime>> GetWeekSeries(DateTime toDate) {
//gets week series from beginning of the year
DateTime dtStartYear = new DateTime(toDate.Year, 1, 1);
List<KeyValuePair<DateTime, DateTime>> list = GetWeekSeries(dtStartYear, toDate);
if (list.Count > 0) {
KeyValuePair<DateTime, DateTime> week = list[0];
list[0] = new KeyValuePair<DateTime, DateTime>(dtStartYear, week.Value);
}
return list;
}
public static List<KeyValuePair<DateTime, DateTime>> GetWeekSeries(DateTime fromDate, DateTime toDate) {
if (fromDate > toDate)
return null;
List<KeyValuePair<DateTime, DateTime>> list = new List<KeyValuePair<DateTime, DateTime>>(100);
DateTime weekStart, weekStop;
toDate = GetWeekStop(toDate);
while (fromDate <= toDate) {
GetWeekInterval(fromDate, out weekStart, out weekStop);
list.Add(new KeyValuePair<DateTime, DateTime>(weekStart, weekStop));
fromDate = fromDate.AddDays(7);
}
return list;
}
public static void GetFirstWeekOfYear(int year, out DateTime weekStart, out DateTime weekStop) {
DateTime date = new DateTime(year, 1, 1);
GetWeekInterval(date, out weekStart, out weekStop);
}
public static void GetWeekInterval(DateTime date,
out DateTime dtWeekStart, out DateTime dtWeekStop) {
dtWeekStart = GetWeekStart(date);
dtWeekStop = GetWeekStop(date);
}
#endregion Public Methods
}
This works beautifully! All you have to do is get the first day of the month you want to get the weeks for and then this will give you the first day of every week. You need to get 5 weeks (not 4) so the Enumerable.Range counts out 5 instead of 4.
var date = new DateTime(DateTime.Today.Year, DateTime.Today.Month, 1);
var weeks = from n in Enumerable.Range(0, 5)
select date.AddDays(7 * n + (-1 * (int)date.DayOfWeek));
Here's what i did, using Chaowlert's code as a starting base. Basically i modified that you need to check if adding the days in the for overflows to the next month, so i don't add 4 days (monday to friday), but actually the minimum between 4 and the number of remaining days in the month. Also, i check if the current day is a weekend, otherwise add days until it's a weekday. My purpose is to print the weeks in a month, from monday to friday
DateTime fechaInicio = new DateTime(año, mes, 1);
DateTime fechaFin = fechaInicio.AddMonths(1);
int diasHastaFinMes = 0;
while (esFinDeSemana(fechaInicio))
fechaInicio = fechaInicio.AddDays(1);
for (DateTime fecha = fechaInicio; fecha < fechaFin; fecha = fecha.AddDays(7))
{
diasHastaFinMes = DateTime.DaysInMonth(fecha.Year, fecha.Month) - fecha.Day;
printWeeks(fecha, fecha.AddDays(Math.Min(4, diasHastaFinMes)));
}