EF core 3 problem by string to npgsqlTime - c#

Hey guys im using Npgsql and need to pass parameters to my PostgreSQL stored procedure
my stored procedure expecting Date for my first two parameters:
SELECT wpv.avail_pro_failedbattry_error_powerconv(
<date>,
<date>,
<character varying>,
<character varying>,
<character varying>
);
so i need to pass date parameters :
NpgsqlDateTime DateFrom = NpgsqlDateTime.Parse(dtFrom);
NpgsqlDateTime DateTo = NpgsqlDateTime.Parse(dtTo);
NpgsqlParameter p0 = new NpgsqlParameter("#drfrom", dtFrom);
NpgsqlParameter p1 = new NpgsqlParameter("#dtto",dtTo);
NpgsqlParameter p2 = new NpgsqlParameter("#regionalmanager", regionalManager);
NpgsqlParameter p3 = new NpgsqlParameter("#serviceunder", service_under);
NpgsqlParameter p4 = new NpgsqlParameter("#supervisor", supervisor);
var x = _db.dataInGlance.FromSqlRaw(#"SELECT * from wpv.avail_pro_failedbattry_error_powerconv(#drfrom,#dtto,#regionalmanager,#serviceunder,#supervisor)
res (o_availability double precision, o_production double precision,o_numberofturbines integer, o_errors_disabled integer,o_failed_battery integer,o_power integer,o_crew_present text)",p0,p1,p2,p3,p4
).ToList();
dtfrom and dtto are string date format which is:
dtFrom="2020/07/03"
dtTo="2020/07/07"
but it gives me an error on the line
NpgsqlDateTime DateFrom = NpgsqlDateTime.Parse(dtFrom);
that the format is not correct!any help?

Looking at the source:
NpgsqlDateTime
which calls NpgsqlDate
along with Timespan.Parse() which seems mandatory.
Since you are not using a time, you could use NpgsqlDate.Parse() instead.
The source seems to be expecting the following format for date parsing: yyyy-MM-dd
So if you meant the 3rd of July
dtFrom="2020-07-03"
but if you meant the 7th of March
dtFrom="2020-03-07"
Source code:
try {
var idx = str.IndexOf('-');
if (idx == -1) {
throw new FormatException();
}
var year = int.Parse(str.Substring(0, idx));
var idxLast = idx + 1;
if ((idx = str.IndexOf('-', idxLast)) == -1) {
throw new FormatException();
}
var month = int.Parse(str.Substring(idxLast, idx - idxLast));
idxLast = idx + 1;
if ((idx = str.IndexOf(' ', idxLast)) == -1) {
idx = str.Length;
}
var day = int.Parse(str.Substring(idxLast, idx - idxLast));
if (str.Contains("BC")) {
year = -year;
}
return new NpgsqlDate(year, month, day);
} catch (OverflowException) {
throw;
} catch (Exception) {
throw new FormatException();
}
Additionally if NpgsqlDate.Parse is not accepted, you could use NpgsqlDateTime.Parse with the time part set to zero.
NpgsqlDateTime.Parse("2020-07-03 00:00")

Related

How to find the closest date in c#?

I am trying to display the values of ApmaksasApmers (which is a Reference Value) which are closest to DateToCompare in comparison to GivenDate
For example:
DateToCompare =01.01.2022 and 01.01.2021
and GivenDate = 01.03.2022
I am trying to get the values which come from date 01.01.2022
Here is my code:
vm.ApmaksasApmērs.LookupSource = _nolasītMaksājumusQuery.Nolasīt()
.OrderBy(x => x.DateToCompare.Value > vm.GivenDate.Value ? vm.GivenDate.Value - x.DateToCompare.Value : x.DateToCompare.Value - vm.GivenDate.Value)
.Select(x => new KeyValuePair<Guid?, string>(x.Id, x.ApmaksasApmērs +" (" + x.PersonasLīdzmaksājumsProcentos + "%)".ToString())) ;
Here I am geting an error of Name:[ApmaksasApmērs],Type:[ReferenceValue],Message:[Don't currently support idents of type TimeSpan]
Is there a better way of doing this? Thanks in advance
Hi if DateToCompare is an array then we compare the absolute value of difference between each el with the given date and when the value is lowest that's the closest date
Here is how
//adding some data
DateTime[] DateToCompare = {
new DateTime(2001, 05,05),
new DateTime(2022,01,01),
new DateTime(2021,01,01)
};
DateTime GivenDate = new DateTime(2022, 05, 02);
//Get the absolute value of diference between first el and given date
TimeSpan span = abs(DateToCompare[0] - GivenDate);
DateTime closestDate = DateToCompare[0];
//new we check each el if the dif is lower
for (int i = 1; i < DateToCompare.Length; i++)
{
if (abs(GivenDate - DateToCompare[i]) < span)
{
span = abs(GivenDate - DateToCompare[i]);
closestDate = DateToCompare[i];
}
}
//get absolute value
TimeSpan abs(TimeSpan t)
{
return (t.TotalSeconds >= 0) ? t : -t;
}
Console.WriteLine(closestDate.ToShortDateString());
Here is what I did :
Create a list for all of the elements:
var saraksts = _nolasītMaksājumusQuery.Nolasīt().Where(x => x.DateToCompare <= vm.GivenDate).ToList();
Find the max value from the list:
var maxDate = list.Max(x=>x.DateToCompare)
Find all of the elements where MaxDate == DateToCompare:
vm.ApmaksasApmērs.LookupSource = list.Where(x => x.DateToCompare== maxDate).Select(x => new KeyValuePair<Guid?, string>(x.Id, x.ApmaksasApmērs +" (" + x.PersonasLīdzmaksājumsProcentos + "%)".ToString()));

C# WinForm error import from excel to database

Hei. I need to understand why I receive an error like that :
C# windows form import from excel error
I can't separe the year from string (year time). Or, can I renounce at split and import directly the string as "date"? Sorry, I'm too beginner in c#, but I need this help, is a task for me.
Here is my code :
for (int i = 0; i < dvColumns.Count; i++)
{
string columnName = string.Empty;
string columnField = string.Empty;
if ((dvColumns[i]["Header"] != null) && (!Convert.IsDBNull(dvColumns[i]["Header"])))
{
columnName = dvColumns[i]["Header"].ToString();
}
if ((dvColumns[i]["Field"] != null) && (!Convert.IsDBNull(dvColumns[i]["Field"])))
{
columnField = dvColumns[i]["Field"].ToString();
}
rangeObject = cellsObject.GetType().InvokeMember("Item", BindingFlags.GetProperty, null, cellsObject, new object[] { row, i + 1 });
object valueObject = rangeObject.GetType().InvokeMember("Value", BindingFlags.GetProperty, null, rangeObject, null);
if (columnName == "FiscalCode" && columnField == "PartnerId")
{
string fiscalCode = Erp.Core.Utils.GetStringFromObject(valueObject);
partnerId = p.GetPartnerIdByFiscalCode(fiscalCode);
eventRow["PartnerId"] = partnerId;
}
else if (columnField == "StartDate" || columnField == "EndDate")
{
string date = Erp.Core.Utils.GetStringFromObject(valueObject);
DateTime columnDate = DateTime.Now;
string[] dateComponents = null;
int year = 0;
int month = 0;
int day = 0;
if (date.Contains("."))
{
dateComponents = date.Split('.');
}
if (date.Contains("/"))
{
dateComponents = date.Split('/');
}
if (date.Contains(":"))
{
dateComponents = date.Split(':');
}
if (dateComponents.Length > 1)
{
string s = dateComponents[0];
day = Erp.Core.Utils.GetIntFromObject(s);
s = dateComponents[1];
month = Erp.Core.Utils.GetIntFromObject(s);
s = dateComponents[2];
year = Erp.Core.Utils.GetIntFromObject(s);
columnDate = new DateTime(year, month, day, 9, 0, 0);
}
eventRow[columnField] = columnDate;
}
else if (columnField != "PartnerId" && columnField != "StartDate" && columnField != "EndDate")
{
eventRow[columnField] = valueObject;
}
}
I tried to keep in excel same format as in database table : 'yyyy/mm/dd hh:mm:ss.000'.
The line date = Erp.Core.Utils.GetStringFromObject(valueObject); get my date from first excel cell.
ds.Tables["Events"] is all time empty.
I know this line eventRow[columnField] = date; must add the dates in DB, really? After split, day is ok (receive an int by s[0]), month is ok (receive an int by s[1], but s[2] for year is something like 2017 19:06:22 .... year plus time). I tried to split again by space, but without results, to keep the number (2017) in year variable.
Best way is to use DateTime.ParseExact method. In your case, if original format is 'yyyy/mm/dd hh:mm:ss.000', you can convert it to DateTime like this:
//string date = Erp.Core.Utils.GetStringFromObject(valueObject);
string date = "2017/08/15 10:20:30.000";
DateTime columnDate = DateTime.ParseExact(date, "yyyy/MM/dd HH:mm:ss.fff", CultureInfo.InvariantCulture);
This way you can skip parsing excel string.
In your example, usage will be like this:
//...snip...
else if (columnField == "StartDate" || columnField == "EndDate")
{
string date = Erp.Core.Utils.GetStringFromObject(valueObject);
//parsing date string
DateTime columnDate = DateTime.ParseExact(date, "yyyy/MM/dd HH:mm:ss.fff", CultureInfo.InvariantCulture);
eventRow[columnField] = columnDate;
}
else if (columnField != "PartnerId" && columnField != "StartDate" && columnField != "EndDate")
{
eventRow[columnField] = valueObject;
}
if hours are in 12-hour format, use lowercase hh, like this "yyyy/MM/dd hh:mm:ss.fff"

Sql procedure slow using 2 dates d1 and d2

I have 2 problems, first when i use 2 defined dates my request works but when i try to do this with two var which came from my C# code it doesnt work it's very slow. And then if i use a limit with those 2 vars it works untill 294 but at 295 it doesnt work i do not know why. There is my code.
CREATE OR REPLACE FUNCTION prc_get_list_resa(d1 date, d2 date, p_id_resa integer, p_state character, p_id_clt integer, p_id_chauff integer, p_id_conv integer, p_id_fact integer, p_id_org integer)
RETURNS refcursor AS
$BODY$
DECLARE
ref refcursor;
BEGIN
OPEN ref FOR
SELECT *
FROM db_reservations res
LEFT JOIN db_clients clt ON res.id_clt_resa = clt.id_clt
LEFT JOIN db_organisations org ON res.id_org_resa = org.id_org
LEFT JOIN db_chauffeurs chauff ON res.id_chauff_resa = chauff.id_chauff
LEFT JOIN db_vehicules vehic ON res.id_vehic_resa = vehic.id_vehic
LEFT JOIN db_type_transport ttransp ON res.id_type_transp_resa = ttransp.id_type_transp
WHERE res.date_dep_resa >= (select distinct d1 from db_reservations) and res.date_dep_resa < (select distinct d2 from db_reservations)
and ((res.id_resa = p_id_resa) or (p_id_resa = 0))
and ((res.id_org_resa = p_id_org) or (p_id_org = 0))
and ((res.id_chauff_resa = p_id_chauff) or (p_id_chauff = 0))
and ((res.id_clt_resa = p_id_clt) or (p_id_clt = 0))
and ((res.id_conv_resa = p_id_conv) or (p_id_conv = 0))
and ((res.id_fact_resa = p_id_fact) or (p_id_fact = 0))
and ((res.etat_resa = p_state) or (p_state = ''))
order by id_org_resa,id_clt_resa, date_dep_resa,type_trajet asc limit 1000;
RETURN ref ;
END;
$BODY$
LANGUAGE plpgsql VOLATILE
COST 100;
ALTER FUNCTION prc_get_list_resa(date, date, integer, character, integer, integer, integer, integer, integer)
OWNER TO postgres;
The c# code :
public static List<Reservation> ListReservations(string param, int p_id_resa, string p_state, int p_id_clt, int p_id_chauff, int p_id_conv, string p_deb_period, string p_fin_period, int p_id_fact, int p_id_pass, int p_id_org)
{
string d1, d2;
DateTime baseDate = DateTime.Today;
var today = baseDate;
var yesterday = baseDate.AddDays(-1);
var thisWeekStart = baseDate.AddDays(-(int)baseDate.DayOfWeek);
var thisWeekEnd = thisWeekStart.AddDays(7).AddSeconds(-1);
var lastWeekStart = thisWeekStart.AddDays(-7);
var lastWeekEnd = thisWeekStart.AddSeconds(-1);
var thisMonthStart = baseDate.AddDays(1 - baseDate.Day);
var thisMonthEnd = thisMonthStart.AddMonths(1).AddSeconds(-1);
var lastMonthStart = thisMonthStart.AddMonths(-1);
var lastMonthEnd = thisMonthStart.AddSeconds(-1);
if (param == "lastweek")
{
d1 = thisWeekStart.ToString("dd-MM-yyyy");
d2 = thisWeekEnd.ToString("dd-MM-yyyy");
}
else if (param == "lastmonth")
{
d1 = thisMonthStart.ToString("dd-MM-yyyy");
d2 = thisMonthEnd.ToString("dd-MM-yyyy");
}
else if (param == "today")
{
d1 = DateTime.Today.ToString("dd-MM-yyyy");
d2 = DateTime.Today.ToString("dd-MM-yyyy");
}
else if (param == "all")
{
d1 = "01-01-1900";
d2 = "01-01-2100";
}
else
{
d1 = p_deb_period;
d2 = p_fin_period;
}
NpgsqlDataReader dr = null;
List<Reservation> lst_reservation = new List<Reservation>();
ApplicationConfig db = new ApplicationConfig();
string cnx = db.getConnectionStringFromXML();
NpgsqlConnection npgsqlcnx = new NpgsqlConnection(cnx);
npgsqlcnx.Open();
NpgsqlTransaction tran = npgsqlcnx.BeginTransaction();
// NpgsqlCommand command = new NpgsqlCommand("prc_get_reservations", npgsqlcnx);
NpgsqlCommand command = new NpgsqlCommand("prc_get_list_resa", npgsqlcnx);
command.CommandType = CommandType.StoredProcedure;
if ((d1 != "") && (d1 != null))
{
command.Parameters.AddWithValue("#d1", DateTime.Parse(d1));
}
else
{
command.Parameters.AddWithValue("#d1", DateTime.Parse("01/01/1900"));
}
if ((d2 != "") && (d2 != null))
{
command.Parameters.AddWithValue("#d2", DateTime.Parse(d2));
}
else
{
command.Parameters.AddWithValue("#d2", DateTime.Parse("01/01/2100"));
}
command.Parameters.AddWithValue("#p_id_resa", p_id_resa);
command.Parameters.AddWithValue("#p_state", p_state);
command.Parameters.AddWithValue("#p_id_clt", p_id_clt);
command.Parameters.AddWithValue("#p_id_chauff", p_id_chauff);
command.Parameters.AddWithValue("#p_id_conv", p_id_conv);
command.Parameters.AddWithValue("#p_id_fact", p_id_fact);
command.Parameters.AddWithValue("#p_id_org", p_id_org);
dr = command.ExecuteReader();
int t = dr.FieldCount;
lst_reservation = Reservations(dr);
// lst_reservation = Reservations(dr);
npgsqlcnx.Close();
return lst_reservation;
}
d1 and d2 must be declared as DateTime variables - don't store dates in strings. Especially when passing those dates to a database that expects a date rather than a string.
In all likelihood, you are passing a string to the database and the database is interpreting that string differently (e.g. is 1/2/2017 1st Feb or 2nd Jan?). By passing only dates to the database there is no ambiguity.
Thus instead of code like:
d1 = DateTime.Today.ToString("dd-MM-yyyy");
you will use code like:
d1 = DateTime.Today;
Also change this line:
WHERE res.date_dep_resa >= (select distinct d1 from db_reservations) and res.date_dep_resa < (select distinct d2 from db_reservations)
to:
WHERE res.date_dep_resa >= d1 and res.date_dep_resa < d2

Need to correct time span string format

I have a time span string as
1.21:00:00
it means 45 hours and i need it as
45:00:00
and i use following method from
Need only HH:MM:SS in time span string
it works perfectly for this above problem but when i change the string as
1.21:30:00
then mentioned code return me one hour more than actual time. in this case it return me 46:29:00 but actual that i need is 45:29:00.
I am using c#
EDIT
public Tuple<string,string> Calculate_Hours(DateTime strt, DateTime end)
{
TimeSpan wrkhrs = new TimeSpan(0, 0, 0);
TimeSpan exthrs=new TimeSpan(0,0,0);
cmd = new SqlCommand("select * from vw_Rept_Attend where UserID ='"+Convert.ToInt32 (cmbEmp.SelectedValue)+"' and convert(date,AtnDate) between '"+strt.Date+"' and '"+end.Date+"'",conn);
conn.Open();
dr = cmd.ExecuteReader();
while (dr.Read())
{
if (dr["WorkHrs"].ToString().Length>0)
wrkhrs=wrkhrs.Add(Convert.ToDateTime(dr["WorkHrs"].ToString()).TimeOfDay);
// exthrs = exthrs.Add(Convert.ToDateTime(dr["ExtraHrs"].ToString()).TimeOfDay);
if (!dr["ExtraHrs"].ToString().Contains("-") && dr["ExtraHrs"].ToString().Length > 0)
{
exthrs = exthrs.Add(Convert.ToDateTime(dr["ExtraHrs"].ToString()).TimeOfDay);
}
else if (dr["ExtraHrs"].ToString().Contains("-") && dr["ExtraHrs"].ToString().Length > 0)
{
//int index = dr["ExtraHrs"].ToString().LastIndexOf('-');
//string rhs = dr["ExtraHrs"].ToString().Substring(index + 1);
string ext = dr["ExtraHrs"].ToString().Substring(dr["ExtraHrs"].ToString().LastIndexOf("-") +1);
//TimeSpan test = Convert.ToDateTime(dr["ExtraHrs"].ToString()).TimeOfDay.Negate();
exthrs = exthrs.Subtract(Convert.ToDateTime(ext).TimeOfDay);
}
}
conn.Close();
dr.Close();
// string tst = exthrs.ToString().Substring(exthrs.ToString().LastIndexOf("-") + 1);
// wrkhrs.ToString();
// exthrs.ToString();
var val1 = TimeSpan.Parse(wrkhrs.ToString());
string val3= string.Format("{0}:{1:mm}:{1:ss}", Math.Floor(TimeSpan.Parse(wrkhrs.ToString()).TotalHours), TimeSpan.Parse(wrkhrs.ToString()));
var val2=TimeSpan.Parse(exthrs.ToString());
string val4=string.Format("{0}:{1:mm}:{1:ss}", Math.Floor(TimeSpan.Parse(exthrs.ToString()).TotalHours), TimeSpan.Parse(exthrs.ToString()));
return new Tuple<string, string>(string.Format("{0}:{1:mm}:{1:ss}", Math.Floor(TimeSpan.Parse(wrkhrs.ToString()).TotalHours), TimeSpan.Parse(wrkhrs.ToString())), string.Format("{0}:{1:mm}:{1:ss}", Math.Floor(TimeSpan.Parse(exthrs.ToString()).TotalHours), TimeSpan.Parse(exthrs.ToString())));
// MessageBox.Show(wrkhrs.ToString()+exthrs.ToString());
}
this is what i did yet.
I'm not sure if i got it since your expected result is strange. You add 30 minutes but expect 29 minutes in the result string? If i ignore that this should work:
var ts = TimeSpan.Parse("1.21:30:00");
string result = string.Format("{0:00}:{1:00}:{2:00}", (int)ts.TotalHours, ts.Minutes, ts.Seconds);
Returns: 45:30:00
You can use Math.Abs if you want to handle negative timespans:
String.Format("{0:00}:{1:00}:{2:00}", (int)ts.TotalHours, Math.Abs(ts.Minutes), Math.Abs(ts.Seconds));

insert date of birth into sql server

I made a JavaScript for date of birth, when debugging you choose your day of birth in three drop down boxes. One for days one for months and one for years. I'm working on C# asp.net. The problem is when i click on test(which is submit or confirm) the date is not taken to the database table. It fills empty! Any help would be appreciated..
here's the code:
DateOfBirth.js:
function date_populate(dayfield, monthfield, yearfield)
{
var today = new Date();
var dayfield = document.getElementById(dayfield);
var monthfield = document.getElementById(monthfield);
var yearfield = document.getElementById(yearfield);
for (var i = 0; i < 32; i++)
{
dayfield.options[i] = new Option(i , i + 1)
dayfield.options[today.getDate()] = new Option(today.getDate(), today.getDate(), true, true)
}
for (var m = 0; m < 12; m++)
{
monthfield.options[m] = new Option(monthtext[m], monthtext[m])
monthfield.options[today.getMonth()] = new Option(monthtext[today.getMonth()], monthtext[today.getMonth()], true, true)
}
var thisyear = today.getFullYear()
for (var y = 0; y < 100; y++)
{
yearfield.options[y] = new Option(thisyear, thisyear)
thisyear -= 1
}
yearfield.options[0] = new Option(today.getFullYear(), today.getFullYear(), true, true)
}
Form.asp.cs
protected void Button1_Click(object sender, EventArgs e)
{
String D, M, Y, Full;
D = Day.Value.ToString();
M = Month.Value.ToString();
Y = Year.Value.ToString();
Full = D + "/" + M + "/" + Y;
}
Don't construct dates as strings. Pass them as dates. For example:
DateTime dob = new DateTime(Year.Value, Month.Value, Day.Value);
...
cmd.Parameters.AddWithValue("dob", dob);
where the cmd.CommandText involves #dob when you want to refer to the date of birth.
Format the date 'yyyy-mm-dd' and it will insert.
Are you using a stored procedure?
Change your SP parameter from SqlDbType.NVarChar to SqlDbType.DateTime and then pass the date as a DateTime object to the parameter. You dont need to worry about conversions anymore.
DateTime dateofbirth = new DateTime(Convert.ToInt32(yearfield.SelectedValue),Convert.ToInt32(monthfield.SelectedValue), Convert.ToInt32(dayfield.SelectedValue));
param[0] = new SqlParameter("#DateOfBirth", SqlDbType.DateTime);
param[0].Value = dateofbirth;

Categories