c# check if daterange between an interval - c#

I need some clear mind to check if a date range false between another interval. Here is whats happening:
DateTime[] dates = new DateTime[20];
dates[0] = Convert.ToDateTime(initial_date);
for (int i = 1; i <= 19; i++)
{
dates[i] = initial_date.AddYears(i);
}
So i have an array that stores 20 dates. If the initial_date = 1/20/2012 the array goes from dates[0] = 1/20/2012 up to dates[19] = 1/20/2031
and now i want to check if a user selects two dates for example 1/1/2013 and 1/1/2014 the selections falls between the the first element of the array (dates[0]) and the second (dates[1]). so far:
DateTime a1 = Convert.ToDateTime(vtable.Rows[0][0]);
DateTime a2 = Convert.ToDateTime(vtable.Rows[vtable.Rows.Count - 1][0]);
DateTime start = DateTime.MinValue;
DateTime end = DateTime.MaxValue;
for (int i = 0; i < 20; i++)
{
if (a1.CompareTo(dates[i]) >= 0)
{
start = dates[i];
for (int j = 19; j > 0 ; j--)
{
if (a2.CompareTo(dates[j]) >= 0)
{
end = dates[j];
break;
}
}
break;
}
}
this is working up to the point when a user selects a daterange that falls only between one element of the array. Like for example if the selection is 1/30/2012 - 5/30/2012 then start = date[0] and end = date[0]
I know i can simply state at the end if end == unassigned then end = start but i am thinking is better to correct the algorithm than applying a patch at the end
Thank you very much

Store your date ranges as pairs as in start to end, where end would next start - 1 day.
Makes things much clearer in the code.

var rangeMax = dates.Max();
var rangeMin = dates.Min();
DateTime a1 = Convert.ToDateTime(vtable.Rows[0][0]);
DateTime a2 = Convert.ToDateTime(vtable.Rows[vtable.Rows.Count - 1][0]);
if ((a1 > rangeMin) && (a1 < rangeMax) && (a2 > rangeMin) && (a2 < rangeMax))
{
//dates are in given range
}

Related

show the most recent date of a datagridview

i have a datagridview with a column filled with dates, i want a textbox to show only the most recent one, what i did wasis to put a very early date in the textbox(01/01/0000) and then run the whole datagrid in a for loop but it gives me this error
String was not recognized as a valid DateTime
dataGridView1.Columns[14].DefaultCellStyle.Format = "dd/MM/yyyy";
for (int i = 0; i < dataGridView1.Rows.Count; i++)
{
DateTime date = Convert.ToDateTime(dataGridView1.Rows[i].Cells[14].Value.ToString());
DateTime date1 = DateTime.ParseExact(dataRecente.Text, "dd/MM/yyyy", System.Globalization.CultureInfo.CurrentUICulture.DateTimeFormat);
if (date > date1)
{
dataRecente.Text = Convert.ToString(date);
}
}
Why not fetch the date straight from the source for the datagridview, presumably a datatable or dataset ? If the underlying data changes later for example due to user input, the datatable can trigger an event, so you can refresh the textbox.
The loop is totally unnecessary, so is the parsing and conversion. If you have valid datetime values they can easily be sorted.
Also, you are assuming that the date will always be in a certain column but the user could drag columns and change the display order, and your code will crash miserably.
So instead of:
dataGridView1.Columns[14].DefaultCellStyle.Format = "dd/MM/yyyy";
you can have:
dataGridView1.Columns[datagridview1.Columns["colDate"].Index].DefaultCellStyle.Format = "dd/MM/yyyy";
(not tested but should be very close if not correct)
Each column in the datagrid is an control, and hopefully you've given them meaningful column names (in this example: colDate).
You could fetch the max date from your datatable using the DataTable.Compute function like:
table.Compute("MAX([DateColumn 1])", "");
(Do handle the case the datatable is empty, or expect the return value to be null)
Other alternatives: use the DataTable.Select function or LINQ.
i found another...incredibly brute and unelagent solution, since i do not care how the interface looks and as a noob i know very little of dataset etc i have created three datagrid with the one column for days one for months and one for years.
the script then sort by year, the ones on top with the same year go into the second datagridview and are sorted by month, and the script repeat for the day, in the end the first row of the last datagris contain the most recent date.
As said this is incredibly brutish and could seems a neanderthalian solution...but it worked.
for (int i2 = 0; i2 < date.Rows.Count; i2++)
{
int inizio = Int32.Parse(date.Rows[i2].Cells[1].Value.ToString());
int fine = Int32.Parse(date.Rows[i2].Cells[2].Value.ToString());
for (int i = inizio; i < fine; i++)
{
dataSortingGrid.Rows.Add();
int startIndex = 0;
int length = 2;
string dataIntera = dataGridView1.Rows[i].Cells[14].Value.ToString();
int i3 = dataSortingGrid.Rows.Count - 1;
String giorni = dataIntera.Substring(startIndex, length);
dataSortingGrid.Rows[i3].Cells[0].Value = giorni;
startIndex = 3;
length = 2;
String mesi = dataIntera.Substring(startIndex, length);
dataSortingGrid.Rows[i3].Cells[1].Value = mesi;
startIndex = 6;
length = 4;
String anni = dataIntera.Substring(startIndex, length);
dataSortingGrid.Rows[i3].Cells[2].Value = anni;
dataSortingGrid.Rows[i3].Cells[3].Value = dataGridView1.Rows[i].Cells[14].Value.ToString();
}
dataSortingGrid.Sort(dataSortingGrid.Columns[2], System.ComponentModel.ListSortDirection.Descending);
//mesi
int nRowMesi = Int32.Parse(dataSortingGrid.Rows.Count.ToString());
for (int i = 0; i < nRowMesi; i++)
{
if (i < 1)
{
dataSortingGridMesi.Rows.Add();
dataSortingGridMesi.Rows[i].Cells[0].Value = dataSortingGrid.Rows[i].Cells[0].Value;
dataSortingGridMesi.Rows[i].Cells[1].Value = dataSortingGrid.Rows[i].Cells[1].Value;
dataSortingGridMesi.Rows[i].Cells[2].Value = dataSortingGrid.Rows[i].Cells[2].Value;
dataSortingGridMesi.Rows[i].Cells[3].Value = dataSortingGrid.Rows[i].Cells[3].Value;
}
else
{
int valoreAnniSopra = Convert.ToInt32(dataSortingGrid.Rows[i - 1].Cells[2].Value);
int valoreAnniSotto = Convert.ToInt32(dataSortingGrid.Rows[i].Cells[2].Value);
if (valoreAnniSotto < valoreAnniSopra)
{
break;
}
dataSortingGridMesi.Rows.Add();
dataSortingGridMesi.Rows[i].Cells[0].Value = dataSortingGrid.Rows[i].Cells[0].Value;
dataSortingGridMesi.Rows[i].Cells[1].Value = dataSortingGrid.Rows[i].Cells[1].Value;
dataSortingGridMesi.Rows[i].Cells[2].Value = dataSortingGrid.Rows[i].Cells[2].Value;
dataSortingGridMesi.Rows[i].Cells[3].Value = dataSortingGrid.Rows[i].Cells[3].Value;
}
}
dataSortingGridMesi.Sort(dataSortingGridMesi.Columns[1], System.ComponentModel.ListSortDirection.Ascending);
//giorni
int nRowGiorni = Int32.Parse(dataSortingGridMesi.Rows.Count.ToString());
for (int i = 0; i < nRowGiorni; i++)
{
if (i < 1)
{
dataSortingGridGiorni.Rows.Add();
dataSortingGridGiorni.Rows[i].Cells[0].Value = dataSortingGridMesi.Rows[i].Cells[0].Value;
dataSortingGridGiorni.Rows[i].Cells[1].Value = dataSortingGridMesi.Rows[i].Cells[1].Value;
dataSortingGridGiorni.Rows[i].Cells[2].Value = dataSortingGridMesi.Rows[i].Cells[2].Value;
dataSortingGridGiorni.Rows[i].Cells[3].Value = dataSortingGridMesi.Rows[i].Cells[3].Value;
}
else
{
int valoreMesiSopra = Convert.ToInt32(dataSortingGridMesi.Rows[i - 1].Cells[1].Value);
int valoreMesiSotto = Convert.ToInt32(dataSortingGridMesi.Rows[i].Cells[1].Value);
if (valoreMesiSotto < valoreMesiSopra)
{
break;
}
dataSortingGridGiorni.Rows.Add();
dataSortingGridGiorni.Rows[i].Cells[0].Value = dataSortingGridMesi.Rows[i].Cells[0].Value;
dataSortingGridGiorni.Rows[i].Cells[1].Value = dataSortingGridMesi.Rows[i].Cells[1].Value;
dataSortingGridGiorni.Rows[i].Cells[2].Value = dataSortingGridMesi.Rows[i].Cells[2].Value;
dataSortingGridGiorni.Rows[i].Cells[3].Value = dataSortingGridMesi.Rows[i].Cells[3].Value;
}
}
dataSortingGridGiorni.Sort(dataSortingGridGiorni.Columns[0], System.ComponentModel.ListSortDirection.Descending);

Automatic Day Assign

I need help about assigning day automatically. I couldn't find correct way.
Now problem is that I have fitness program. And I will add new user. When I add I will add program too. Fitness program has limit.
For example. 8 seans. Then user chooses every Saturday and Sunday.
16.03.2019, 17.03.2019, 23.03.2019, 24.03.2019,
30.03.2019, 31.03.2019, 06.04.2019, 07.04.2019
The dates will be assign automatically due to his chosen. uye.DAYS choosed days of week. For example '0,6' and uye.SURE means limit of seans
if(uy.UYELIK== "PLATES")
{
DateTime date = DateTime.Now.Date;
System.TimeSpan duration = new System.TimeSpan(1, 0, 0, 0);
for (int i = 0; i < uye.SURE; i++)
{
date = date.Add(duration);
var list = uye.DAYS.Split(',');
for(int j = 0; j < list.Length; j++)
{
if ((int)date.DayOfWeek == Convert.ToInt32(list[j]))
{
HR_FITNESS_USER_PLATES_PROGRAM program = new HR_FITNESS_USER_PLATES_PROGRAM();
program.REF_HOCA = uye.HOCA;program.SEANS_LIMIT = uye.SURE;program.SEANS_TIME = date;program.REF_UYELIK = uy.ID;program.SICIL = uye.SICIL.ToString();
db.HR_FITNESS_USER_PLATES_PROGRAM.Add(program);db.SaveChanges();
}
}
}
}
This code is not correct. Here I can't increase day if not one of them. How can I do it?
As I understand, you need to insert a weekend fitness program for a member. Here is a simple psuedocode for that,
var startDate = DateTime.Today; //today
int currentDayOfWeek = (int)startDate.DayOfWeek; //today
//saturday of this week, disregarding if today is
//saturday or sunday, it is up to you to enhance this.
DateTime thisSaturday = startDate.AddDays(6 - currentDayOfWeek);
var sessions = 8;
for (int i = 0; i<sessions; i++)
{
SaveToDb(thisSaturday);
thisSaturday = thisSaturday.AddDays(7); //next week's weekend
}
private void SaveToDb(DateTime saturday)
{
DateTime sunday = saturday.AddDays(1);
//insert data for saturday and sunday
}

passing class to a formula produces the same value

In my code below I have output which shows different values for ema12 (the methods only calculate the ema12 value but in the list of classes, each class has the same value for the last ema12 value in the list even though each one is different and somehow all ema12 values are now the same. Am I missing something simple?
CalculationData currentCalcData = new CalculationData();
for (int i = 0; i < Data.Count; i++)
{
var currentDate = Data.ElementAt(i).Date;
currentCalcData = PassValuesToCalculationData(ListCalculationData, currentCalcData,
i, days, currentDate, PassIndicatorType.ExponentialMovingAverage);
currentCalcData = PassValuesToCalculationData(ListCalculationData, currentCalcData,
i, days, currentDate, PassIndicatorType.SimpleMovingAverage);
Console.WriteLine(currentCalcData.Ema12);
// add current calculator class to the list
ListCalculationData.Add(currentCalcData);
}
Output via Console.WriteLine():
47.614134621466156130843047529
47.832250005270668646730641192
47.832250005270668646730641192
48.050616671234579493833222366
48.050616671234579493833222366
48.137201115069968894655459384
48.137201115069968894655459384
48.173574299727306375368064800
48.173574299727306375368064800
48.237097726430332191985656160
48.237097726430332191985656160
48.292151362906287899720902005
48.292151362906287899720902005
48.331864514518782846424781738
48.331864514518782846424781738
48.407615912582945133568144173
48.407615912582945133568144173
48.441267124238552449092391617
48.441267124238552449092391617
48.491764841006745455880072735
Values for ema12 in each class in the list is: 48.49
This is the method that it calls in the PassValuesToCalculationData
case PassIndicatorType.MovingAverageConvergenceDivergenceOscillator:
// for ema 12
if (index >= 11)
{
if (index == 11)
{
// get sma to start ema
currentCalcData.Ema12 = CalculateSMA(12, currentDate, SmaType.Price);
}
else
{
// get regular ema
currentCalcData.Ema12 = CalculateEMA(smoothingFactor, currentPrice, listCalcData.ElementAt(index - 1).Ema12);
// for ema 26
if (index >= 25)
{
if (index == 25)
{
// get sma to start ema
currentCalcData.Ema26 = CalculateSMA(26, currentDate, SmaType.Price);
}
else
{
// get regular ema
currentCalcData.Ema26 = CalculateEMA(smoothingFactor, currentPrice, listCalcData.ElementAt(index - 1).Ema26);
// get macd line and other macd stuff
currentCalcData.Macd = CalculateMACDLine(currentCalcData.Ema12, currentCalcData.Ema26);
// add macd to list to get ema of macd
currentCalcData.ListMacd.Add(currentCalcData.Macd);
// macd signal line is 9 day ema of macd
if (currentCalcData.ListMacd.Count >= 9)
{
if (currentCalcData.ListMacd.Count == 9)
{
// do sma to start ema
currentCalcData.MacdSignal = currentCalcData.ListMacd.Average();
}
else
{
currentCalcData.MacdSignal = CalculateEMA(smoothingFactor, currentCalcData.MacdSignal, listCalcData.ElementAt(index - 1).MacdSignal);
currentCalcData.MacdHistogram = CalculateMACDHistogram(currentCalcData.Macd, currentCalcData.MacdSignal);
}
}
}
}
}
}
break;
The issue you are having is because you only instantiate 1 object currentCalcData and put that same reference into the ListCalculationData multiple times.
The solution is put the currentCalcData instantiation inside the for loop, then you will have different objects inside the ListCalculationData.
for (int i = 0; i < Data.Count; i++)
{
CalculationData currentCalcData = new CalculationData();
var currentDate = Data.ElementAt(i).Date;
//.... and continue the rest

How to display current date by default on drop down list?

I would like to display a week of dates with the default being today's date on a drop down list. How can I do this?
I was also told to "use class DateTime.Now, and convert the data value into a string".
Any help is appreciated!
this works for me on my asp.net project
DropDownList1.Items.Add(DateTime.Now.ToString());
and this one on my combobox
comboBox1.Items.Add(DateTime.Now);
i'm not entirely sure about your question. is the following you want to do?
for (int i = 0; i < 7; i++)
{
DropDownList1.Items.Add(DateTime.Now.AddDays(-i).ToString());
}
Try This:
//Get Start And End
int delta = Convert.ToInt32(DateTime.Now.DayOfWeek);
delta = delta == 0 ? delta + 7 : delta;
DateTime moday = DateTime.Now.AddDays(1 - delta);
DateTime sunday = DateTime.Now.AddDays(7 - delta);
//Get Date Range
List<DateTime> allDates = new List<DateTime>();
//Add To Your List
for (DateTime i = moday; i <= sunday; i = i.AddDays(1))
{
DropDownList1.Items.Add(i.Date.DayOfWeek);
}
//Select Today Name
DropDownList1.SelectedItem = DateTime.Today.Date.DayOfWeek;
Edited
For This Format(mm/dd/yyy)
//Add To Your List
for (DateTime i = moday; i <= sunday; i = i.AddDays(1))
{
comboBox1.Items.Add(i.Date.ToShortDateString());
}
//Select Today Date(dd/mm/yyy)
comboBox1.SelectedItem = DateTime.Today.ToShortDateString();
you can put it on the load event
protected void Page_Load(object sender, EventArgs e)
{
for (int i = 0; i < 7; i++)
{
DropDownList1.Items.Add(DateTime.Now.AddDays(-i).ToString());
}
}

Get last 'N' quarters in C#

Suppose the current quater is 3 and the year is 2011. How can I get the last 5 quarters
Desired output:
Q3-2011
Q2-2011
Q1-2011
Q4-2010
Q3-2010
The Q and '-' is appended.
I am trying as under
int generateQuater = 5;
int currentQuater = 3;//GetQuarter(DateTime.Now.Month);
int currentYear = DateTime.Now.Year;
List<string> lstQuaterYear = new List<string>();
lstQuaterYear.Add(string.Concat('Q',currentQuater, '-', currentYear));
for (int i = generateQuater; i > 0; i++)
{
//code to be placed
}
Thanks
You have to decrease your loop variable. The rest is not too difficult math.
Its also not necessary to handle the first iteration in any special way:
for (int i = generateQuater; i > 0; i--)
{
lstQuaterYear.Add(string.Format("Q{0}-{1}", currentQuater, currentYear));
if (--currentQuater == 0)
{
currentQuater = 4;
currentYear--;
}
}
As a pure LINQ expression:
public IEnumerable<String> GetQuarters(int start, int year, int count)
{
return (from q in Enumerable.Range(0, count)
select String.Format("Q{0}-{1}", (start - q) + (((q + 1) / 4) * 4) , year - ((q + 1) / 4)));
}
The math is somewhat ugly but does work, to use it you can just do:
foreach (String quarter in GetQuarters(3, 2011, 5))
{
Console.WriteLine(quarter);
}
Your for loop should go from 0 to your variable, when you're increasing i.
The inner code could be something like:
currentQuarter--;
if(currentQuarter == 0)
{
currentQuarter = 4;
currentYear--;
}
Don't forget to refactor it :)
int count = 5;
int currentQuarter = GetQuarter(DateTime.Now.Month);
int currentYear = DateTime.Now.Year;
List<string> lstQuaterYear = new List<string>();
for (int i = count; i > 0; i--)
{
lstQuaterYear.Add(string.Concat('Q', currentQuarter, '-', currentYear));
currentQuarter--;
if (currentQuarter == 0)
{
currentQuarter = 4;
currentYear--;
}
}
One way is to check for year roll over and then set the quarter to 4 and decrement the year:
int quarter=3;
int year=2011;
int count=5;
for(int i=0;i<count;i++)
{
lstQuaterYear.Add(string.Format("Q{0} {1}", quarter, year);
quarter--;
if(quarter==0)
{
quarter=4;
year--;
}
}
Alternatively you could calculate a totalQuartal=year+quartal-1. Then decrement it on each step. And finally use year=totalQuartal/4 and quartal=totalQuartal%4+1. But I think the first way is easier to understand.
public static IEnumerable Generate(int number, int currentYear, int currentQuarter)
{
int counter = number;
int quarter = currentQuarter;
int year = currentYear;
while (counter-- > 0)
{
yield return String.Format("Q{0}-{1}", year, quarter);
quarter = quarter>1?quarter-1:4;
year = quarter==4?year-1:year;
}
}
Here is my version (sorry, it is in VB.NET).
The idea is to :
easily find out the quarter based on a date (easy : divide it by 4 ... and add 1 to avoid zeros)
go back in time from the current date, removing 3 month at each time
printout the formatted quarter
the code :
Private Shared Function GetQuarterForDate(ByVal d As DateTime) As Integer
Return (d.Month \ 4) + 1 'integer division
End Function
Private Shared Function GetLastNQuarters(ByVal N As Integer) As IEnumerable(Of String)
Dim myDate = DateTime.Now
Dim res As New List(Of String)()
Do While N > 0
'using yield would be nicer in C# ... does not exist in VB
res.Add(String.Format("Q{0}-{1}", GetQuarterForDate(myDate), myDate.Year))
myDate = myDate.AddMonths(-3)
N = N - 1
Loop
Return res
End Function
<TestMethod()>
Public Sub CanRetrieveQuarter()
Dim quarters = GetLastNQuarters(5)
For Each q In quarters
Console.WriteLine(q)
Next
End Sub
That last "test method" prints out :
Q3-2011
Q2-2011
Q1-2011
Q4-2010
Q3-2010
In case you should do some operations on the quarter period, like check if moment is within a quarter, you can use the Quarter class of the Time Period Library for .NET:
// ----------------------------------------------------------------------
public ITimePeriodCollection GetPastQuarters( int count )
{
TimePeriodCollection quarters = new TimePeriodCollection();
Quarter quarter = new Quarter();
for ( int i = 0; i < count; i++ )
{
quarters.Add( quarter );
quarter = quarter.GetPreviousQuarter();
}
return quarters;
} // GetPastQuarters

Categories