mssql datetimeoffset not regonized - c#

I'm getting Values from my database, save them in a List, change Values and Update the database.
No error message shows up.
The Values in the database are saved like this -> "2014-07-11 06:35:09.343 +00:00"
string dateformat = "dd.MM.yyyy HH:mm:ss zzz";
foreach (var value in vals)
{
dt = DateTimeOffset.ParseExact(value[0].ToString(),dateformat, CultureInfo.InvariantCulture);
String sqlString = "UPDATE SampleValues " +
"SET Value = #VALUE " +
"WHERE ID = #ID AND SampleTime = #DATETIME";
var sqlCommand = new SqlCommand(sqlString, connection);
sqlCommand.Parameters.Add("#ID", System.Data.SqlDbType.UniqueIdentifier).Value = ID;
sqlCommand.Parameters.Add("#DATETIME", System.Data.SqlDbType.DateTimeOffset).Value = dt;
sqlCommand.Parameters.Add("#VALUE", System.Data.SqlDbType.NVarChar, int.MaxValue).Value = value[1];
var excuter = sqlCommand.ExecuteNonQuery();
}
Nothing in the database gets updated.
When the value is parsed dt = {11.07.2014 06:35:09 +00:00}
When I change my string dateformat to "yyyy-MM-dd HH:mm:ss zzz"
I get an error. String was not recognized as a valid DateTime.
I also tried CAST(#DATETIME as datetimeoffset(7)) nothing happened.
The Datetype in the Datebase is datetimeoffset(3)
Any ideas?

According to the samples you provided, you have values in the database with millisecond precision, but you are parsing values from strings with only whole second precision.
2014-07-11 06:35:09.343 +00:00 != 2014-07-11 06:35:09 +00:00
These can't be equal because one side is 343 milliseconds difference from the other.
In general, it's not a great idea to match timestamps with such fine precision using exact equality. Instead, consider a range match. If you know you have values to the whole second, you could match values >= the start of the whole second and < the start of the next whole second.
Then again - it would appear you already have an ID in your where clause. If that's indeed a unique identifier, then there's no need to match on the timestamp at all.

Related

Comparing two datetimes to check for a clash but seems to be confusing MM/DD with DD/MM C# ASP.NET

I am trying to check my database for a clash, I am reading up using a reader and calling the value down. My value is 10/12/2018 15:00:00 So I have stored this as #moduleStartTime
My next query checks the database using the above datetime and if it is between any other dates entered.
The issue I am encountering is that there are no clashes, so this shouldn't flag up that there are. I have found that the clash it is returning has a datetime of 12/10/2018 15:00:00
It appears as though somewhere in the search, it is reversing DD/MM
Here is my code
//Reading to get all modules student is enrolled on
string checkclash = "SELECT * FROM cModuleTimes INNER JOIN cStudentModule ON cModuleTimes.ModuleID = cStudentModule.ModuleID WHERE cStudentModule.StudentID=#studentid AND #date BETWEEN[StartTime] AND[EndTime] AND ModTimeID <> #modtimeid";
SqlCommand myCommandclash = new SqlCommand(checkclash, myConnectionclash);
myCommandclash.Parameters.AddWithValue("#date", moduleStartTime);
myCommandclash.Parameters.AddWithValue("#courseid", courseid);
myCommandclash.Parameters.AddWithValue("#studentid", user);
myCommandclash.Parameters.AddWithValue("#modtimeid", moduletocompareid);
//create a sqldatareader object that asks for dats from a table
SqlDataReader rdrreadclash = myCommandclash.ExecuteReader();
if (rdrreadclash.HasRows)
{
while (rdrreadclash.Read())
{
string getname = rdrreadclash["ModTimeID"].ToString();
string gettime = rdrreadclash["StartTime"].ToString();
Warning.Text = "There appears to be a clash with this event..<br><br> <br> <b>Would you like to continue?</b> <br><br>";
}
ViewClash.Visible = true;
YesContinue.Visible = true;
FinishMod.Visible = false;
}
myConnectionclash.Close();
I have tried a couple of conversions but am receiving an issue with string not recognised as a DateTime.
If anyone has any answers on how I would prevent this clash from appearing, I would be very grateful.
Thank you.
moduleDateTime is currently a string, you need to parse it in to a DateTime object where the parsing operation has the proper MM/DD order you want.
DateTime dateAsDateTime = DateTime.ParseExact(moduleStartTime, "dd/MM/yyyy HH:mm:ss", null);
myCommandclash.Parameters.AddWithValue("#date", dateAsDateTime);
You then must format the returned date time back to a string in the format you want.
string gettime = ((DateTime)rdrreadclash["StartTime"]).ToString("dd/MM/yyyy HH:mm:ss ");

DateTime timestamp has period instead of colon

I have a Datatable with two DateTime columns: date_from and date_to.
string dateFrom = row["date_from"].ToString();
string dateTo = row["date_to"].ToString();
When this code is run in a customer environment, it returns dates in the following format:
"2016-01-01 00.00.00"
"2016-02-01 00.00.00"
This string is then inserted into SQL:
SELECT * FROM my_table
WHERE UPPER(status) = 'N'
AND trans_date >= {ts '1900-01-01 00.00.00' }
AND trans_date <= {ts '1900-01-01 00.00.00' }
When this SQL is executed it returns the error "Conversion failed when converting date and/or time from character string."
So a quick fix for this is to run a string.Replace() where I replace period with colon:
dateFrom = dateFrom.Replace(".", ":");
However, my question is rather why the date is returned with periods as the timestamp separator and not colons?
I have created this test on my local machine, but unfortunately for this scenario it returns a correct representation of the DateTime string:
DataTable table = new DataTable();
table.Columns.Add("date", typeof(DateTime));
DataRow row = table.NewRow();
row["date"] = DateTime.Now;
table.Rows.Add(row);
DateTime date = DateTime.Parse(table.Rows[0]["date"].ToString());
My guess so far would be that it has something to do with the customers culture, but I would really appreciate input from someone who has experience with this so I can give feedback to the customer about why this happened in the first place.
It might just be a coincidence, but it is worth mentioning that this only happens for users with Windows 10. Everyone using Windows 7 does not get this error.
As you says, this is about customer's culture. Specifically CultureInfo.DateTimeFormat.
This property returns a DateTimeFormatInfo object that defines the culturally appropriate format of displaying dates and times.
This object have a property TimeSeparator that gets or sets the string that separates the components of time, that is, the hour, minutes, and seconds.
You can setup this property to specify a separator like :.
However a better approach is passing a specific culture to ToString() method like CultureInfo.InvariantCulture (culture-independent):
string dateFrom = ((DateTime)row["date_from"]).ToString(CultureInfo.InvariantCulture);
string dateTo = ((DateTime)row["date_to"]).ToString(CultureInfo.InvariantCulture);
or use your own format:
string dateFrom = ((DateTime)row["date_from"]).ToString("yyyy-MM-dd HH:mm:ss");
string dateTo = ((DateTime)row["date_to"]).ToString("yyyy-MM-dd HH:mm:ss");

Format string into Time from datatable C#

I am creating a datatable from excel import and bulkcopying it to database, I need to put the Scheduled Start as start time into database as time hh:mm:ss but it keeps going into database as 30/12/1899 10:30:00, all I want is the 10:30:00 to go into database. How can I do this?
I have tried converting to DateTime and then formating but keeps saying it is not a valid DateTime.
using (OleDbDataAdapter oda = new OleDbDataAdapter("SELECT * FROM [" + sheet1 + "]", excel_con))
{
oda.Fill(dtExcelData);
}
excel_con.Close();
if (dtExcelData.Rows.Count > 0)
{
foreach (DataRow rw in dtExcelData.Rows)
{
//Creates StaffID
rw["StaffID"] = "00" + rw["Host Key of Staff"].ToString();
//Creates Start Time
rw["Scheduled Start as start time"] = rw["Scheduled Start as start time"].ToString("hh-mm");
}
// Response.Write(strConcate);
}
You can't have a DateTime without both a date and a time. If you try to omit the time, it'll probably default to midnight. If you omit the date, it apparently defaults to Dec 30, 1899 in the database.
If you don't see a column type for only Time, you'll have to either:
use a string or text type for that column and store the time as a string like you're currently attempting to do, or
keep the column as a Date/Time and don't worry about the date portion that's stored
I'd do it the second way, and then use a format string like .ToString("hh-mm") so that the user only sees the portion you want them to see. They'll never realize you've stored a date. This way, you're not storing the time as a string and then needing to manipulate it back into the correct format later on when you inevitably try to do some calculation with it.
but keeps saying it is not a valid DateTime
i think your field in db is DateTime type.this is for what you are doing in your foreach.your are converting it to a 'string' and now you try to save a string .change the db field from DateTime to nchar or nvarchar and store time in string format the way you want.
now every time you get data from db
I believe your problem is with this line
rw["Scheduled Start as start time"] = rw["Scheduled Start as start time"].ToString("hh-mm");
If rw["Scheduled Start as start time"] is a DateTime as I suspect, then you cannot then assign a string to it...its a DateTime, not a string. It must have a full date and time.
You could change the type to be a string and store the datetime elsewhere or store the string elsewhere.
try this one
String.Format("{0:t}", dt); // "4:05 PM" ShortTime
String.Format("{0:d}", dt); // "3/9/2008" ShortDate

MS Access stores the incorrect DateTime.MinValue?

I have a problem when storing DateTime.MinValue into a field (as Date/Time type) in MS Access. Printing this out prior to storing in database, I get "1/1/0001 12:00:00 AM", which is expected. However after retrieving the same value out of the database I get "1/1/2001 12:00:00 AM" (note the year 2001 instead of year 1).
This is obviously incorrect! Anyone have any ideas?
Note, that I am using DateTime.MinValue as someone suggested as invalid date/time, because DateTime cannot be null value.
The code to write to database is:
public static bool StartNow(string profileID, string startNotes)
{
DateTime now = DateTime.Now;
OleDbCommand cmd = new OleDbCommand("SELECT * FROM shifts WHERE profile_id=#profile_id AND closed=false;");
cmd.Parameters.AddWithValue("#profile_id", profileID);
// A new shift should NEVER be started with another open shift.
OleDbDataReader reader = Database.Read(cmd);
if (reader.HasRows)
return false;
cmd = new OleDbCommand("INSERT INTO shifts(profile_id, start, stop, start_log, stop_log, start_notes, stop_notes, closed) VALUES(#profile_id, #start, #stop, #start_log, #stop_log, #start_notes, #stop_notes, #closed);");
cmd.Parameters.AddWithValue("#profile_id", profileID);
cmd.Parameters.AddWithValue("#start", RoundUp(now, 30).ToString());
cmd.Parameters.AddWithValue("#stop", DateTime.MinValue);
cmd.Parameters.AddWithValue("#start_log", now.ToString());
cmd.Parameters.AddWithValue("#stop_log", DateTime.MinValue);
cmd.Parameters.AddWithValue("#start_notes", startNotes);
cmd.Parameters.AddWithValue("#stop_notes", "");
cmd.Parameters.AddWithValue("#closed", false);
// TODO: need to set default values for stop, stop_log and stop_notes
return Database.Write(cmd) == 1 ? true : false;
}
This is the code to read back in the date and time:
public static List<ShiftView> TodaysShifts()
{
List<ShiftView> shifts = new List<ShiftView>();
// INFO: Not intended to retrieve a lot of records as there is no caching....
OleDbCommand cmd = new OleDbCommand("SELECT profiles.profile_id, profiles.full_name, shifts.start, shifts.stop, shifts.start_log, shifts.stop_log, shifts.start_notes, shifts.stop_notes FROM shifts, profiles WHERE (shifts.start>=#today) AND (shifts.profile_id=profiles.profile_id);");
cmd.Parameters.AddWithValue("#today", DateTime.Today);
OleDbDataReader reader = Database.Read(cmd);
while(reader.Read())
{
shifts.Add(new ShiftView(
reader.GetString(reader.GetOrdinal("profile_id")),
reader.GetString(reader.GetOrdinal("full_name")),
reader.GetDateTime(reader.GetOrdinal("start")),
reader.GetDateTime(reader.GetOrdinal("stop")),
reader.GetDateTime(reader.GetOrdinal("start_log")),
reader.GetDateTime(reader.GetOrdinal("stop_log")),
reader.GetString(reader.GetOrdinal("start_notes")),
reader.GetString(reader.GetOrdinal("stop_notes"))
));
}
return shifts;
}
In Microsoft Access "Valid date values range from -657,434 (January 1, 100 A.D.) to 2,958,465 (December 31, 9999 A.D.). Valid time values range from .0 to .9999, or 23:59:59." (ref: here.) So, you cannot store "1/1/0001 12:00:00 AM" in an Access Date/Time field.
As suggested by Jon Skeet :-
Basically, don't use DateTime.MinValue to represent a missing value.
You can't use DateTime.MinValue in a SQL Server DateTime field, as SQL
Server has a minimum value of the start of 1753.
Instead, make your property a Nullable (aka
DateTime?), and set it to null when you don't have a value. Also make
sure your database field is nullable. Then you just need to make sure
that that null ends up as a NULL value in the database. Exactly how
you do that will depend on your data access.
and you can give a try to use SqlDateTime.MinValue instead of DateTime.MinVaue

Error on & after 13th of Every Month; When Converting Date and/or Time from character string

The code below Works ok; from 01st to 12th of every month; However as soon as I click on 13th or greater date I Get this error
Conversion failed when converting date and/or time from character string.
This my Code
DateTime dt = Convert.ToDateTime(Calendar1.SelectedDate.ToString("yyyy-MM-dd"));
myConnection.Open();
string cmdStr1 = "SELECT COUNT(*) FROM Payment WHERE PaymentDate = '" + dt + "'";
SqlCommand PIDexist1 = new SqlCommand(cmdStr1, myConnection);
int temp1 = Convert.ToInt32(PIDexist1.ExecuteScalar().ToString());
myConnection.Close();
Thank for your Help
This is How Date is saved in my Database 2012-01-13
No, never bind dates like that. Let the .NET data provider handle this for you - there are just way too many pitfalls with locales on the App and Sql Server for you to use strings as dates.
myConnection.Open();
string cmdStr1 = "SELECT COUNT(*) FROM Payment WHERE PaymentDate = #dt'";
SqlCommand PIDexist1 = new SqlCommand(cmdStr1, myConnection);
SqlParameter parameter = PIDexist1.Parameters.Add("#dt", System.Data.SqlDbType.DateTime);
parameter.Value = dt;
...
Because it's trying to convert 13 as the month.
Try using DateTime.Parse("...", [Culture]) and specifying the appropriate culture.
Most likely you're encountering a DD-MM-YY vs MM-DD-YY situation. It's too much of a coincidence that it works until the 12th day when there are 12 months. Try to be more explicit in your use of dates; perhaps use the three letter month code.
There is no need to convert the date .ToString(). Simply use the SelectedDate DateTime value as named parameter to the SqlCommand query. If you need the day only, use the DateTime.Date property

Categories

Resources