DateTime timestamp has period instead of colon - c#

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");

Related

How to convert this date 2017-07-09T17:50:21.000-0500 | C#

when i run the below code,
string dt = "2017-07-09T17:50:21.000-0500";
DateTime date = Convert.ToDateTime(dt);
it gives me output as
7/10/2017 4:20:21 AM
where as i want my output to be
2017-07-09 17:50
update
the code #alexander-petrov gave worked
string dt = "2017-07-09T17:50:21.000-0500";
string date = DateTimeOffset.Parse(dt).DateTime.ToString("yyyy-MM-dd HH:mm");
gives output
2017-07-09 17:50
but on inserting the same to database it is adding +5 hrs to the time and inserting as
2017-07-09 22:50
This is a Round-Trip format of a DateTime specified with a DateTimeKind.Local kind.
You need to decide if your program needs to be aware of time zones or not.
You could try parsing it while supplying the System.Globalization.DateTimeStyles.RoundtripKind or System.Globalization.DateTimeStyles.AdjustToUniversal parameter to the Parse method.
If you want take offset into account then use DateTimeOffset type.
string dt = "2017-07-09T17:50:21.000-0500";
DateTimeOffset date = DateTimeOffset.Parse(dt);
// format on my machine
// 09.07.2017 17:50:21 - 05:00
Console.WriteLine(date);
// without offset
// 09.07.2017 17:50:21
Console.WriteLine(date.DateTime);
I couldn't get your date to work, as I think there is a colon missing in the last part. Adding that colon back allows me to convert the XSD date time into a SQL DATETIME using this script:
DECLARE #stringDate VARCHAR(30);
SELECT #stringDate = '2017-07-09T17:50:21.000-05:00';
DECLARE #xmlDate XML;
SELECT #xmlDate = CAST('' AS XML);
SELECT #xmlDate.value('xs:dateTime(sql:variable("#stringDate"))', 'datetime');
Results:
2017-07-09 22:50:21.000
Try:
string date = "2017-07-09T17:50:21.000-0500";
DateTime d = DateTime.ParseExact(date, "yyyy'-'MM'-'dd'T'HH':'mm':'ss'.'fffzzzz", null);

mssql datetimeoffset not regonized

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.

How to parse string to DateTime?

I have product list and every product has create date in DateTime type. I want to take some products that created after my entering time in string type.
I enter EnteredDate in string type, like this format : 05/16/2012
1. var dates = from d in Products
2. where d.CreateDate >= DateTime.ParseExact( EnteredDate, "mm/dd/yy", null )
3. select d;
In second line I got error as String was not recognized as a valid DateTime for "mm/dd/yy".
I also tried DateTime.Parse(), Convert.ToDateTime() and got same error.
How can I filter this product list by create date?
"mm" is minutes, and your year is 4 digits, not 2. You want "MM/dd/yyyy", if your format is really always that. How confident are you on that front? (In particular, if it's entered by a user, you should probably make your code culture-sensitive...)
I would suggest pulling the parsing part out of the query though, and also probably using the invariant culture for parsing if you've really got a fixed format:
DateTime date = DateTime.ParseExact(EnteredDate, "MM/dd/yyyy",
CultureInfo.InvariantCulture);
var dates = Products.Where(d => d.CreateDate >= date);
Call
DateTime.ParseExact(EnteredDate, "MM/dd/yyyy", CultureInfo.InvariantCulture);

Watin : Get Datetime and perform calculation

I have a textfield that has a date with the format "12/23/2010".Is there away for me to get the number 23 using watin ie get number from textfield;i'm gonna use it like this.
1.Get datetime 12/23/2010 and get number '23'
2.substract 2 from 23 and store it somewhere[ie: 23 - 2 = 21]
3.Insert the new datetime number [ie:12/21/2010 ]
string myDate = browser.TextField(Find.ByName("myTextField")).Value;
DateTime time = = new DateTime();
time2 = time - 2;
browser.TextField(Find.ByName("myTextField")).TypeText(time2);
Is this possible?or should i be looking to another way.Ask the user to insert the data instead.
You should use DateTime.Parse, DateTime.TryParse, DateTime.ParseExact or DateTime.TryParseExact to parse from text to a DateTime.
If a failure to parse indicates a failure in the code somewhere (which is probably the case here, given that it's a test) I suspect DateTime.ParseExact is the most appropriate approach, providing the expected format, culture etc.
if what you want is to subtract 2 days from a date I would do it like this:
DateTime dt = DateTime.Parse(myDate)-TimeSpan.FromDays(2);
//its steps 1,2 & 3 in one easy to read line :)
This is of course if you are sure the string you have IS a valid date. If it might not be, then you should do what the Skeet recommends, which is using first a try parse, checking if the return value is true, and if it is, then do the rest, and if it is not, send an error message.
consider writing
DateTime dt = Convert.ToDateTime(myDate);
DateTime dtNew = new DateTime(dt.Year, dt.Month, dt.Day - 2);
browser.TextField(Find.ByName("myTextField")).TypeText(dtNew.ToShortDateString());
Try getting the value of the date as string
Convert it to datetime and use AddDays we can use negative or positive value
And insert it into textbox
string myDate = this.Elements.textfield.Value;
DateTime dt = Convert.ToDateTime(myDate);
DateTime dtNew = dt.AddDays(-3);
this.Elements.ChangeDateActive.TypeText(dtNew.ToShortDateString());
That's it thanks

DataTable filter expression with DateTime and less-or-equal operator problem

I have the following code:
DataTable t = new DataTable();
t.Locale = CultureInfo.InvariantCulture;
t.Columns.Add("Date", typeof(DateTime));
DateTime today = DateTime.Now;
DateTime yesterday = today.AddDays(-1);
DateTime tomorow = today.AddDays(1);
t.Rows.Add(yesterday);
t.Rows.Add(today);
t.Rows.Add(tomorow);
string filter = string.Format(CultureInfo.InvariantCulture,
"Date >= #{0}# AND Date <= #{1}#", yesterday, tomorow);
t.DefaultView.RowFilter = filter;
foreach (DataRowView v in t.DefaultView)
Console.WriteLine(v["date"]);
I'm expecting that the filtered t.DefaultView now contains all three "days". But for some reason the last date from the range isn't included. It seems <= operator for DateTime type works like a <.
Where is the problem? Is that a bug? Any suggestions how to overcome that?
Update.
Got some responses about DateTime type and comparison operators. Thanks.
But now I want to direct attention to filter expression.
Ok, say I have the folloving loop:
foreach (DataRow r in t.Rows)
{
DateTime date = (DateTime)r["Date"];
if (yesterday <= date && date <= tomorow)
Console.WriteLine(date);
}
This loop should show the same result like
foreach (DataRowView v in t.DefaultView)
Console.WriteLine(v["date"]);
from the previous example, yes? No! Here <= works as I'm expecting and the result is all three days. Why?
Update #2: solution.
As Joe has noted - the problem is about fractions of a second.
If I format upper and lower bounds with Round-trip date/time pattern (to preserve fractions of a second) - everything works just fine:
string filter = string.Format(CultureInfo.InvariantCulture,
"Date >= '{0}' AND Date <= '{1}'",
yesterday.ToString("o", CultureInfo.InvariantCulture),
tomorow.ToString("o", CultureInfo.InvariantCulture));
The date comparison takes the time into account. So, for instance, "today at midday" is greater than just "today". If you use DateTime.Now, the time is included. So, if DateTime.Now is "today at midday", then tomorrow = today.AddDays(1) is less than "tomorrow at 3PM"... So you need to ignore the time part of the date. You can do that by formatting the date without the time. Also, if you want to check that a date is "less or equal than tomorrow" (regardless of the time), check that it is "strictly less than the day after tomorrow" :
string filter = string.Format(CultureInfo.InvariantCulture,
"Date >= #{0:MM/dd/yyyy}# AND Date < #{1:MM/dd/yyyy}#",
yesterday,
tomorrow.AddDays(1));
The code you posted in your update is not equivalent to the row filter.
Your row filter formats the date using the general format for the current culture. This probably does not include fractions of a second - therefore unless you happen to call DateTime.Now on a second boundary, your tomorrow value will be some fractions of a second beyond the range specified by the filter.
I.e. if your tomorrow value is '2009-12-23 01:02:03.456', your row filter is only taking values up to and including '2009-12-23 01:02:03', a few fractions of a second before the value specified by tomorrow.
If you only want to compare dates, you should use DateTime.Date to truncate the time component from your dates (and use DateTime.Today rather than DateTime.Now for the current date).
Try with
DateTime today = DateTime.Today;
if does not solve, check whether your date field contains time also. there lies your problem.
Update: your second comment.
when you compare with DateTime.Now e.g. Date <= 21.12.2009 14:35:35, it will take all before 14:35 hours and will ignore later rows. Hope this helps you.
See following article to get more idea
http://dotnetguts.blogspot.com/2007/06/understanding-datetime-and-timespan-in.html

Categories

Resources