Postgres and c# - DateTime with timezone confusion - c#

Hopefully not a repost of another... a rather simple question, but I think I'm fundamentally confused about how dates/times with timezones are handled between Postgres and c#.
Simple situation, at one point in the program I call DateTime.Now and save to a variable 'now'. This is inserted into a Postgres DB.
cmd.Parameters.AddWithValue("createdat", now);
Great. The column that this is inserted into is of type "timestamp with time zone". When I view the result from something like DataGrip or DBeaver the raw data is exactly what I want (I think).
2021-03-09 15:07:51
Later on I query this table in a rather simple way.
SELECT createdat FROM mytable WHERE mycondition;
I cast it as a c# DateTime type and populate a class with it.
while (reader.Read())
{
myClass.createdAt = (DateTime) reader["createdat"];
}
However, the value is populated as the following:
3/9/2021 10:07:51 AM
Something is not working here. First, if the column in the DB is of timestamp with time zone, where is the time zone information? Second, if the time zone is working, since it is being both populated and queried from the same computer, why is there a discrepancy? Third, and the pressing issue, how do I solve this? Must I explicitly define the time zone? I'm confused as to why it is returning different data... Hopefully, someone can help me out.

I think Dbeaver is changing the time zone, but the data inserted is the same you get on c#. Try to check directly on the server using commandline because maybe dbeaver is changing it to diplay on your pc

Related

ASP.Net C# sqlDr.GetValue(a) Date Column Displaying Time too

I tried to use
sqlDr.GetValue(a).ToString()
to display a DATE column from my database which looks like this..(the Date Submitted column)
But the problem is , when i display it using getValue(8).toString(), something like this is displayed..
Thanks for taking your time to read my post , any reply is much appreciated!
The problem is .Net does not have a Date-only primitive type. Therefore the Sql Server Date column type maps to a full DateTime value in .Net, which always includes a time component. If you don't provide a time component, the DateTime struct will have a 0-value time component, which maps to 12:00:00.000 AM.
To get around this, you need to specify the output format for your column, so that it explicitly does not include a time value. You want something like this:
((DateTime)getValue(8)).ToString("d")
However, the exact code you need will vary wildly depending on how your result table is created. If necessary, check the SqlDataReader.GetDataTypeName() function to know what type you're dealing with.
Try using the DateTime.ToShortTimeString Method ():
Console.WriteLine("Short date string: \"{0}\"\n", myDateTime.ToShortDateString());
Output: Short date string: "5/16/2001"

Datetime format is 'mm-dd-yyyy' when getting while using SqlDataAdapter but if I run the same query in ms sql then its 'yyyy-mm-dd'

I know the question is a bit confusing. Please let me elaborate.
Suppose
I have a table student master which has a column DOB
I have inserted a record and in DOB I have inserted '1991-01-01'
running select statement from sql server is returning date in the same format as it is inserted '1991-01-01' but when I am running the same query from C# using SqlDataAdapter then its returning date as '01-01-1991'
Can anyone explain why it is happening and is there any way to fetch the date in same format as it is inserted.
Query
Is it possible to get the DateTime using SqlDataAdapter as it was inserted?
P.S: column data type is Datetime
let's separate the wheat from the chaff :)
if for your needs meaningful is data type (datetime in this case), then formatting does not matter at all. All layers which will exchange or process the data will use data type information for that.
But
if the meaningful part is formatting, i.e. string representation of the data, then you need to consider the appropriate settings of UI tools you use to display your data. SSMS, for example, uses regional settings for that. If you need to visualize data in the identical manner, so you need the identical strings, you should take care of formatting by your self or in another words, you need to convert your datetime data to string in the same way in all places where you need it.
In T-SQL, for example, you could use CAST and CONVERT functions for formatting your data in a format you need.
If you can't match up the "Cultures" between the SQL Server and the machine you're building the application on (and, in fact, you cannot rely on that really if you're application is going to be deployed to other machines!), then the cheap and quick way round it is to run your date returns through a parse function such as this:
private string FncFormatDate(string date)
{
DateTime formattedDate;
if (DateTime.TryParse(date, out formattedDate))
{
return formattedDate.ToString("yyyy-MM-dd");
}
else
{
return "Invalid date";
}
}
I hope this answers your question.

How to save and show elapsed time correctly in datagridview?

I want to save elapsed time in a form into sql table
timer started at form load event and when I click the save button try to save it with
cmd.Parameters.AddWithValue("#duration", textBox3.Text);
in sql table and duration column data saved like this: 00:22
and this absolutely correct for my job
but in datagridview's duration column time showed like this:03/16/2015 12:22pm
Why data in datagridview converted to a full date data instead of original elapsed time?
Well, you didn't give us enough information about your problem but I try my best..
first time it was a float data type but i changed it to nvarchar(255)
for better performance in saving data from c# program
Based on your data (which is 00:22) neither float not nvarchar are seem the right type in your database.
If this is a time interval, time type can be the right type since it is a time of a day. But this time type can't hold bigger than 24:00 values. You will get an error when you try to insert it a bigger value.
If this data can be more bigger than 24:00, I would suggest to parse it to TimeSpan first and save it's Ticks property to bigint typed column in your database.
Looks like your program takes your 00:22 and parse it to DateTime in somehow like DateTime.Parse("00:22"), that's why it generates a today's date with parsed time of day as a DateTime in your datagridview.
By the way, don't use AddWithValue method as a best practice. It may unexpected results sometimes. Use .Add() method overloads to specify your SqlDbType and it's size.
Further reading:
Bad habits to kick : choosing the wrong data type
Can we stop using AddWithValue() already?

How can i set sql date time with entity framework c#.net

I am very new to entity framework. Nice concept and fast as well.
Working in c#.net right now. I have stucked here where datetime comes in picture.
I mean....
lets assume i have user table in DB where CreatedDate fields is there in with datetime datatype in sql db.
My entity framework works like this...
when i need to add object to db, i simply pass objUser.createdDate = DateTime.now.
How ever I want to change the concept for some requirement changes.
I need to store sql server DateTime() for createdDate field in table.
How can i do that???
any idea...please help.
follwoing is a just sample code of my project.
objCustomer.RegisterDate = DateTime.Now;
objCustRepository.AddCustomer(objCustomer);
I want to remove this DateTime.Now line and maintain through sql....
if you can store the value from stored procedure instead of your business logic then you can try it by following.
to store SQL Datetime value then you can also use GETDATE() function in SQL.
or
you can define RegisterDate default value = GETDATE()
It sounds like you are trying to target the specific timezone associated with your sql server, if I am not mistaken?
If so why not use DateTimeOffset.Now via your c# when setting the date.
See this blog post here about the type.
A DateTimeOffset represents a specific point in time, so you can use it to convert to any timezone representation you may need on your UI.
Be aware though that it is only supported on SQL Server 2008 and greater, if I remember correctly. :)

How to keep previous and new value of data?

I’m currently working on a project where we need to archive and trace all the modified data’s.
When a modification surrender, we have to kept theses information
Who has modified the data?
When?
And … that’s why I’m asking this question: Keep the previous
and the new value of the data.
Quickly, I have to trace every modification for every data.
Example :
I have a name field why the value “Morgan”.
When I modify this value, I have to be able to say to the user that the 6th of January, by XXX, the value changed from “Morgan” to “Robert” …
I have to find a clean and generic method to do this because a large amount of data is concerned by this behavior.
My program is in C# (.NET 4) and we are using Sql Server 2008 R2 and NHibernate for the object mapping.
Do you any ideas, experience or solution about how to do a thing like that?
I am a little confused about at what point you want to have the old vs new data available. But, this can be done within a database trigger as in the following question:
trigger-insert-old-values-values-that-was-updated
NHibernate Envers its what you want :)
You must use NHibernate 3.2+ (3.2 is the current release).
Its easy like
enversConf.Audit<Person>();
You can get info here and here
I've been in the same situation as you. I ended up doing in this way:
Save an ActivityEntry in the database containing an identity column (if you have multiple objects that change), an action-indicator (could be "User changed firstname", as a int), date field, userId and most important a parameter field.
Combining the values from the parameter field and the action-indicator I'm able to make strings like "{0} changed {1}'s firstname from {2} to {3}" where my parameter values could be "John;Joe".
I know it feels kinda wrong saving these totally loosely typed values in the database, but I believe it's the only way around, without having a copy of each table.

Categories

Resources