Get datetime from database and split it - c#

I am working on a C# program. I created an EF code-first database in which I read in a csv file. This csv file contains a DateTime object. This DateTime object was saved in the database. Now I have to get this DateTime and parse it into the DATE (dd-mm-yyyy) and the TIME (hh:mm:ss.fff). Unfortunately I don't know how to solve this problem.
private readonly PerformanceAnalyseToolContext db;
public HomeController(PerformanceAnalyseToolContext db)
{
this.db = db;
}
public IActionResult ReadCsvData(string csvData) //get csvData String
{
ChartData chartData = new ChartData();
string[] lines = csvData.Split("\n"); //Split after enter
//List<ChartData> chartDataList = new List<ChartData>();
foreach (var line in lines)
{
string[] values = line.Split(','); // SPlit after ,
try //try catch, because if an error occurs the process has to continue
{
chartData = new ChartData { //Create object from csv data
Timestamp = Convert.ToDateTime(values[0] + "." + values[1]),
Function = Convert.ToString(values[2]),
Duration = Convert.ToInt32(values[4]),
IsError = Convert.ToBoolean(values[5])
};
db.ChartDatas.Add(chartData); //Save object into database
db.SaveChanges();
}
catch(Exception exc)
{
exc.ToString();
}
}
return View(chartData);
}
public List<ChartDatanDTO> GetDataForChart(string function)
{ //here i get the Data from the DB
return db.ChartDatas
.Where(x => x.Function == function)
.Select(x => new ChartDatanDTO
{
durat = x.Duration,
err = x.IsError,
time =x.Timestamp
})
.ToList();
}

You can specify the format of your DateTime in the ToString method.
time = x.Timestamp.ToString("dd-MM-yyyy hh:mm:ss.fff")
If you need them separated you can do ToString twice.
date = x.Timestamp.ToString("dd-MM-yyyy")
time = x.Timestamp.ToString("hh:mm:ss.fff")

You can use DateTime.ParseExact() method
DateTime dt = DateTime.ParseExact(yourDateTime, "yyyy/MM/DD", CultureInfo.InvariantCulture);
for more info you can check:
https://learn.microsoft.com/en-us/dotnet/standard/base-types/parsing-datetime

Convert function directly doesn't work in LINQ,
So you also can use DBFunctions to truncate time and SqlFunctions.DatePart to get time
........
.Select(x => new ChartDatanDTO
{
date = DbFunctions.TruncateTime(x.YourDateTime),
time = SqlFunctions.DatePart("hh", x.YourDateTime) + ":" +
SqlFunctions.DatePart("mm", x.YourDateTime) +":" +
SqlFunctions.DatePart("ss", x.YourDateTime)
});

Related

ShouldQuote putting quotes around all fields in a row instead just the ones I need

I'm only want to put quotes around a fields that are dates and no other field.
I wrote a function to pass to ShouldQuote to return true if the field is a DateTime. But it's putting quotes around every field in the row. I stepped through the code and verified that the result returned from my function is false, but the field still has quotes around it. Am I doing something wrong or this the intended functionality of ShouldQuote?
private bool ShouldQuote(string field, WritingContext context)
{
DateTime date;
var result = DateTime.TryParseExact(field, "MM/dd/yyyy", CultureInfo.InvariantCulture, DateTimeStyles.None, out date);
return result;
}
var config = new Configuration();
config.ShouldQuote = ShouldQuote;
Are you using an earlier version of CsvHelper? You would need CsvConfiguration with the current version 15.0.5.
class Program
{
static void Main(string[] args)
{
var records = new List<Foo>
{
new Foo { Id = 1, Name = "Quinn", Date = "05/20/2020" }
};
var config = new CsvConfiguration(CultureInfo.InvariantCulture)
{
ShouldQuote = ShouldQuote
};
using (var csv = new CsvWriter(Console.Out, config))
{
csv.WriteRecords(records);
}
Console.ReadKey();
}
private static bool ShouldQuote(string field, WritingContext context)
{
DateTime date;
var result = DateTime.TryParseExact(field, "MM/dd/yyyy", CultureInfo.InvariantCulture, DateTimeStyles.None, out date);
return result;
}
}

DateTime parsing in c#:getting a 'System.FormatException: 'String was not recognized as a valid DateTime' error

I have a dataset in a .csv file in a local folder, below is a sample row of the data, it has 13 attributes to each item.
I am parsing this data in C#, my code has been working for 2 years and I cannot remember
The code reading the .csv file is, this section is parsing the data into compiledList.
static string loadFile(string fileLocation)
{
string text = "";
try
{
text = File.ReadAllText(fileLocation);
}
catch (Exception e)
{
Console.WriteLine("An error has occured...");
Console.WriteLine(e.Message);
}
return text;
}
static ConcurrentBag<Item> interpretFile(string text, ConcurrentBag<Item> compiledList)
{
String[] substrings = text.Split('\n');
int settlementPeriod = -1; int totalSP = -1;
foreach (string line in substrings)
{
String[] items = line.Split(',');
if (items[0] == "HDR")
{
settlementPeriod = int.Parse(items[3]);
if (settlementPeriod > 48)
settlementPeriod -= 48;
if (settlementPeriod < 0)
settlementPeriod += 48;
totalSP = getTotalSettlementPeriod(DateTime.ParseExact(items[2], "yyyyMMdd", null), settlementPeriod);
}
if (items[0] == "BOALF")
{
//Item Bid = new Item(items);
Item Bid = new Item
{
recordType = items[0],
unitID = items[1],
acceptID = float.Parse(items[2]),
acceptTime = DateTime.ParseExact(items[3], "yyyyMMddHHmmss", null),
deemedFlag = ToBoolean(items[4]),
soFlag = ToBoolean(items[5]),
storFlag = ToBoolean(items[6]),
fromTime = DateTime.ParseExact(items[7], "yyyyMMddHHmmss", null),
fromLevel = float.Parse(items[8]),
toTime = DateTime.ParseExact(items[9], "yyyyMMddHHmmss", null),
toLevel = float.Parse(items[10]),
settlementPeriod = settlementPeriod,
totalSP = totalSP
};
compiledList.Add(Bid);
Sample item from the .csv is:
When I open the data set in Notebad below is what i see:
Note that items[0] is the first colum from the about sample data set. there the data which I am now having issues with is column 4 which is '2.02E+13' shown above.
What that actually is '20191211202600' which is the 'yyyymmddhhmmss' in number format. I do not know what has changed such that the below is giving me an error.
acceptTime = DateTime.ParseExact(items[3], "yyyyMMddHHmmss", null)
`
The error that I am getting is:
System.FormatException: 'String was not recognized as a valid
DateTime.'
I would appreciate your assistance and let me know if further clarification is required.
Thanks
I don't think the problem is with your C# code, the columns which contain date format yyyymmddhhmmss should be of type string, where they are now treated as a number. This problem arises from the program you are saving the CSV file (for example excel or google spreadsheets) you need to change the column data type to string (as it is now automatically detected as a number).
The following works in .NET fiddle (https://dotnetfiddle.net/), can you verify the string that is being used in the call to DateTime.ParseExact? Perhaps the string is not equal to what you would expect at runtime.
using System;
public class Program
{
public static void Main()
{
Console.WriteLine(DateTime.ParseExact("20191211202600", "yyyyMMddHHmmss", null));
}
}
Output is:
12/11/2019 8:26:00 PM

How to compare date in linq c#

i have 'created date' and 'closed date' in my file and i'm converting it in json so i have that dates in json.
in my method i have two parameter like from date and to date and i want to count particular column data of my file between from date and to date.so how can we write code to fetch it using linq.
i tried this...
public JsonResult StatusDerails(DateTime from,DateTime to)
{
string csvurl = WebConfigurationManager.AppSettings["csvfileurl"];
var lines = System.IO.File.ReadAllLines(csvurl).Skip(1);
List<Product> prdt = new List<Product>();
foreach (string line in lines)
{
Product c1 = new Product();
var split = line.Split(',');
c1.ID = Int32.Parse(split[0]);
c1.Area_Path = split[1];
c1.IterationPath = split[2];
c1.State = split[3];
c1.Reason = split[4];
c1.Priority = Int32.Parse(split[5]);
c1.Severity = split[6];
c1.Tags = split[7];
c1.Title = split[8];
c1.CreatedDate = split[9];
c1.CreatedBy = split[10];
c1.ResolvedDate = split[11];
c1.ResolvedBy = split[12];
c1.ClosedDate = split[13];
c1.AssignedTo = split[14];
prdt.Add(c1);
}
//var list = prdt.GroupBy(a=>a.AreaPath).Select(a=>new UIproduct() {
var productName = prdt.Select(a => a.Area_Path).Distinct();
List<StatusDetail> statusdetail = new List<StatusDetail>();
foreach (var Name in productName)
{
StatusDetail sd = new StatusDetail();
sd.CarryOver = prdt.Where(a => a.CreatedDate >= from.Date.ToString() && a.ClosedDate <= to.Date.ToShortDateString
}
return Json(statusdetail, JsonRequestBehavior.AllowGet);
}
The comparison of DateTime as string will not be a good option and that wont gives you the exact result, So I recommend you to change the type of CreatedDate and ClosedDate to DateTime. and compare two DateTime values in linq. I think instead of splitting json for creating object of certain types you can use json converters.
Fix for your scenario:
c1.CreatedDate = DateTime.Parse(split[9]);
c1.ClosedDate = DateTime.Parse(split[13]);
Don't forget to change the type in the class, Now its fine to use the linq as like the following:
sd.CarryOver = prdt.Where(a => a.CreatedDate >= from.Date && a.ClosedDate <= to.Date);

[System.DateTime])' has no supported translation to SQL

I want to execute a query like this:
List<supervisorAnswerQuesttionPres> temp =
(from i in dbconnect.tblAnswerLists
where i.StudentNum == studentNumber
select new supervisorAnswerQuesttionPres
{
answerList = _resAnswerList,
questionList = _resQuestionist,
date = ConvertToPersianToShow(i.dateOfAnswer.Value.Date)
}).OrderBy(i => i.date).ToList();
My class that this query is returned is something like this :
public class supervisorAnswerQuesttionPres
{
public string date { set; get; }
public List<string> questionList { set; get; }
public List<string> answerList { set; get; }
}
In this query i use a function to convert my Datetime to another presentation i use this function for this :
public string ConvertToPersianToShow(DateTime? datetime)
{
string date;
DateTime dt;
if (!datetime.HasValue) return "";
dt = datetime.Value;
// dt = datetime;
string year = Convert.ToString(persian_date.GetYear(dt));
string month = Convert.ToString(persian_date.GetMonth(dt));
string day = Convert.ToString(persian_date.GetDayOfMonth(dt));
if (month.Length == 1)
{
month = "0" + Convert.ToString(persian_date.GetMonth(dt));
}
if (day.Length == 1)
{
day = "0" + Convert.ToString(persian_date.GetDayOfMonth(dt));
}
Convert.ToString(persian_date.GetMonth(dt)) + "/" +
+ dt.Minute + ")";
date = year + "/" + month + "/" + day;
return date;
}
This function just convert my DateTime ,But when i execute the query i got this error:
Method 'System.String ConvertToPersianToShow(System.Nullable`1[System.DateTime])' has no supported translation to SQL.
It's trying to convert the query into SQL, but doesn't know how to convert the ConvertToPersianToShow method.
The solution is to call ToList() after the where clause to bring the entities into memory, then do the select:
var temp = dbconnect.tblAnswerLists
.Where(i => i.StudentNum == studentNumber)
.ToList() // <-- This will bring the data into memory.
.Select(i => new supervisorAnswerQuesttionPres
{
answerList = _resAnswerList,
questionList = _resQuestionist,
date = ConvertToPersianToShow(i.dateOfAnswer.Value.Date)
})
.OrderBy(i => i.date)
.ToList()
When calling ToList(), the query is translated into SQL, e.g. something like
SELECT * FROM <table> WHERE StudentNum = '<studentNumber>'
and executed against the database. When the data returns and you have it in memory, you can use LINQ to Objects to query and manipulate the data further.
NOTE! Generally you should be careful to call ToList before you've added at least a where clause, otherwise you'll end up fetching way too much data into memory.
try this:
var temp = (from i in dbconnect.tblAnswerLists
let pDate = ConvertToPersianToShow(i.dateOfAnswer.Value.Date)
where i.StudentNum == studentNumber
select new PresentClass.supervisorAnswerQuesttionPres
{
answerList = _resAnswerList,
questionList = _resQuestionist,
date = pDate
}).OrderBy(i => i.date).ToList();
reference: Method x has no supported translation to SQL
LINQ to SQL does not know how to translate a call your method 'ConvertToPersianToShow' into SQL in order to execute the where clause on the server. Your method does not exist on the server.
maybe something like this would help, but if it doesn't work you should fetch your data and then change it to the way you want it to be shown as
List<PresentClass.supervisorAnswerQuesttionPres> temp
= (from i in dbconnect.tblAnswerLists
let PDate=ConvertToPersianToShow(i.dateOfAnswer.Value.Date)
where i.StudentNum == studentNumber
select new PresentClass.supervisorAnswerQuesttionPres
{
answerList = _resAnswerList,
questionList = _resQuestionist,
date = PDate
}).OrderBy(i=>i.date).ToList();
As some people have noted, you can't run C# in SQL (well...lets ignore SQL CLR).
However your real problem comes from your poorly architected program.
Your data layer is doing display logic, and none of the Microsoft engineers expected that.
You should bring your data out of the database first. Then on your display logic use ConvertToPersianToShow(DateTime?) to bind to your view.
public class SupervisorAnswerQuestion
{
public DateTime? Date { set; get; }
public List<string> Questions { set; get; }
public List<string> Answers { set; get; }
}
public class SupervisorAnswerQuestionViewModel
{
public SupervisorAnswerQuestion SupervisorAnswerQuestion {get;set;}
public string DateFormated
{
get { return SupervisorAnswerQuestion.Date.ToString("yyyy/MM/dd");
}
}
Actual come to think of it. Scrap ConvertToPersianToShow, learn DateTime.ToString(string) for datetime formatting.

DateTime class common error displayed again

I run into a little common problem with datetime class that I have no idea how to resolve.
I don't know what the error is but I see the troubleshooting tips are displayed as
When converting a string to DateTime, parse the string to take the date before putting each variable into the DateTime object. Make sure your method arguments are in the right format.
Here is the piece of code I extract from my program,
public IEnumerable<CONTACT_INFO> GetContactInfo(string tableName)
{
DataTable dt = GetUserInfo(tableName);
List<CONTACT_INFO> lst = new List<CONTACT_INFO>();
foreach (DataRow row in dt.Rows)
{
string sDate = "";
if(!string.IsNullOrEmpty(row["birthday"].ToString()))
{
sDate = row["birthday"].ToString();
}
string format = "yyyyMMdd";
System.Globalization.CultureInfo provider =CultureInfo.InvariantCulture;
string datetime = DateTime.Now.ToShortDateString();
if (!string.IsNullOrEmpty(sDate))
{
datetime = DateTime.ParseExact(sDate, format, provider).ToShortDateString();
}
if (row["companyname"].ToString().CompareTo("companylogo") != 0)
{
string profile_time = row["profile_timestamp"].ToString();
if (!string.IsNullOrEmpty(profile_time))
{
CSTimeZone time = new CSTimeZone();
profile_time = time.FromUnix(Convert.ToDouble(profile_time)).ToShortDateString()+" "+
time.FromUnix(Convert.ToDouble(profile_time)).ToLongTimeString();
}
string lastUseNetTime = row["last_used_networktime"].ToString();
if (!string.IsNullOrEmpty(lastUseNetTime))
{
CSTimeZone time = new CSTimeZone();
double sec = Convert.ToDouble(lastUseNetTime) * 60;
lastUseNetTime = time.FromUnix(Convert.ToDouble(sec)).ToShortDateString() + " " +
time.FromUnix(Convert.ToDouble(sec)).ToLongTimeString();
}
string lastOnlineTime = row["lastonline_timestamp"].ToString();
if (!string.IsNullOrEmpty(lastOnlineTime))
{
CSTimeZone time = new CSTimeZone();
lastOnlineTime = time.FromUnix(Convert.ToDouble(lastOnlineTime)).ToShortDateString() + " " +
time.FromUnix(Convert.ToDouble(lastOnlineTime)).ToLongTimeString();
}
lst.Add(new CONTACT_INFO()
{
gender=Convert.ToInt32(row["gender"].ToString()),
timezone=row["timezone"].ToString(),
fullName = row["fullname"].ToString(),
profile_timestamp = profile_time,
last_used_networktime = lastUseNetTime,
lastonline_timestamp = lastOnlineTime,
birthday = string.IsNullOrEmpty(sDate) ? "" : datetime
});
}
}
return lst;
}
The function FromUnix is written as
public DateTime FromUnix(double seconds)
{
DateTime datetime = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc).ToLocalTime();
return datetime.AddSeconds(seconds);
}
I am pretty sure this is a parsing problem
The following line would throw exceptions if the value of sDate is not in the defined format of yyyyMMdd
datetime = DateTime.ParseExact(sDate, format, provider).ToShortDateString();
I would first use TryParseExact instead of a simple Parse since you do not seem to be using try/catch clauses. It might be a good idea to use the debugger to see exactly where your program is failing.
Other example of potential failures in your code are
double sec = Convert.ToDouble(lastUseNetTime) * 60;
Use double.tryParse
Convert.ToInt32(row["gender"].ToString()
If gender turns out not to be a number another exception will be thrown
etc...

Categories