I am writing C# code for a business rule in a program called Prophet 21.
The code essentially is saying, if a product price has been updated in the last year, put that price into a field called PO Price.
Everything works solid except for one tiny problem, when making sure that the price was updated within the last year, it looks at the PO Price update date. At some point in the past, a lot of these were set to 00/00/00 and using an algorithm with date doesn't seem to understand it. My best guess is that I need to convert the date somehow, but I am quite a C# novice, any help would be appreciated. Here's the code I am working with.
public class SetPOCost : Rule //this rule sets the PO cost to the other cost when the item is stockable and the disposition is B
{
public override RuleResult Execute()
{
RuleResult result = new RuleResult();
result.Success = true;
string s = Data.Fields["other_cost"].FieldValue;
decimal ldcOtherCost = Convert.ToDecimal(s);
s = Data.Fields["po_cost"].FieldValue;
decimal ldcPOCost = Convert.ToDecimal(s);
string stockable = Data.Fields["stockable"].FieldValue;
string disposition = Data.Fields["disposition"].FieldValue;
s = Data.Fields["ufc_inventory_supplier_date_cost_last_modified"].FieldValue;
//this next line is added from the SuggestPromiseDate rule because it was running into errors doing both rules
Data.Fields.GetFieldByAlias("suggested_promise_date").FieldValue = Data.Fields.GetFieldByAlias("line_max_promise_date").FieldValue;
DateTime dtLastModified = Convert.ToDateTime(s);
DateTime thisDate = DateTime.Today;
DateTime thisDateLastYear = thisDate.AddYears(-1);
Boolean dateIsGood = dtLastModified.CompareTo(thisDateLastYear) >= 0;
if (stockable == "N" && disposition == "B" && ldcPOCost == 0 && ldcOtherCost > 0 && dateIsGood)
{
Data.Fields["po_cost"].FieldValue = ldcOtherCost.ToString();
}
return result;
}
You can use TryParse to check the date coming in.
s = Data.Fields["ufc_inventory_supplier_date_cost_last_modified"].FieldValue;
//this next line is added from the SuggestPromiseDate rule because it was running into errors doing both rules
Data.Fields.GetFieldByAlias("suggested_promise_date").FieldValue = Data.Fields.GetFieldByAlias("line_max_promise_date").FieldValue;
DateTime dtLastModified;
if (DateTime.TryParse(s, out dtLastModified) == false)
dtLastModified = DateTime.MinValue;
How about just:
s = Data.Fields["ufc_inventory_supplier_date_cost_last_modified"].FieldValue;
if (s == "00/00/00") {
s="01/01/0001";
}
00/00/00 is not a valid date in .NET; dates start counting from January 1st, 0001. Detect when this date occurs in your original data source, and then create a new date as new DateTime(0);.
Related
Is it possible to make a pattern for NodaTime's LocalTime, which matches the ISO 8601 standard for times? That is, can you make (minutes and) seconds optional, like you can make fractional seconds optional? I wish to be able to always have hours and minutes, but add everything else only when needed.
This doesn't exist in NodaTime currently, nor does it exist as an option for the built in DateTime and DateTimeOffset objects.
Probably the best you could do is to create two patterns and add some logic for which to use.
var p1 = LocalTimePattern.ExtendedIsoPattern;
var p2 = LocalTimePattern.CreateWithInvariantCulture("HH:mm");
// formatting
LocalTime t = // your input
var p = t.Second == 0 && t.TickOfSecond == 0 ? p2 : p1;
string s = t.Format(p);
// parsing
string s = // your input
var result = p1.Parse(s);
if (!result.Success)
result = p2.Parse(s);
if (!result.Success)
// throw some exception, etc.
LocalTime t = result.Value;
I would like to query the db for items with a date greater than or equal to a given date.
The date in the db is a datetime and records time.
If the user enters the search string "1/30/2014", they expect entries that occurred at any time on that date to be returned. However, anything that has a time after 12 am is not returned.
I know I could simply add a day to the search string, but is there a more appropriate way?
if (form["closedend"] != "")
{
DateTime d = DateTime.Parse(form["closedend"]);
traces = traces.Where(s => s.date_Closed >= d);
}
You can use the Date property to truncate the time part:
traces = traces.Where(s => s.date_Closed.Date <= d.Date);
On this way you'd include this day since both DateTimes are midnight.
Update if you use LINQ to Entities DateTime.Date is not supported, you could use this solution: Using DateTime in LINQ to Entities
.Where(s => EntityFunctions.TruncateTime(s.date_Closed) <= EntityFunctions.TruncateTime(d))
You said
with a date greater than or equal to a given date
but in your code you write
s.date_Closed <= d
I think you must change <= by >= to obtain dates greater or equal to d, now you're getting dates less or equal to d.
For this example you don't need neccessary any other dll. You can implement other function, which return bool, f.e:
public bool MyFunction(DateTime s)
{
DateTime d = DateTime.Parse(Your constructor);
return (s.date_Closed >= d);
}
var query = from obj in traces
where MyFunction(obj.date_Closed.Date)
select obj;
or:
var query = traces.Where(p => MyFunction(p.data_Closed.Date));
You can use DbFunctions.TruncateTime(StartDateTime) To remove the time from datetime.
if (form["closedend"] != "")
{
DateTime d = DateTime.Parse(form["closedend"]);
traces = traces.Where(s => DbFunctions.TruncateTime(s.date_Closed) >= DbFunctions.TruncateTime(d));
}
Can you help me in removing the time in my code or rather correct my code for possible errors.
Thanks. Here's my code and ill state the error later.
else if (this.dateTimePicker1.Value != DateTime.Now)
{
this.chkBxLessNinety.Enabled = false;
string dateInString = Convert.ToString(Convert.ToDateTime(_dr[4]));
DateTime startdate = DateTime.Parse(dateInString);
DateTime datelimit = startdate.AddDays(90);
//string date = Convert.ToString(Convert.ToDateTime(datelimit.Date).ToString("mm/dd/yyyy"));
string mydate1 = this.dateTimePicker1.Value.ToShortDateString();
if (mydate1 > datelimit)
{
MessageBox.Show("Cannot Sync data more or equal to 90 days");
}
else
{
}
the line if (mydate1 > datelimit) shows an error which says > cannot be applied as operand of type string an datetime.
Please help.
Thanks in advance.
You want to compare DateTimes with each other. Since you want to exclude the time portion then the Date property will make both dates at midnight hour.
DateTime mydate1 = this.dateTimePicker1.Value;
if (mydate1.Date > datelimit.Date)
{
MessageBox.Show("Cannot Sync data more or equal to 90 days");
}
Just remove .ToShortDateString()
And also:
string dateInString = Convert.ToString(Convert.ToDateTime(_dr[4]));
DateTime startdate = DateTime.Parse(dateInString);
Don't convert from DateTime to string and then back to DateTime, it's pointless
You can't use the > to compare a string and a DateTime. Instead, you should replace
string mydate1 = this.dateTimePicker1.Value.ToShortDateString();
with
DateTime mydate1 = this.dateTimePicker1.Value;
This way, you'll be comparing things of the same type (DateTime).
I need to compare a cell's value to dates in the scope of the current week.
I need to see if a date from a cell can be matched to any date in the current week. If so, success Match should be incremented.
I was thinking about putting dates in an array or dictionary and then compare it to a cell value.
DateTime cellValue = DateTime.Now;
var beginweek = DateTime.Now.Date.AddDays( (int)DateTime.Now.DayOfWeek *-1);
var endweek = beginweek.AddDays(6);
if (cellValue.Date >= beginweek.Date && cellValue.Date <= endweek.Date)
{
//do something
}
You can use the Week class of the Time Period Library for .NET:
// ----------------------------------------------------------------------
public bool IsInCurrentWeek( DateTime test )
{
return new Week().HasInside( test );
} // IsInCurrentWeek
I fixed this with a solution based on Jeremy's answer. The difference is that I used
DateTime cellDateValue = Convert.ToDateTime(((HtmlCell)cell).InnerText);
instead of
DateTime cellValue = DateTime.Now;
Is there a way to compare two DateTime variables in Linq2Sql but to disregard the Time part.
The app stores items in the DB and adds a published date. I want to keep the exact time but still be able to pull by the date itself.
I want to compare 12/3/89 12:43:34 and 12/3/89 11:22:12 and have it disregard the actual time of day so both of these are considered the same.
I guess I can set all the times of day to 00:00:00 before I compare but I actually do want to know the time of day I just also want to be able to compare by date only.
I found some code that has the same issue and they compare the year, month and day separately. Is there a better way to do this?
try using the Date property on the DateTime Object...
if(dtOne.Date == dtTwo.Date)
....
For a true comparison, you can use:
dateTime1.Date.CompareTo(dateTime2.Date);
This is how I do this in order to work with LINQ.
DateTime date_time_to_compare = DateTime.Now;
//Compare only date parts
context.YourObject.FirstOrDefault(r =>
EntityFunctions.TruncateTime(r.date) == EntityFunctions.TruncateTime(date_to_compare));
If you only use dtOne.Date == dtTwo.Date it wont work with LINQ (Error: The specified type member 'Date' is not supported in LINQ to Entities)
If you're using Entity Framework < v6.0, then use EntityFunctions.TruncateTime
If you're using Entity Framework >= v6.0, then use DbFunctions.TruncateTime
Use either (based on your EF version) around any DateTime class property you want to use inside your Linq query
Example
var list = db.Cars.Where(c=> DbFunctions.TruncateTime(c.CreatedDate)
>= DbFunctions.TruncateTime(DateTime.UtcNow));
DateTime dt1 = DateTime.Now.Date;
DateTime dt2 = Convert.ToDateTime(TextBox4.Text.Trim()).Date;
if (dt1 >= dt2)
{
MessageBox.Show("Valid Date");
}
else
{
MessageBox.Show("Invalid Date... Please Give Correct Date....");
}
DateTime? NextChoiceDate = new DateTime();
DateTIme? NextSwitchDate = new DateTime();
if(NextChoiceDate.Value.Date == NextSwitchDate.Value.Date)
{
Console.WriteLine("Equal");
}
You can use this if you are using nullable DateFields.
DateTime dt1=DateTime.ParseExact(date1,"dd-MM-yyyy",null);
DateTime dt2=DateTime.ParseExact(date2,"dd-MM-yyyy",null);
int cmp=dt1.CompareTo(dt2);
if(cmp>0) {
// date1 is greater means date1 is comes after date2
} else if(cmp<0) {
// date2 is greater means date1 is comes after date1
} else {
// date1 is same as date2
}
DateTime econvertedDate = Convert.ToDateTime(end_date);
DateTime sconvertedDate = Convert.ToDateTime(start_date);
TimeSpan age = econvertedDate.Subtract(sconvertedDate);
Int32 diff = Convert.ToInt32(age.TotalDays);
The diff value represents the number of days for the age. If the value is negative the start date falls after the end date. This is a good check.
In .NET 5:
To compare date without time you must use EF.Functions.DateDiffDay() otherwise you will be comparing in code and this means you are probably pulling way more data from the DB than you need to.
.Where(x => EF.Functions.DateDiffDay(x.ReceiptDate, value) == 0);
You can try
if(dtOne.Year == dtTwo.Year && dtOne.Month == dtTwo.Month && dtOne.Day == dtTwo.Day)
....
In your join or where clause, use the Date property of the column. Behind the scenes, this executes a CONVERT(DATE, <expression>) operation. This should allow you to compare dates without the time.
int o1 = date1.IndexOf("-");
int o2 = date1.IndexOf("-",o1 + 1);
string str11 = date1.Substring(0,o1);
string str12 = date1.Substring(o1 + 1, o2 - o1 - 1);
string str13 = date1.Substring(o2 + 1);
int o21 = date2.IndexOf("-");
int o22 = date2.IndexOf("-", o1 + 1);
string str21 = date2.Substring(0, o1);
string str22 = date2.Substring(o1 + 1, o2 - o1 - 1);
string str23 = date2.Substring(o2 + 1);
if (Convert.ToInt32(str11) > Convert.ToInt32(str21))
{
}
else if (Convert.ToInt32(str12) > Convert.ToInt32(str22))
{
}
else if (Convert.ToInt32(str12) == Convert.ToInt32(str22) && Convert.ToInt32(str13) > Convert.ToInt32(str23))
{
}