I'm using Infragisitics 17.1 UltraGrid.
The Grid has 2 columns.
I want the formatted string of the second column, just like below.
'20170102123456' => '2017-01-02 12:34:56"
The data type of the second column is 'string' not 'date'.
This grid will have huge data, so any conversion is worry to me.
But any adive is welcome.
DataSoure just like below.
private void SetTestData()
{
DataTable dtDataSource = new DataTable("table1");
dtDataSource.Columns.Add("OrderDate", typeof(DateTime));
dtDataSource.Columns.Add("RequiredDate", typeof(string));
ultraGrid1.DataSource = dtDataSource;
DataRow rowNew = dtDataSource.NewRow();
rowNew["OrderDate"] = DateTime.Now;
rowNew["RequiredDate"] = "20170101123456";
dtDataSource.Rows.Add(rowNew);
}
And I Initialize Grid Just like below,
private void UltraGrid1_InitializeLayout(object sender, Infragistics.Win.UltraWinGrid.InitializeLayoutEventArgs e)
{
// Fit columns
e.Layout.AutoFitStyle = AutoFitStyle.ExtendLastColumn;
// Set date formats
e.Layout.Bands[0].Columns["OrderDate"].Format = "yyyy-MM-dd HH:mm:ss";
e.Layout.Bands[0].Columns["RequiredDate"].Format = "yyyy-MM-dd HH:mm:ss";
}
The first column works fine, but the second column does not.
How i can display the second column just like below?
'20170102123456' => '2017-01-02 12:34:56"
UltraGrid will not be able to do this conversation alone. What you can do in this specific case is implement your own custom IEditorDataFilter. To do so change your InitializeLayuot like this:
private void UltraGrid1_InitializeLayout(object sender, InitializeLayoutEventArgs e)
{
// Fit columns
e.Layout.AutoFitStyle = AutoFitStyle.ExtendLastColumn;
// Set date formats
e.Layout.Bands[0].Columns["OrderDate"].Format = "yyyy-MM-dd HH:mm:ss";
// You do not need this as the column data type is string
//e.Layout.Bands[0].Columns["RequiredDate"].Format = "yyyy-MM-dd HH:mm:ss";
// Set the column's editor DataFilter instead
e.Layout.Bands[0].Columns["RequiredDate"].Editor.DataFilter = new DF();
}
Then create your custom DataFilter like this:
internal class DF : IEditorDataFilter
{
public object Convert(EditorDataFilterConvertArgs conversionArgs)
{
switch(conversionArgs.Direction)
{
case ConversionDirection.DisplayToEditor:
break;
case ConversionDirection.EditorToDisplay:
var valueAsString = conversionArgs.Value.ToString();
var year = int.Parse(valueAsString.Substring(0, 4));
var month = int.Parse(valueAsString.Substring(4, 2));
var day = int.Parse(valueAsString.Substring(6, 2));
var hours = int.Parse(valueAsString.Substring(8, 2));
var minutes = int.Parse(valueAsString.Substring(10, 2));
var result = new DateTime(year, month, day, hours, minutes, 0).ToString("yyyy-MM-dd HH:mm:ss");
conversionArgs.Handled = true;
conversionArgs.IsValid = true;
return result;
case ConversionDirection.OwnerToEditor:
break;
case ConversionDirection.EditorToOwner:
break;
default:
break;
}
return conversionArgs.Value;
}
}
Related
How to get a Friday date from the given start date and end date,
For Example:
25/03/2021 - starting date
14/08/2021 - endind date
I have a class
public static class DateUtils
{
public static List<DateTime> GetWeekdayInRange(this DateTime from, DateTime to, DayOfWeek day)
{
const int daysInWeek = 7;
var result = new List<DateTime>();
var daysToAdd = ((int)day - (int)from.DayOfWeek + daysInWeek) % daysInWeek;
do
{
from = from.AddDays(daysToAdd);
result.Add(from);
daysToAdd = daysInWeek;
}
while (from < to);
return result;
}
}
That is how i call it in main method:
var from = DateTime.Today; // 25/8/2019
var to = DateTime.Today.AddDays(23); // 23/9/2019
var allFriday = from.GetWeekdayInRange(to, DayOfWeek.Friday);
Console.WriteLine(allFriday);
Console.ReadKey();
Error i get:
System.Collections.Generic.List`1[System.DateTime]
I am new and still learning, how do I call in the main method so that my output be like all dates(fridays) between the range?
Link I followed
To Answer your question, instead of printing allFridays in one go, iterate over each element of list i.e allFridays, convert into string and then print
foreach(var friday in allFridays)
Console.WriteLine(friday);
Why you are getting System.Collections.Generic.List[System.DateTime] ?
Console.WriteLine(), for non primitive type by default calls
.ToString() function which prints type of it(if it is not overridden). In your case, you
need an individual date not a type of List, so you need to iterate
each DateTime from the list and print each date.
One Liner solution:
Console.WriteLine(string.Join(Environment.NewLine, allFridays));
Alternate solution:
public static List<DateTime> GetWeekdayInRange(this DateTime #from, DateTime to, DayOfWeek day)
{
//Create list of DateTime to store range of dates
var dates = new List<DateTime>();
//Iterate over each DateTime and store it in dates list
for (var dt = #from; dt <= to; dt = dt.AddDays(1))
dates.Add(dt);
//Filter date based on DayOfWeek
var filteredDates = dates.Where(x => x.DayOfWeek == day).ToList();
return filteredDates;
}
...
var #from = DateTime.Today; // 25/8/2019
var to = DateTime.Today.AddDays(23); // 23/9/2019
var allFriday = #from.GetWeekdayInRange(to, DayOfWeek.Friday);
Console.WriteLine(string.Join(Environment.NewLine, allFridays));
.NET FIDDLE
Since in your Usage section, you have successfully get the result via GetWeekdayInRange. You can print the dates with these methods:
Method 1:
allFriday.ForEach(x => Console.WriteLine(x.ToShortDateString()));
Method 2:
foreach (var friday in allFriday)
{
Console.WriteLine(friday.ToShortDateString());
}
Method 3:
for (var i = 0; i < allFriday.Count(); i++)
{
Console.WriteLine(allFriday[i].ToShortDateString());
}
Note: ToShortDateString() is one of the methods to display Date string. You can define your desired Date pattern with ToString().
i have a table in SqlServer which contain's: (ID, item_name, date_time_added)
i want to create a C# code to first: view (ID,item_name, date_time_added) column in datagridview then calculate (date_time_NOW - date_time_added) and view the result in a new column(named: expire's in:) in same datagridview...
Note: result would count day's remaining before expiring
what i've tried so far:
DataTable dt = new DataTable();
dt.Columns.Add(new DataColumn("Expire's in:", typeof(int)));
int countrow = dataGridView1.RowCount;
for (int i = 0; i < countrow; i++)
{
string dateAsString = dataGridView1.Rows[dataGridView1.SelectedRows[0].Index].Cells[3].Value.ToString();
DateTime.TryParseExact(dateAsString , "yyyy-MM-dd", System.Globalization.CultureInfo.InvariantCulture, System.Globalization.DateTimeStyles.AssumeLocal, out DateTime dateAsString);
dateTimePicker3.Text = dateAsString;
DateTime expire_date = dateTimePicker3.Value;
TimeSpan span = expire_date - DateTime.Now;
int days = span.Days;
dataGridView1.Rows[dataGridView1.SelectedRows[0].Index].Cells[4].Value = days;
}
Note:Code Updated...
Any help will be greatly appreciated..
I will assume the “ExpireDate” field returned from the sql query is a DateTime object. If this is the case then it would appear that converting the “date” to a string is unnecessary. Example, given a “future” date, then the difference between todays date and the “future” date can be accomplished as…
TimeSpan dif = futureDate.Subtract(DateTime.Now);
Using a DataTable proffers the ability to use an Expression column, however, I do not think this will work with dates and times. Fortunately, this should not be difficult to implement if the grids DataSource is a DataTable. Using a “Class” would be another option. This example uses a DataTable as a DataSource to the grid.
Given this, to make things simple it would appear that a method that takes a DataRow from the data table and adds this TimeSpan difference may come in handy. It may look something like below…
private void SetDifCol(DataRow row) {
TimeSpan dif = ((DateTime)row["ExpireDate"]).Subtract(DateTime.Now);
row["TimeToExpire"] = dif.Days + " days " + dif.Hours + " hours " + dif.Minutes + " minutes";
}
Given that the DataTable has already been filled with the data… the code is going to have to “ADD” this difference column, then loop through each row and calculate the difference between the dates. Therefore, a small method that simply adds this column may look something like below…
private void AddDifferenceColumn(DataTable dt) {
dt.Columns.Add("TimeToExpire", typeof(string));
}
Next is the loop through all the rows in the DataTable and simply call the SetDifCol method on each row.
private void CalculateDateDif(DataTable dt) {
foreach (DataRow row in dt.Rows) {
SetDifCol(row);
}
}
This will work as expected when the data is loaded, however, what if the user “changes” one of the “ExpireDate” values in the grid? In this case, we would need to wire up one of the grids cell change events. Specifically the grids CellValueChanged event. This event will call the SetDifCol method if the “ExpireDate” value changes in that row…
private void dataGridView1_CellValueChanged(object sender, DataGridViewCellEventArgs e) {
if (dataGridView1.Columns[e.ColumnIndex].Name == "ExpireDate") {
if (e.RowIndex >= 0 && dataGridView1.Rows[e.RowIndex].Cells["ExpireDate"].Value != null) {
DataRowView row = (DataRowView)dataGridView1.Rows[e.RowIndex].DataBoundItem;
SetDifCol(row.Row);
}
}
}
Putting this all together may look something like below…
DataTable GridTable;
public Form1() {
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e) {
GridTable = GetTable();
FillTable(GridTable);
AddDifferenceColumn(GridTable);
CalculateDateDif(GridTable);
dataGridView1.DataSource = GridTable;
dataGridView1.Columns[3].Width = 180;
}
private DataTable GetTable() {
DataTable dt = new DataTable();
dt.Columns.Add("ID", typeof(string));
dt.Columns.Add("Name", typeof(string));
dt.Columns.Add("ExpireDate", typeof(DateTime));
return dt;
}
private void AddDifferenceColumn(DataTable dt) {
dt.Columns.Add("TimeToExpire", typeof(string));
}
private void FillTable(DataTable dt) {
dt.Rows.Add("ID1", "Name1", new DateTime(2019, 12, 31));
dt.Rows.Add("ID2", "Name2", new DateTime(2019, 8, 31));
dt.Rows.Add("ID3", "Name3", new DateTime(2019, 4, 30));
dt.Rows.Add("ID4", "Name4", new DateTime(2019, 1, 31));
dt.Rows.Add("ID5", "Name5", new DateTime(2019, 4, 12, 21, 38, 00));
}
private void CalculateDateDif(DataTable dt) {
foreach (DataRow row in dt.Rows) {
SetDifCol(row);
}
}
private void SetDifCol(DataRow row) {
TimeSpan dif = ((DateTime)row["ExpireDate"]).Subtract(DateTime.Now);
row["TimeToExpire"] = dif.Days + " days " + dif.Hours + " hours " + dif.Minutes + " minutes";
}
private void dataGridView1_CellValueChanged(object sender, DataGridViewCellEventArgs e) {
if (dataGridView1.Columns[e.ColumnIndex].Name == "ExpireDate") {
if (e.RowIndex >= 0 && dataGridView1.Rows[e.RowIndex].Cells["ExpireDate"].Value != null) {
DataRowView row = (DataRowView)dataGridView1.Rows[e.RowIndex].DataBoundItem;
SetDifCol(row.Row);
}
}
}
I hope this helps.
EDIT:
to change column type from string to int to sort numerically.
In reference to the extra question you posted, you commented that ”i want to calculate according to what is inside my db Table” … There is no code in this question or the other question that shows a data base. How are you getting the data to begin with?
It appears in this question that there IS a NEW DataTable dt and a column is added to it, however, it is NEVER used. The loop in the code simply adds the difference column to the “GRID” NOT the DataTable. My answer “adds” the diffence column to the DataTable (which you should do). I recommend you show how you are getting the data from the data base.
In reference to sorting the column, you have already noticed that strings that are numbers will not sort properly numerically. This is because they are string… solution… make them ints. Using my answer, two changes are need for this. First the creation of the column needs to be an int type…
private void AddDifferenceColumn(DataTable dt) {
dt.Columns.Add("TimeToExpire", typeof(int));
}
Second a change is needed in the SetDifCol method. Since you only want the days difference and any values less than zero should show as zero (0), then the following changes should accommodate this requirement.
private void SetDifCol(DataRow row) {
TimeSpan dif = ((DateTime)row["ExpireDate"]).Subtract(DateTime.Now);
if (dif.Days >= 0) {
row["TimeToExpire"] = dif.Days;
}
else {
row["TimeToExpire"] = 0;
}
}
These two changes should sort the column numerically as expected.
Lastly, it should be clear, that IF you want this “difference” column to be reflected in the database… then YOU will have to add the difference column to the database table, THEN, you will need to issue an update command to the database table.
From what I see you try to put a string into the DateTime value here:
DateTime str;
str=dataGridView1.Rows[dataGridView1.SelectedRows[0].Index].Cells[3].Value.ToString();
If you want to parse string to DateTime the code should look like this:
string dateAsString = dataGridView1.Rows[dataGridView1.SelectedRows[0].Index].Cells[3].Value.ToString();
DateTime.TryParseExact(dateAsString, "yyyy-MM-dd", System.Globalization.CultureInfo.InvariantCulture, System.Globalization.DateTimeStyles.AssumeLocal, out DateTime dateAsDateTime);
Then you can substract that date from DateTime.Now:
TimeSpan span = dateAsDateTime - DateTime.Now;
And finally extract the days from the span:
int days = span.Days;
OR just do it all in one line:
int days = (DateTime.Now - dataGridView1.Rows[dataGridView1.SelectedRows[0].Index].Cells[3].Value).Days;
I have to add last 18 months to a drop down in asp.net C#.
I have written the logic to get last 18 months as follows.,
List<string> dateList= new List<string>();
private List<string> GetDateDropDownList(DropDown pDropDown)
{
DateTime dt = DateTime.Now;
for (int i = 1; i <= 18; i++)
{
dt = dt.AddMonths(-1);
var month = dt.ToString("MMMM");
var year = dt.Year;
dateList.Add(String.Format("{0}-{1}", month, year));
}
return dateList;
}
now I need to add this list to drop down. I am trying but it is not working. How can I add it to the drop down?
Similar to what others have said, you just bind your function to it.
However, you have a little issue in your code. You create your dateList outside of your actual method, instead of inside of it. You also do not need to pass a dropdown list into the method.
So your updated method should be:
private List<string> GetDateDropDownList()// get rid of parameter
{
List<string> dateList= new List<string>(); // inside method
DateTime dt = DateTime.Now;
for (int i = 1; i <= 18; i++)
{
dt = dt.AddMonths(-1);
var month = dt.ToString("MMMM");
var year = dt.Year;
dateList.Add(String.Format("{0}-{1}", month, year));
}
return dateList;
}
And you bind your dropdown direct to the method
myDropdown.DataSource = GetDateDropDownList();
myDropdown.DataBind();
Alternatively, with your original method you can do the following - notice it's now a void and does not return a list.
private void GetDateDropDownList(DropDown pDropDown)
{
List<string> dateList= new List<string>();
DateTime dt = DateTime.Now;
for (int i = 1; i <= 18; i++)
{
dt = dt.AddMonths(-1);
var month = dt.ToString("MMMM");
var year = dt.Year;
dateList.Add(String.Format("{0}-{1}", month, year));
}
pDropDown.DataSource = dateList;
pDropDown.DataBind()
}
And you would simply pass in your dropdown list
GetDateDropDownList(myDropdownList);
All you're doing in your method is building a list. You never add it to the drop down. Like this...
pDropDown.DataSource = dateList;
pDropDown.DataBind();
You are currently building a list of strings, but in order to make it visible within your dropdown, you'll need to specifically set the DataSource property and then call DataBind() to apply the changes:
// This sets your data
pDropDown.DataSource = dateList;
// This actually binds the current data to the DropDownList control
pDropDown.DataBind();
Additionally, you likely won't need to be returning any values from this method (unless you need them for some other reason) and could consider making it return void:
private void SetDatesForDropDown(DropDown pDropDown, int monthsBack = 18)
{
List<string> dateList= new List<string>();
DateTime dt = DateTime.Now;
for (int i = 1; i <= monthsBack; i++)
{
dt = dt.AddMonths(-1);
dateList.Add(dt.ToString("MMMM-yyyy"));
}
pDropDown.DataSource = dateList;
pDropDown.DataBind();
}
Or simply removing the DropDown parameter and using the results of the method to set your DataSource:
private void GetDateRanges(int monthsBack = 18)
{
List<string> dateList= new List<string>();
DateTime dt = DateTime.Now;
for (int i = 1; i <= monthsBack; i++)
{
dt = dt.AddMonths(-1);
dateList.Add(dt.ToString("MMMM-yyyy"));
}
return dateList;
}
along with:
YourDropDown.DataSource = GetDateRanges();
YourDropDown.DataBind();
There are a number of ways of doing this, below is one such way.
Just remember to bind it to a dropdownlist.
EDITED - Getting the Selected Value
Frontend - ASPX
<asp:DropDownList ID="DropDownList1" runat="server" OnLoad="DropDownList1_Load" OnSelectedIndexChanged="DropDownList1_SelectedIndexChanged" AutoPostBack="true"></asp:DropDownList>
Codebehind - C#
//Populate the DropDownList
protected void DropDownList1_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
// Instantiate your DropDownList
DropDownList drpList = (DropDownList)sender;
List<string> dateList = new List<string>();
DateTime dt = DateTime.Now;
for (int i = 1; i <= 18; i++)
{
dt = dt.AddMonths(-1);
var month = dt.ToString("MMMM");
var year = dt.Year;
dateList.Add(String.Format("{0}-{1}", month, year));
}
// Bind resulting list to the DropDownList
drpList.DataSource = dateList;
drpList.DataBind();
}
}
//Get the Selected Value on change
protected void DropDownList1_SelectedIndexChanged(object sender, EventArgs e)
{
// assign the selected item value to a variable
string value = ((DropDownList)sender).SelectedValue;
}
I try to do little program, to convert DateTime to Double and from double to DateTime.
I used DateTimePicker in C#, to make my users choose date and time to convert, and it works great, but I have little problem with converting double value to DateTime.
When I have double value, I can easilly convert it to Date by using something like this var dt = DateTime.FromOADate(doubleDate); and var date = dt.Date; but I have no idea, how to convert this double value to time.
This is my code:
private void button2_Click(object sender, EventArgs e)
{
var doubleDate = Convert.ToDouble(textBox1.Text);
var dt = DateTime.FromOADate(doubleDate);
var date = dt.Date;
this.dateDateTime.Value = date;
}
Example value: 42722,7819696875 or 42710,5736342593
You need to set the format on the DateTimePicker, Try the following:
var d = 42722.7465005671d; // 12/18/2016 5:54:57 PM
var dateTime = DateTime.FromOADate(d);
this.dateDateTime.Value = date;
this.dateDateTime.Format = DateTimePickerFormat.Time;
I can't seem to get my head around this but what would be the best approach for displaying a list of upcoming events?
At the moment I have a list of json events being displayed. All these events have a specific date on them.
2016-04-01T13:15:00
Most of the events have passed so i do not need to have them shown. How would i go about only showing the upcoming events?
The main thing I cant figure out is how to get todays date...
This is the code I used to display the events.
async void PopulateTableWithData()
{
var service = new Data.RestService();
var response = await service.GetEventItemsAsync();
Debug.WriteLine("JSON RESULTS FOUND: " + response.Count + "events");
listView.ItemsSource = response; // Display data in listview
/**ITEM SELECTED EVENT**/
listView.ItemSelected += (sender, e) =>
{
var i = (listView.ItemsSource as List<EventItems>).IndexOf(e.SelectedItem as EventItems);
string title = response[i].Title;
string description = response[i].EventDescription;
string location = response[i].EventLocation;
string startTime = response[i].EventStartTime;
string endTime = response[i].EventEndTime;
string rowKey = response[i].RowKey;
Navigation.PushAsync(new EventsWebviewPage(title, description, location, startTime, endTime, ReplaceString(rowKey, " ", "%20")));
};
}
Would I have to use some form of DateTime?
Can anyone give me some guidance?
Thanks
EDITED
async void PopulateTableWithData()
{
var service = new Data.RestService();
var response = await service.GetEventItemsAsync();
Debug.WriteLine("JSON RESULTS FOUND: " + response.Count + "events");
//listView.ItemsSource = response; // Display data in listview
for(int i = 0; i < response.Count; i++)
{
// Split raw json date
string[] splitRawDateTime = response[i].EventEndTime.Split('T');
string[] splitRawDate = splitRawDateTime[0].Split('-');
string eventYear = splitRawDate[0];
string eventMonth = splitRawDate[1];
string eventDay = splitRawDate[2];
// Compare dates and display events according to date
DateTime currentDateTime = DateTime.Now;
DateTime eventDateTime = new DateTime(int.Parse(eventYear), int.Parse(eventMonth), int.Parse(eventDay), 0, 0, 0);
int compareDates = DateTime.Compare(eventDateTime, currentDateTime);
List<EventItems> upcomingEvents = new List<EventItems>();
if (compareDates < 0)
{
Debug.WriteLine("Event date {0} is earlier then current date {1}", eventDateTime, currentDateTime);
}
else
{
Debug.WriteLine("Event date {0} is later then current date {1}", eventDateTime, currentDateTime);
upcomingEvents.Add(response[i]);
}
listView.ItemsSource = upcomingEvents;
}
}
}
I have just tried the above code and it seems to be working but how do I only display the upcoming events?
I believe its an issue with my placement of
listView.ItemsSource = response;
I know im probably doing something wrong here. Can anyone help?
You can get the current date and time by using DateTime.Now
You can also create a DateTime object from a string representation of a date by using one of the DateTime.Parse() functions. Then you can compare the two dates by using comparison operators: <, <=, >, >=, ==
Edit: You could try it his way:
async void PopulateTableWithData()
{
var service = new Data.RestService();
var response = await service.GetEventItemsAsync();
Debug.WriteLine("JSON RESULTS FOUND: " + response.Count + "events");
//listView.ItemsSource = response; // Display data in listview
//Instantiate the list of upcoming events before the loop
List<EventItems> upcomingEvents = new List<EventItems>();
for(int i = 0; i < response.Count; i++)
{
// Split raw json date
string[] splitRawDateTime = response[i].EventEndTime.Split('T');
string[] splitRawDate = splitRawDateTime[0].Split('-');
string eventYear = splitRawDate[0];
string eventMonth = splitRawDate[1];
string eventDay = splitRawDate[2];
// Compare dates and display events according to date
DateTime currentDateTime = DateTime.Now;
DateTime eventDateTime = new DateTime(int.Parse(eventYear), int.Parse(eventMonth), int.Parse(eventDay), 0, 0, 0);
int compareDates = DateTime.Compare(eventDateTime, currentDateTime);
if (compareDates < 0)
{
Debug.WriteLine("Event date {0} is earlier then current date {1}", eventDateTime, currentDateTime);
}
else
{
Debug.WriteLine("Event date {0} is later then current date {1}", eventDateTime, currentDateTime);
//Populate the list of upcoming events
upcomingEvents.Add(response[i]);
}
}
//Display the list of upcoming events
listView.ItemsSource = upcomingEvents;
}