I have an 'IF' statement but I want the condition to check that the date of my object is not less than todays date but I can not figure out how to do this at all.
Code
private List<Web.Services.Entities.Generic.Expenditure> getTransactions(int Id, int AccountId, string Identifier)
{
if (Details != null)
{
foreach (var ABC in Details.Info.ABC)
{
if (ABC.Type == "Test" && ABC.Value.Value > 0)
{
int j = 1;
if (ABC.Frequency == "Monthly")
{
j = 3;
}
for (var i = 0; i < j; i++)
{
List.Add(new Web.Services.Entities.Generic.Expenditure
{
Amount = ABC.RegularIncome.Value * -1,
Description = "Income (" + ABC.Frequency + ")",
DueDate = (DateTime)ABC.NextDate.Value.AddMonths(i)
});
}
}
}
}
}
I tried to declare my (DateTime)ABC.NextDate.Value as a VAR above the following IF and then add to if (ABC.Type == "ABC" && ABC.Value.Value > 0) but I got the following error:
operator '&& ' cannot be applied to operands of type 'bool' and
'system.datetime'
I need to add another condition to the above IF and not replace the '0' as this is checking another value in what is returned.
To test a nullable date you do the following:
if (dateTimeToBeTested.Value.Date >= DateTime.Now.Date)
By using the .Date property, you are forcing the DateTime to midnight of the date in question, so time differences will be ignored.
To use this in your example above, you can do the following:
if (ABC.Type == "Test" && ABC.Value.Value > 0 && dateTimeToBeTested.Value.Date >= DateTime.Now.Date)
Use DateTime.Now to compare ABC.Value.Value with current date.
if (ABC.Type == "Test" && ABC.Value.Value > DateTime.Now)
Edit after question update with more required details and updated if statement.
System.Nullable' does not contain a definition for 'Date' and no
extension method 'Date' accepting...
You need to use DateTime.Value to access the Date property of nullable DateTime. Before using Date property you must check if DateTime variable has value. You can use .HasValue to ensure you have value for nullable DateTime.
Once you are sure that your datetime variable has values using .HasValue you can safely use DateProperty so you would use ABC.NextDate.Value instead of ABC.NextDate to access Date Property.
if (ABC.Type == "Test" && ABC.Value.Value > 0 && ABC.NextDate.HasValue && ABC.NextDate.Value.Date >= DateTime.Now.Date)
Related
This question already has answers here:
Linq Overlapped date range checking in single collection
(2 answers)
Closed 1 year ago.
I have a datatable having startdate and enddate columns. I want to check overlapping startdate and enddate using linq.
method input Parameters:
Input DataTable
startDate
endDate
01/Jan/2021
31/Jan/2021
01/Feb/2021
28/Feb/2021
Input Parameters
FromDate: 15/Feb/2021
ToDate: 20/Feb/2021
Expected OutPut: true
I have created a function to check for overlapping dates.
private bool IsDateOverlap(DateTime? FromDate, DateTime? ToDate, DataTable Table)
{
bool isOverlap = false;
try
{
for (int index = 0; index < Table.Rows.Count; index++)
{
if (index == this.RowID)
continue;
DateTime? rowFromDate = Convert.ToDateTime(Table.Rows[index]["startDate"]);
DateTime? rowToDate = Convert.ToDateTime(Table.Rows[index]["endDate"]);
isOverlap = (FromDate <= rowToDate && rowFromDate <= ToDate);
if (isOverlap)
break;
}
}
catch (Exception ex)
{ }
return isOverlap;
}
Its working fine.
I want to do it using linq. Thanks in Advance.
I have an approach that might help you how ever i use a custom object rather than a datatable.
public static List<inputDataTable> ListOfDates = new List<inputDataTable>
{
new inputDataTable { startDate = DateTime.Parse("01/Jan/2021"), endDate = DateTime.Parse("31/Jan/2021"),},
new inputDataTable { startDate = DateTime.Parse("01/Feb/2021"), endDate = DateTime.Parse("28/Feb/2021"),},
};
public static bool checkOverlapping(DateTime starDate, DateTime endDate, List<inputDataTable> storeDate)
{
var e = storeDate.Where(a=> (starDate >= a.startDate && starDate <= a.endDate) || (endDate >= a.startDate && starDate <= a.endDate) );
if(e.Count() > 0)
{
return true;
}
else
{
return false;
}
}
Also you can visit these threads;
Check dates fall within range using Linq
Check One Date is falling Between Date Range-Linq query
Could someone tell me why this query return a wrong value ?
First I generate 30 data at Player.estateagent. The Date must until 28/05.
System.DateTime Now = System.DateTime.Now;
System.DateTime thedate;
thedate = Now;
System.DateTime today = System.DateTime.Now;
for (int i = 1; i <= 30; i++) {
Player.estateagent.Add (new classBundle (thedate, false));
thedate = thedate.AddDays (1);
Debug.Log ("DATE : " + Player.estateagent [i - 1].Date);
}
int count = Player.estateagent.Where (j => {
return j.Complete == false && today.Date <= j.Date.Date;
}).Select (j=> j.Date.Date).Count ();
Debug.Log(count); // Here return 30, It must be 1
When i count i got 30 not 1. It should return 1 because i have query
where j.complete == false && today.Date <= j.Date.Date
Can someone explain what mistake that i done ?
Thanks
Yes, So far I have asked a wrong question. This is just misunderstood about the logic.
The code i am provide above is running without an error. And the logic is right too.
The result is right with 30.
But i want to have a result which Equal and Greater ( <= ) than the Player.estateagent => Date Compire to today date.
So i just need to do today.Date >= j.Date.Date.
Just like that.
I am creating application on Xamarin and on Entry I created this method:
private void expiry_TextChanged(object sender, TextChangedEventArgs e)
{
var monthCheck = new Regex(#"^(0[1-9]?|1[0-2]?)$");
var yearCheck = new Regex(#"^(1[6-9]?|2[0-9]?)$");
var dateParts = expiry.Text.Split('/');
if (!monthCheck.IsMatch(dateParts[0]) || !yearCheck.IsMatch(dateParts[1]))
{
return;
}
var year = int.Parse(dateParts[1]);
var month = int.Parse(dateParts[0]);
var lastDateOfExpiryMonth = DateTime.DaysInMonth(year, month);
var cardExpiry = new DateTime(year, month, lastDateOfExpiryMonth, 23, 59, 59);
int sizeLength = 4;
string tmpText = expiry.Text.Replace("/", "");
if (tmpText.Length > sizeLength)
{
expiry.Text = expiry.Text.Remove(expiry.Text.Length - 1);
return;
}
if (tmpText.Length > 0 && (expiry.Text.Length % 3 == 0) && expiry.Text.Substring(expiry.Text.Length - 1, 1) != "/" && expiry.Text.Substring(expiry.Text.Length - 2, 1) != "/")
{
expiry.Text = string.Concat(expiry.Text.Substring(0, expiry.Text.Length - 1), "/", expiry.Text.Substring(expiry.Text.Length - 1, 1));
}
}
On if (!monthCheck.IsMatch(dateParts[0]) || !yearCheck.IsMatch(dateParts[1])) I am getting error that Index was outside the bounds, but how it is possible if I added only symbol to my expiry Entry field?
The method ExpDate_TextChanged is getting called as soon someone enters the first character into the TextField and it's getting called for each following character. I guess it's empty by default, so the first call of this method happens while there is not yet a "/" in the TextField.
Move the code which is currently in ExpDate_TextChanged to a Button for example, so it's executed when the input is complete. And add a sanity check before accessing any of the elements in dateParts:
if (dateParts.Length < 2)
return;
}
Please note there are better methods for parsing dates like DateTime.TryParse() which I highly recommend.
Me:
You still haven't added a sample date. What can expiry.Text be?
You:
well, it could be 01/17 for example
If that is January 2017 and the expiry time should be: new DateTime(2017,1,31,23,59,59))(so the end of that month), you can use DateTime.TryParseExact:
DateTime cardExpiry;
bool validDate = DateTime.TryParseExact(expiry.Text, "MM/yy", DateTimeFormatInfo.InvariantInfo, DateTimeStyles.None, out cardExpiry);
if (!validDate)
{
MessageBox.Show("Enter a valid card expiry month in the format 'MM/yy', for example 01/17");
return;
}
cardExpiry = cardExpiry.AddMonths(1).AddSeconds(-1); // last date of month, 23:59:59
// ...
Thank you every one for help and suggestions, but unfortunately I solved it in other way: first of all I check does dateParts is more than 0 , instead check (dateParts.Length < 2) . My final code looks like this:
var dateParts = expiry.Text.Split('/');
if(dateParts.Length>0)
{
if(!monthCheck.IsMatch(dateParts[0]) && dateParts[0] != "")
{
if (dateParts[0].Length > 0)
dateParts[0] = dateParts[0].Substring(0, dateParts[0].Length - 1);
}
else
{
if(dateParts[0].Length==2)
dateParts[0] = dateParts[0]+ "/";
}
if(dateParts.Length > 1)
{
if (!yearCheck.IsMatch(dateParts[1]) && dateParts[1] != "")
{
if (dateParts[1].Length > 0)
dateParts[1] = dateParts[1].Substring(0, dateParts[1].Length - 1);
}
}
}
This question already has answers here:
DBNull if statement
(12 answers)
Closed 7 years ago.
I am writing an web application. I want to check if the dateFrom is null or if dateTo is null. If dateFrom is null, print out dateTo, if dateTo is null, then print out dateFrom. If both of then exist, then print out the formation such as 12/3/2015 - 12/3/2015. I have most of the code working, but I cannot figureout how to handle the null date. It keep giving me this exception
String was not recognized as a valid DateTime
Here is my code
public DataSet SearchTimingReq()
{
DateTime effectDateFrom, effectDateTo;
DataSet ds = someDataSet();
if (ds != null && ds.Tables.Count > 0 && ds.Tables[0].Rows.Count > 0)
{
foreach (DataRow row in ds.Tables[0].Rows)
{
if (Convert.ToDateTime(row["Effect_Date_To"].ToString()).ToString("dd/MM/yyyy") == DateTime.MinValue.ToString())
{
row["Effective_Period"] = effectDateFrom.ToString("dd/MM/yyyy");
}
if (Convert.ToDateTime(row["Effect_Date_From"].ToString()).ToString("dd/MM/yyyy") == DateTime.MinValue.ToString())
{
row["Effective_Period"] = effectDateTo.ToString("dd/MM/yyyy");
}
if (effectDateTo != DateTime.MinValue && effectDateFrom == DateTime.MinValue)
{
row["Effective_Period"] = Convert.ToDateTime(row["Effect_Date_From"].ToString()).ToString("dd/MM/yyyy") + " - " + Convert.ToDateTime(row["Effect_Date_To"].ToString()).ToString("dd/MM/yyyy");
}
}
}
}
Updated code
if (!DBNull.Value.Equals(row["Effect_Date_From"]))
{
row["Effective_Period"] = Convert.ToDateTime(row["Effect_Date_To"].ToString()).ToString("dd/MM/yyyy");
}
if (!DBNull.Value.Equals(row["Effect_Date_To"]))
{
row["Effective_Period"] = Convert.ToDateTime(row["Effect_Date_From"]).ToString("dd/MM/yyyy");
}
if (DBNull.Value.Equals(row["Effect_Date_To"]) && DBNull.Value.Equals(row["Effect_Date_From"]))
{
row["Effective_Period"] = Convert.ToDateTime(row["Effect_Date_From"].ToString()).ToString("dd/MM/yyyy") + " - " + Convert.ToDateTime(row["Effect_Date_To"].ToString()).ToString("dd/MM/yyyy");
}
You can use the code below to check for null values on a datatable's datarows.
if (DBNull.Value.Equals(row["Effect_Date_From"]))
{
// null
}
You can use DateTime.TryParse to handle invalid DateTime values and also parse the date at the same time.
DateTime d;
if(DateTime.TryParse(row["column"], out d))
{
//it's a valid DT
}
else
{
//invalid
}
I'd like to query my customers for the ones, whose birthdays are yet to come.
I've tried this query, and it - of course - has failed breathtakingly:
Addresses.Where(adr => adr.DateOfBirth != null && adr.DateOfBirth.Value >
DateTime.Now).Take(15).ToList();
Of course this can't work properly (not if you're born in the future) and I'd like to know how I can query my Nullable<DateTime> without a year?
You can do it in one line like this:
context.Addresses.Where(adr => adr.DateOfBirth != null).OrderBy(adr => EntityFunctions.DiffDays(DateTime.Today, EntityFunctions.AddYears(adr.DateOfBirth, EntityFunctions.DiffYears(adr.DateOfBirth, DateTime.Today) + ((adr.DateOfBirth.Month < DateTime.Today.Month || (adr.DateOfBirth.Day <= DateTime.Today.Day && adr.DateOfBirth.Month == DateTime.Today.Month)) ? 1 : 0)))).Take(15).ToList();
Or in a more readable format:
var query = from adr in context.Addresses
where adr.DateOfBirth != null
let diffYears = EntityFunctions.DiffYears(adr.DateOfBirth, DateTime.Today)
let birthdayOccurred = adr.DateOfBirth.Month < DateTime.Today.Month || (adr.DateOfBirth.Day <= DateTime.Today.Day && adr.DateOfBirth.Month == DateTime.Today.Month)
let nextBirthdate = EntityFunctions.AddYears(adr.DateOfBirth, diffYears + (birthdayOccurred ? 1 : 0))
let daysToBirthdate = EntityFunctions.DiffDays(DateTime.Today, nextBirthdate)
orderby daysToBirthdate
select adr;
var result = query.Take(15).ToList();
I'm not sure you can do this as a one-liner. Certainly not with any degree of clarity.
The needed steps are:
Create an ordered list containing only the birthdates where the
month/day comes after today.
Create an ordered list containing only the birthdates where the month/day is before today.
Append the second list to the first one, you now have a single list, sorted in
birthday order.
Take the first 15.
I think the C# code would look something like this (You might need to add a List or two.)
var list1 = Addresses.Where(adr => adr.DateOfBirth != null && (adr.DateOfBirth.Value.Month > DateTime.Today.Month || (adr.DateOfBirth.Value.Month == DateTime.Today.Month && adr.DateOfBirth.Value.Day >= DateTime.Today.Day))).ToList();
var list2 = Addresses.Where(adr => adr.DateOfBirth != null && (adr.DateOfBirth.Value.Month < DateTime.Today.Month || (adr.DateOfBirth.Value.Month == DateTime.Today.Month && adr.DateOfBirth.Value.Day < DateTime.Today.Day))).ToList();
var fullList = list1.Add(list2);
Im not familiar with Linq, I'll try to help with some pseudocode.
Most important condition should look like this:
Date(CurrentDate.Year, DateOfBirth.Month, DateOfBirth.Day) >= CurrentDate
|| ' OR
Date(CurrentDate.Year + 1, DateOfBirth.Month, DateOfBirth.Day) >= CurrentDate
This will work 31 December too.
Alternative:
// consider this as pseudocode, I didnt tested that in C#
function GetNextBirthday(DateTime DateOfBirth)
{
int yearOfNextBirthday;
int birthdayMMDD = DateOfBirth.Month*100 + DateOfBirth.Day;
int todayMMDD = CurrentDate.Month*100 + CurrentDate.Day;
if (birthdayMMDD >= todayMMDD)
{
yearOfNextBirthday = CurrentDate.Year; // this year
}
else
{
yearOfNextBirthday = CurrentDate.Year + 1; // next year
}
DateTime nextBirthday;
// you have to write this line yourself, i dont remember how to make date from Y, M, D
nextBirthday = DateFromYMD(yearOfNextBirthday, DateOfBirth.Month, DateOfBirth.Day);
return nextBirthday;
}
Here is my entry for "one liner":
DateTime now = DateTime.Now;
var next15 =
from a in db.Addresses
where a.DateOfBirth != null
let diff = EntityFunctions.DiffSeconds(
EntityFunctions.AddYears(now, -EntityFunctions.DiffYears(a.DateOfBirth, now)),
a.DateOfBirth)
orderby diff >= 0 ? diff : diff + 366*24*60*60
select new a;
var res = next15.Take(15).ToList();
Just tested with SQL Database - and it works like charm ;)
Try something like this; (this is working - I've tested)
//A mock up value for comparison (as DayOfYear not supported in Linq)
int doy = DateTime.Today.Month * 31 + DateTime.Today.Day;
var results = Addresses.Where(a => a.DateOfBirth != null)
.OrderBy( a =>
(a.DateOfBirth.Value.Month * 31 + a.DateOfBirth.Value.Day) +
(a.DateOfBirth.Value.Month * 31 + a.DateOfBirth.Value.Day > doy ? 0 : 400 ))
.Take(15).ToList();
Here's the same solution as #Aducci but with nullable date and the DBFunctions, as EntityFunctions became deprecated.
pacientes = from paciente in pacientes
where paciente.Nascimento != null
let diffYears = DbFunctions.DiffYears(paciente.Nascimento, DateTime.Today)
let birthdayOccurred = paciente.Nascimento.Value.Month < DateTime.Today.Month
|| (paciente.Nascimento.Value.Day <= DateTime.Today.Day && paciente.Nascimento.Value.Month == DateTime.Today.Month)
let nextBirthdate = DbFunctions.AddYears(paciente.Nascimento, diffYears + (birthdayOccurred ? 1 : 0))
let daysToBirthdate = DbFunctions.DiffDays(DateTime.Today, nextBirthdate)
orderby daysToBirthdate
select paciente;