Unable to Compare 2 DateTime, from CRM and Excel - c#

I encountered issue comparing DateTime values from CRM and Excel.
1. DateTime excelDT1 = Convert.ToDateTime(row[Excel.notificationdate].ToString().Trim(), System.Globalization.CultureInfo.GetCultureInfo("hi-IN").DateTimeFormat); ;
2. var excelDT2 = row[Excel.notificationdate].ToString().Trim();
3. var excelDT3 = row[Excel.notificationdate];
4. DateTime crmDT1 = Convert.ToDateTime(caseEntity.Attributes[Case.notificationdate].ToString().Trim(), System.Globalization.CultureInfo.GetCultureInfo("hi-IN").DateTimeFormat); ;
5. var crmDT2 = caseEntity.Attributes[Case.notificationdate].ToString().Trim();
6. var crmDT3 = caseEntity.Attributes[Case.notificationdate];
Below are the outputs respectively:
excelDT1: 1/13/2020 12:00:00 AM
excelDT2: 13/01/2020
excelDT3: 13/01/2020
crmDT1: 12/1/2020 4:00:00 PM
crmDT2: 1/12/2020 4:00:00 PM
crmDT3: 1/12/2020 4:00:00 PM
May I know how can I format the above such that they can be checked if they are equal?
Thank you.

You can compare 1st and 4th with public static bool Equals (DateTime t1, DateTime t2);
var result = DateTime.Equals(excelDT1, crmDT1);

Related

How can I check whether there is conflict in time from string like 6:00 PM to 9:00 PM

I am building something like exam datesheet. I'm currently having issues in finding conflicts between time..
I have a List of strings that stores time intervals like-
List<string> times = new List<string>();
times.Add("6:00 PM to 9:00 PM");
times.Add("10:00 AM to 1:00 PM");
Now suppose, if want to add below time to the list, I first want to check it does not conflict with the time that is already there.
So, in below case, it should not be added.
if(NotConflict("5:00 PM to 7:00 PM"))
times.Add("5:00 PM to 7:00 PM");
But the following can be added since there is no conflict.
if(NotConflict("2:00 PM to 5:00 PM"))
times.Add("2:00 PM to 5:00 PM");
I cannot use DateTime here because it the very old system and time is being stored like above. And it being used at many places.
This should work:
private static Tuple<DateTime, DateTime> ParseDate(string dateTimes)
{
var split = dateTimes.Split(new[] { " to " }, StringSplitOptions.None);
var time1 = DateTime.ParseExact(split[0], "h:mm tt",
CultureInfo.InvariantCulture);
var time2 = DateTime.ParseExact(split[1], "h:mm tt",
CultureInfo.InvariantCulture);
return Tuple.Create(time1, time2);
}
private static bool NotConflict(IEnumerable<string> times, string time) {
var incTime = ParseDate(time);
return !times.Any(t => {
var parsed = ParseDate(t);
return incTime.Item1 <= parsed.Item2 && parsed.Item1 <= incTime.Item2;
});
}
public static void Main()
{
var times = new List<string>();
times.Add("6:00 PM to 9:00 PM");
times.Add("10:00 AM to 1:00 PM");
Console.WriteLine("No Conflict 5:00 PM to 7:00 PM: {0}", NotConflict(times, "5:00 PM to 7:00 PM"));
Console.WriteLine("No Conflict 2:00 PM to 5:00 PM: {0}", NotConflict(times, "2:00 PM to 5:00 PM"));
}
ParseDate will return a formatted tuple with the start and end time in Item1 and Item2 respectively. Then you simply use Linq's Any function to filter and make sure that you don't return any that fall within the bounds.
See the DotNet fiddle here.

Excel time validation for a range using EPPlus

I want to validate a column in Excel using EPPlus for time range like 1:00 PM to 11:00 AM.
Time must be "hh:mm AM/PM" format.
I solved the problem. Here is the code :
var validationEndTime = workSheet.DataValidations.AddTimeValidation("H:H");
validationEndTime.ShowInputMessage = true;
validationEndTime.Prompt = "Add end time in hh:mm AM/PM format as example 9:00 AM or 12:30 PM";
validationEndTime.ErrorStyle = ExcelDataValidationWarningStyle.stop;
validationEndTime.ShowErrorMessage = true;
validationEndTime.Error = "Insert valid time";
validationStartDate.Operator = ExcelDataValidationOperator.between;
var timeEnd = validationStartDate.Formula.Value;
timeEnd.Hour = 00;
timeEnd.Minute = 00;
var timeEnd2 = validationStartDate.Formula2.Value;
timeEnd2.Hour = 23;
timeEnd2.Minute = 59;
validationEndTime.Formula.Value = timeEnd;
validationEndTime.Formula2.Value = timeEnd2;
And this will make a validation in excel like this :
I tried a lot to make DataValidations.AddDateTimeValidation work but it didn't work for me. So instead of looking for solution in C#, I tried to figure out how excel deals with time.
Excel stores time in decimal numbers. So instead of using DataValidations.AddDateTimeValidation, I used
DataValidations.AddDecimalValidation,
I converted the start time and end time in excel to decimal number with 10 digit precision.
So 12:00:00 just becomes 0.00 and 11:59:59 pm becomes 0.999305555555556.
My C# code looks something like this
var validdateTime = sheet1.DataValidations.AddDecimalValidation("H:H");
validdateTime.ShowInputMessage = true;
validdateTime.Prompt = "Add end time in hh:mm AM/PM format as example 9:00 AM or 12:30 PM";
validdateTime.AllowBlank = false;
validdateTime.ShowErrorMessage = true;
validdateTime.Error = "The time entered is not valid";
validdateTime.ErrorStyle = ExcelDataValidationWarningStyle.stop;
validdateTime.Operator = ExcelDataValidationOperator.between;
validdateTime.Formula.Value = 0.0;
validdateTime.Formula2.Value = 0.999305555555556;

Why Timespan subtract method returns error value?

I am trying to find days between two dates using a Time span.
nextdate1='2014-12-20'
today `='2014-12-18'`
My sample code is:
DateTime nexdate1 = dr.GetDateTime(2); //gets from database. I checked and the value is correct
DateTime today = DateTime.Now;
TimeSpan nextdate = nexdate1.Subtract(today);
int difference = nextdate.Days;
Now I get difference=1. Actually the difference is 2 (20-18).
Why it shows difference as 1?
TimeSpan.Days is an int. Your answer is getting truncated.
In the following code:
var date1 = DateTime.Parse("Dec 12, 2014");
var date2 = DateTime.Parse("Dec 14, 2014");
var difference = (date2 - date1).Days;
difference is set to 2.
But in this code:
var date1 = DateTime.Parse("Dec 12, 2014 12:01 AM");
var date2 = DateTime.Parse("Dec 14, 2014");
var difference = (date2 - date1).Days;
difference is set to 1.
When we look at the timespan date2 - date1, we get the following:
{1.23:59:00}
Days: 1
Hours: 23
Minutes: 59
Seconds: 0
TotalDays: 1.9993055555555554
You should set nextDate = nexdate1.Date.Subtract(DateTime.Today); so that you're only looking at the difference in days, or take (int)Math.Round(nextDate.TotalDays)
Actually your datetime variable having time part, because of that time your result get affected. Hence you have to find only date part of your datetime value:
Use DateTime.Date
Do it like this:
DateTime nexdate1 = dr.GetDateTime(2);
DateTime today = DateTime.Now;
TimeSpan nextdate = nexdate1.Date.Subtract(today.Date); // Here find only date part from datetime value.
//TimeSpan nextdate = nexdate1-today
int difference = nextdate.Days;

Create a List of hours

I'm trying to create list of hours my code like
var hours = Enumerable.Range(00, 24).Select(i => i.ToString("D2")));
it generates something like this in 24 hour format
but actually i need same thing not on 24 hours but 12 like after with AM PM postfix
what is the best way to generate hour list with 00.00 AM/PM formatted
Thanks
You can create a DateTime instance then use ToString format of hh.mm tt.
var hours = Enumerable.Range(00, 24)
.Select(i => new DateTime(2000,1,1,i,0,0).ToString("hh.mm tt"));
You need to execute the query using something like ToArray() to get the result since the behavior of linq is deferred execution.
var hours = Enumerable.Range(00, 24).Select(i => (DateTime.MinValue.AddHours(i)).ToString("hh.mm tt"));
You're dealing with time, so using appropriate type, DateTime, seems better than using int:
var hours = from i in Enumerable.Range(0, 24)
let h = new DateTime(2014, 1, 1, i, 0, 0)
select h.ToString("t", CultureInfo.InvariantCulture);
var startDate = DateTime.Today;
IEnumerable<DateTime> listOfHours = Enumerable.Range(0, 24).Select(h => startDate.AddHours(h));
If you need more flexibility and have from/to for specific times that overlap midnight (and increase step to let's say every 2h) you can use something like this:
private static IEnumerable<string> GetListOfHours(DateTime start, DateTime end, int step)
{
while (start <= end)
{
yield return start.ToString("hh.mm tt");
start = start.AddHours(step);
}
}
So this:
var start = DateTime.Now.Date.AddHours(6); // 6 am
var end = DateTime.Now.AddDays(1).Date.AddHours(2); // 2 am
var step = 1;
var list = GetListOfHours(start, end, step);
Will produce this:
06.00 AM
07.00 AM
08.00 AM
09.00 AM
10.00 AM
11.00 AM
12.00 PM
01.00 PM
02.00 PM
03.00 PM
04.00 PM
05.00 PM
06.00 PM
07.00 PM
08.00 PM
09.00 PM
10.00 PM
11.00 PM
12.00 AM
01.00 AM
02.00 AM
https://dotnetfiddle.net/8LYxA6

Reason for this strange behavior of DateTime?

I have this method:
public static DateTime GetDatetime(string ampm, string hour, string minute)
{
int iHour = Convert.ToInt32(hour);
int iMinute = Convert.ToInt32(minute);
if (ampm == "PM" && iHour != 12)
iHour = 12 + iHour;
DateTime dtTime = new DateTime(DateTime.Now.Year, DateTime.Now.Month,
DateTime.Now.Day, iHour, iMinute, 0);
return dtTime;
}
which basically accepts AM/PM and hour and minute and gives DateTime. I give input as
DateTime startTIme = GetDatetime("AM", "12", "30");
I get time correctly as 12:30 in morning on my local machine. However when I run this same method on server I get 12:30 PM. This is driving me nuts. Can anybody help me out? What am I doing wrong?
Update:
My new function is:
public static DateTime GetDatetime(string ampm, string hour, string minute)
{
int iHour = Convert.ToInt32(hour);
int iMinute = Convert.ToInt32(minute);
if (ampm == "PM" && iHour != 12)
iHour = 12 + iHour;
else if (ampm == "AM" && iHour == 12)
iHour = 0;
DateTime dtTime = new DateTime(DateTime.Now.Year, DateTime.Now.Month,
DateTime.Now.Day, iHour, iMinute, 0);
return dtTime;
}
This seem to work fine. Can anybody find any issue in this code?
Your function always returns 12:30 PM (noon) when called with: GetDatetime("AM", "12", "30");
As Eric mentioned the reason you're getting different results might be that the two computers print out dates in a different way.
For example with my settings the result is:
2012-05-03 12:30:00 (half-hour past noon in my computer's format)
With US settings the result is:
5/3/2012 12:30:00 PM (half-hour past noon in US format)
To print the date in the same way on both machines, you can specify a culture info to use for the date formatting:
DateTime dateResult = GetDatetime("AM", "12", "30");
string strResult = dateResult.ToString(System.Globalization.CultureInfo.GetCultureInfo("en-US"));
On all computers strResult will have the following value: 5/3/2012 12:30:00 PM
But most importantly, you should fix your code to get the expected result (12AM should be midnight, not noon).
You can simply use the DateTime.Parse() (msdn link) (or TryParse()) method to do this. Look at following example code:
string[] times = new string[]
{
"00:00 AM"
, "01:00 AM"
, "10:00 AM"
, "12:00 AM"
, "00:00 PM"
, "01:00 PM"
, "10:00 PM"
, "12:00 PM"
};
foreach (var time in times)
{
DateTime date = DateTime.Parse(time);
Console.WriteLine(date);
}
Gives output:
03/05/2012 00:00:00
03/05/2012 01:00:00
03/05/2012 10:00:00
03/05/2012 00:00:00
03/05/2012 12:00:00
03/05/2012 13:00:00
03/05/2012 22:00:00
03/05/2012 12:00:00
In your case, just make a string that contains "hour":"minutes" + "AM" or "PM". In code that would be (if your input is invalid, the Parse() method throws an exception or else a very weird result)):
public static DateTime GetDatetime(string ampm, string hour, string minute)
{
return DateTime.Parse(hour + ":" + minute + " " + ampm);
}
Please check the current culture like this:
Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo("en-us");
Because in different cultures, dates are written in different formats. e.g. (may the 3rd) = 3/5/2012 or 5/3/2012 and so on
http://msdn.microsoft.com/en-us/library/system.threading.thread.currentculture.aspx
Your machine isnt setup to use 24 hour clock
The server is.
Change that in the usual way and all will be fine :)
How to:
Click Start, and then click Control Panel.
Click Date, Time, Language, and Regional Options, and then click Regional and Language Options.
To change one or more of the individual settings, click Customise.
Got to time tab and the formats are there!

Categories