Issue in the mapping - c#

I am working in creating to get the data from the PostgreSQL and insert in to MS SQL Database. So the field in the PostgreSQL is of datatype Timestamp without time zone and this needs to be going in to the field of DataTime type in MS SQL DB. I am using the scripting functoid in the map to convert them and insert.Below is the scripting I am using
public string ConvertSampDateRec(string dateReceived)
{
DateTime recDate;
DateTime.TryParseExact("yyyy-MM-dd HH:mm:ssZ", dateReceived, System.Globalization.CultureInfo.CurrentCulture, System.Globalization.DateTimeStyles.None, out recDate);
string returnRec = recDate.ToString("yyyy-MM-ddTHH:mm:ss");
return returnRec;
}
I am not sure if the format is yyyy-MM-dd HH:mm:ssZ for the TimeStamp without time zone. With this I am getting error like below
Details:"System.Data.SqlTypes.SqlTypeException: SqlDateTime overflow. Must be between 1/1/1753 12:00:00 AM and 12/31/9999 11:59:59 PM.
It is making the returnRec as 0001-01-01T00:00:00 for all the dateReceivedeven if it is not null.I tried even using DateTimeOffset but still no help

You can't put 0001-01-01T00:00:00 into a SQL database, as the error message shows, the smallest date that can be handled is 1753-01-01T00:00:00
Also, why aren't you handling the return value from DateTime.TryParseExact? You have no way of knowing when it's failing to parse the string, so you are getting the default for a DateTime object (equal to DateTime.MinValue)
Make sure you're handling the return similar to this:
private static DateTime _sqlDefaultDateTime = new DateTime(1753, 01, 01);
private void foo()
{
string parsedDate;
if (!DateTime.TryParseExact())
{
parsedDate = _sqlDefaultDateTime;
}
}

HOLD ON everyone. Sorry, but this keep going around and around, there's two other questions for the exact same thing.
OP needs to use the 'o' format to emit a xs:datetime compatible string so that it can be properly converted to a SQL date time.
This is a BizTalk specific circumstance and this explanation has been offered several times.
There's also some additional handling required which has already been described in another post.

Related

NodaTime Invalid DateTime.Kind for Instant.FromDateTimeUtc

I'm trying to get ahold of this timezone issue we are having. We would like to store all DateTimes in UTC, and then convert the DateTime to the user's timezone.
We decided to use NodaTime for this, as it seems like the right approach. However, we are experiencing an issue with it.
This is how we convert the DateTime to UTC (note - I hardcoded the usersTimeZone for now):
public static DateTime ConvertLocaltoUTC(this DateTime dateTime)
{
LocalDateTime localDateTime = LocalDateTime.FromDateTime(dateTime);
IDateTimeZoneProvider timeZoneProvider = DateTimeZoneProviders.Tzdb;
var usersTimezoneId = "Europe/Copenhagen";
var usersTimezone = timeZoneProvider[usersTimezoneId];
var zonedDbDateTime = usersTimezone.AtLeniently(localDateTime);
var returnThis = zonedDbDateTime.ToDateTimeUtc();
return zonedDbDateTime.ToDateTimeUtc();
}
And here is how we convert it back:
public static DateTime ConvertUTCtoLocal(this DateTime dateTime)
{
Instant instant = Instant.FromDateTimeUtc(dateTime);
IDateTimeZoneProvider timeZoneProvider = DateTimeZoneProviders.Tzdb;
var usersTimezoneId = "Europe/Copenhagen"; //just an example
var usersTimezone = timeZoneProvider[usersTimezoneId];
var usersZonedDateTime = instant.InZone(usersTimezone);
return usersZonedDateTime.ToDateTimeUnspecified();
}
However, when we convert it back to local time, it throws an exception:
Argument Exception: Invalid DateTime.Kind for Instant.FromDateTimeUtc
at the first line of ConvertUTCtoLocal().
An example of the DateTime could be: "9/18/2017 5:28:46 PM" - yes this has been through the ConvertLocalToUTC method.
Am I providing an incorrect format? What am I doing wrong here?
The exception you show:
Argument Exception: Invalid DateTime.Kind for Instant.FromDateTimeUtc
Is thrown from this code:
Instant instant = Instant.FromDateTimeUtc(dateTime);
It means that dateTime.Kind needs to be DateTimeKind.Utc to be convertible to an Instant, and for whatever reason it is not.
If you look at the result of your ConvertLocaltoUTC method, you'll find that it does have .Kind == DateTimeKind.Utc.
So, the problem lies elsewhere in your code, wherever you created the dateTime you're passing in to ConvertUTCtoLocal.
You may find the solution could be any of the following:
You might need to call DateTime.SpecifyKind to set the kind to UTC, but be careful to only do this when your values are actually UTC and it's just not setting the kind. For example, use this when loading a UTC-based DateTime from a database.
You might need to call .ToUniversalTime(), but be careful to only do this if the machine's local time zone is relevant to your situation. For example, do this in desktop or mobile apps where a UI control is picking a date, but you meant it to mean UTC instead of local time.
You might need to change how you parse strings into DateTime values, such as by passing DateTimeStyles.RoundTripKind to a DateTime.Parse call (or any of its variants. For example, do this if you are reading data from text, csv, etc.
If you want to avoid having to decide, don't write functions that take DateTime as input or give DateTime as output. Instead, use DateTimeOffset, or use Noda-Time types like Instant, LocalDateTime, etc. as early as possible.
This is what worked for me:
Instant instant = Instant.FromDateTimeUtc(DateTime.SpecifyKind(datetime, DateTimeKind.Utc));

How to solve DateTimeInvalidLocalFormat error: "A UTC DateTime is being converted to text in a format that is only correct for local times."?

I am getting this error while in Debug though the ToString() is executed:
A UTC DateTime is being converted to text in a format that is only
correct for local times. This can happen when calling
DateTime.ToString using the 'z' format specifier, which will include a
local time zone offset in the output. In that case, either use the 'Z'
format specifier, which designates a UTC time, or use the 'o' format
string, which is the recommended way to persist a DateTime in text.
This can also occur when passing a DateTime to be serialized by
XmlConvert or DataSet. If using XmlConvert.ToString, pass in
XmlDateTimeSerializationMode.RoundtripKind to serialize correctly. If
using DataSet, set the DateTimeMode on the DataColumn object to
DataSetDateTime.Utc.
public static string ToInterfaceString(this DateTime value)
{
return value != DateTime.MinValue ? value.ToString("yyyy-MM-ddTHH:mm:sszzz") : string.Empty;
}
In the app that I've just starting to work on it is used this format in many places. So what should I do in fact? Replace zzz with Z?
Update 1:
the DateTime that is passed to my extension is initiated to:
DateTimeCreated = DateTime.UtcNow;
Weird thing is that if I pass to this extension some other DateTime objects I don't receive any error/warning.
It's a green warning only.
So - as you seem to know what you are doing - you can just comprehend the message (which is correct) and mark the checkbox to Ignore this warning in the future.
As the DateTimeInvalidLocalFormat error explains, the conversion of the date value to string with your defined date format is not usable with DateTime which have the property Kind set to 'Utc'. Even though this error is just a warning and your code should still work, the resulting date string you will get after such operation will be incorrect. This means that if you convert your date to string and will try to parse it again to DateTime, the resulting DateTime value will be different from your original DateTime value. The difference will be as large as your time zone offset from the UTC time is. This is a serious error and should not be ignored especially if your local time does not match the UTC time.
Example:
In this example I assume that the local time zone is 2 hours ahead of UTC time.
DateTime yourLocalTime = DateTime.Now; // => 2020-05-15 08:00:00 => yourLocalTime.Kind = Local
DateTime yourTimeInUTC = DateTime.UtcNow; // => 2020-05-15 06:00:00 => yourTimeInUTC.Kind = Utc, note hours, e.g. 6 vs 8
string dateFormat = "yyyy-MM-ddTHH:mm:sszzz";
string testDateLocal = yourLocalTime.ToString( dateFormat ); // 2020-05-15T08:00:00+02:00 - This is correct date and time
string testDateUtc = yourTimeInUTC.ToString( dateFormat ); // 2020-05-15T06:00:00+02:00 - This date and time is 2 hours behind your actual date and time
To print the date and time string correctly using your date format you have to first convert your UTC date and time to the local date and time:
string testDateUtc2 = yourTimeInUTC.ToLocalTime().ToString( dateFormat ); // 2020-05-15T08:00:00+02:00 - This is correct date and time
To fix your code you should add conversion to the local time in your method:
public static string ToInterfaceString(this DateTime value)
{
return value != DateTime.MinValue ? value.ToLocalTime().ToString("yyyy-MM-ddTHH:mm:sszzz") : string.Empty;
}
You could also print UTC date and time instead of local date and time by replacing date format specifiers 'zzz' to 'Z'. However, in this case you will have a similar issue with conversion in case the DateTime passed to your method is not in UTC Kind, but e.g. in Local Kind and therefore, you have to always convert it to UTC before generating the string:
public static string ToInterfaceString(this DateTime value)
{
return value != DateTime.MinValue ? value.ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ssZ") : string.Empty;
}
Printing of date and time without doing conversion can also be done by using date format specifier 'o', but then the generated date string format will differ based on supplied DateTime Kind and this date format also includes the milliseconds.
public static string ToInterfaceString(this DateTime value)
{
return value != DateTime.MinValue ? value.ToString("o") : string.Empty;
}
This exception is thrown and caught internally inside of ToString() method so the application will continue to run further. It's the only debugger who shows this.
It might initially look like a warning which is visible when debugging only but in fact, this code will generate valid results only in case when your computer time zone is UTC (seems there will be no internal exception in this case too). If your local time zone offset is, for example, UTC+02 than the result of:
new DateTime(2020,7,30,11,22,33, DateTimeKind.Utc).ToString(#"yyyy-MM-dd\THH:mm:sszzz");
on your computer will be "2020-07-30T11:22:33+02:00" which doesn't make sense because the result obviously should have UTC offset as 00:00.
Also, of course, such internal exceptions is a bad thing for control flow and might affect your app performance if this occurs too often.
To avoid invalid .ToString() results and also internal exceptions you can just create DateTimeOffset from given DateTime and invoke .ToString() for it. So the code:
new DateTimeOffset(new DateTime(2020,7,30,11,22,33, DateTimeKind.Utc)).ToString(#"yyyy-MM-dd\THH:mm:sszzz");
will give expected result "2020-07-30T11:22:33+00:00" for any local time zone.
Another suggestion is to use the "K" custom format specifier which gives the correct results for both DateTime and DateTimerOffset.

Retrieve format of date from date value

I am receiving some data into a variable of type object. In certain cases this data are date values. For that data, I would like to convert this to a string and return it in the same format as it was passed. In some cases, the object could be a datetime, in others a date only or time only values.
As soon as I convert the object to a date or a string, it is obviously given a time of midnight which in my scenario may be a valid time (so I cannot test to see if the time is midnight in which case I could deduce that it would have been a date only date value, nor can I use regex on it as there will always be a time element).
Intellisense shows me it correctly, ie in the format I am wishing to return the value.
Is there an easy way to achieve this (hopefully without using reflection)
Many thx
Simon
Your question is a little unclear but I think you're looking for something like this:
DateTime result;
if (DateTime.TryParse(value, out result))
{
// use result here
}
In the above code value is a string that represents the data coming in. The code will only enter the if block if the string is a valid DateTime. At which point you can do the processing you need on it.
Im not sure i understand the question but i would recommend you to take a look at this conversion example on MSDN, and see the Documentation of the DateTime Structur it contains a lot of Conversion/Formatting Methods i hope it helps.
There are many way to do formatting on the datetime and one of the simple way is fetch the data from the required table in the desired format. Like here you need to display the date and if you your format is dd/MM/yyyy then try this
select Convert(varchar(10),StartDate,103) as StartDateformat from table where filtername=#filtername
use this link to find other format Cast and Convert
From local variable to DateTime Conversion
DateTime todateformat = Convert.ToDateTime(txttodate.Text.Trim());
From DateTime to local variable Conversion in specific format
string startdate = todateformat.ToString("dd/MM/yyyy hh:mm:ss");

Function to return only date

I have made a function to convert a textbox value to date.
I want to store the converted date in a datetime field in my business object with only date and not time like in format(yyyy-MM-dd)
My function is returning date along with time
public static DateTime ExtractDate(string myDate)
{
DateTime result = DateTime.MinValue;
if (myDate != null)
{
try
{
result=DateTime.Parse(myDate, new System.Globalization.CultureInfo("en-CA", true), System.Globalization.DateTimeStyles.AdjustToUniversal).ToString("yyyy-MM-dd");
}
catch (Exception)
{
throw new ApplicationException("DateTime conversion error");
}
}
return (result.Date);
}
DateTime itself always includes a time, in the case when you're setting it equal to a 'date' then the time will be 00:00:00. When it comes to displaying the string you'll need to use a format string that includes just the date part.
Just use:
result = DateTime.Parse(...).Date;
Therre's no need to convert the date/time back to a string first. The resulting DateTime will just be midnight on the relevant date.
I see that you're adjusting to universal time - you need to be aware that that may change the date. Dates are inherently local - i.e. my August 25th may well start at a different time to yours due to time zones. Alternatively, you could parse it as if it were in UTC to start with and treat it that way. You just need to be careful with what you're doing - you could run into problems where midnight doesn't exist on some days in some time zones. (Been there, done that...)
I would also suggest using DateTime.TryParseExact and specifying the input format. In particular, if you only expect users to enter dates, then specify appropriate date formats. Using TryParseExact instead of ParseExact means you don't have to catch an exception to notice that the user hasn't entered a valid date.
EDIT: Just to clarify: .NET doesn't have a type representing "just a date". Noda Time does, but that's not ready for production yet :( Normally you'd just use a DateTime and ignore the time part.
Date property returns a DateTime with time set to "00.00:00". You can not remove time from a DateTime, you can avoid to show it in the GUI using string.Format("d", yourDate).
I would change the method and return a string instead of a DateTime, because there is always time attached (therefor also the name DateTIME ;-))
If you return a string, you can do something like:
return DateTime-object.ToString("yyyy/MM/dd");
Good luck!

.NET DateTime to SqlDateTime Conversion

While converting .NET DateTime (when is default(DateTime)) to SqlDateTime should I always check if the .NET date is between SqlDateTime.MinValue and SqlDateTime.MaxValue [or] Is there a good way to do this.
Is it possible that the date could actually be outside that range? Does it come from user input? If the answer to either of these questions is yes, then you should always check - otherwise you're leaving your application prone to error.
You can format your date for inclusion in an SQL statement rather easily:
var sqlFormattedDate = myDateTime.Date.ToString("yyyy-MM-dd HH:mm:ss");
If you are checking for DBNULL, converting a SQL Datetime to a .NET DateTime should not be a problem. However, you can run into problems converting a .NET DateTime to a valid SQL DateTime.
SQL Server does not recognize dates prior to 1/1/1753. Thats the year England adopted the Gregorian Calendar. Usually checking for DateTime.MinValue is sufficient, but if you suspect that the data could have years before the 18th century, you need to make another check or use a different data type. (I often wonder what Museums use in their databases)
Checking for max date is not really necessary, SQL Server and .NET DateTime both have a max date of 12/31/9999 It may be a valid business rule but it won't cause a problem.
Also please remember resolutions [quantum of time] are different.
http://msdn.microsoft.com/en-us/library/system.data.sqltypes.sqldatetime.aspx
SQL one is 3.33 ms and .net one is 100 ns.
on my quest to do this with entitie, i stumbled over here, just hitting back to post what i've found out...
when using EF4, "a sql's" datetime column can be filled from .NET's DateTime using BitConverter.
EntitieObj.thetime = BitConverter.GetBytes(DateTime.Now.ToBinary());
also Fakrudeen's link brought me further... thank you.
-To compare only the date part, you can do:
var result = db.query($"SELECT * FROM table WHERE date >= '{fromDate.ToString("yyyy-MM-dd")}' and date <= '{toDate.ToString("yyyy-MM-dd"}'");
var sqlCommand = new SqlCommand("SELECT * FROM mytable WHERE start_time >= #StartTime");
sqlCommand.Parameters.Add("#StartTime", SqlDbType.DateTime);
sqlCommand.Parameters("#StartTime").Value = MyDateObj;

Categories

Resources