-
Notifications
You must be signed in to change notification settings - Fork 822
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Timestamptz translation and session timezone #1469
Comments
This is the (current) expected behavior, even if it's confusing. tl;dr First, keep in mind that the When Npgsql reads values from PostgreSQL, those values are in binary encoding. PostgreSQL's binary encoding of To truly match PostgreSQL's behavior, Npgsql would have to be aware of the PostgreSQL session timezone. This is theoretically possible, but involves converting PostgreSQL timezone identifiers to .NET ones - not at all trivial, and probably not worth the bother, although if someone wants to take a look go ahead. Closing as this is the expected behavior, but feel free to continue the conversation and ask questions. |
@roji, thanks for the reply!
Yes, I'm aware of that. Timestamptz is indeed a timestamp at utc, an inaccurate naming.
Exactly, that's my point. Is that information (the session timezone) available to Npgsql when, say, data reader is processed? In my scenario (ported from Oracle), we initialize the database session after opening the connection by calling a stored procedure:
We use timezone='+1:00' syntax both in Oracle and PostgreSQL. These numeric offsets seems to be easy to support. So, is that current session timezone setting always readily available to Npgsql or it should be queried via extra network roundtrip? We don't use Npgsql to change the session's timezone explicitly — it is done inside the |
I think, the real problem is that DateTime.ToLocalTime() uses the OS's time zone information. It cannot be overridden per-thread or even per-application, it's system-wide. So if Npgsql had a thread-local setting to override the TimeZoneInfo used for the timestamp conversion, that would just fine. Is that possible? |
@yallie, it's very easy to work around this (i.e. by explicitly doing timezone conversion client-side). It's true that Regarding changing Npgsql to make it convert The real problem, as I said before, is that PostgreSQL uses IANA time zone names (e.g. America/New_York), while .NET TimeZoneInfo uses Windows time zone names (e.g. Eastern Standard Time). This means that converting PostgreSQL's timezone names to something usable by Npgsql is non-trivial - see this question. In a nutshell Npgsql would have to internally maintain a mapping, which may need to be updated from time to time... Not something I'd like to do unless it's necessary, but this issue simply doesn't seem important enough to go down that road... |
Yes, that may be fine if the application is PostgreSQL-only. But it's a pain for multi-database applications, in my case Oracle/Postgres. It's OK to have different queries for different databases, but it's too bad if I'm also forced to process the results differently throughout the application code.
Yes, I understand that it's not an easy task, and I agree that it's quite a burden to support (I guess it's easier for the Oracle driver because everything is handled by the database itself). Perhaps it's OK to leave this timezone translation complexity to the end-user, but I don't think it's fine to leak it down to the application code... What about providing an extension point to Npgsql so I can translate dates according to my needs?
What about the multi-tier applications? Application server connects to the database to process the client requests. App-server threads belong to different user sessions and have different time zones. So it's just pointless to convert timestamps using the app-server's time zone info. TL/DR: please provide an extension point to Npgsql so I can handle all datetime translation by myself. It can be as easy as an interface with two methods (convert DateTime before sending to PostgreSQL + convert it back upon reading). The default implementation is just the current behavior, namely DateTime.ToUTC() and DateTime.ToLocalTime(). And my implementation is up to me. Would that be OK? Thanks, Alex. |
Sorry for not answering sooner on this. One of the main new features of 3.3 will probably be general extensibility for type converters, allowing you to add type handlers for types Npgsql doesn't support, or replace standard type handlers with custom ones - this would allow you to do any sort of timezone conversion you want. See #1475. |
One thing you can also do is convert the time stamp to a string on the server (by appending ::text). Then you will get the expected value if all you want is just to print it anyway to the user. Or convert it to a "timestamp without time zone". Then the returned timestamp will be a DateTime object with the correct time zone. |
No worries @roji! Thanks for your answer. We decided to disable the support for the time zones in the application completely until we find a way to work around the time translation issue.
Unfortunately we're stuck with the 2.x branch due to the requirement of using the .NET 4.0 version for the foreseeable future.
Thanks @Emill, we already did that and documented the time zones as an unsupported feature. Hope we'll get back to that one day though. |
Sorry for the dumb question, perhaps I am missing something obvious. According to the PostgreSQL documentation,
timestamp with time zone
values are returned using the current session's time zone, i.e.:But I can't get it to work with Npgsql. Looks like the driver uses system's time zone settings instead of the supplied
timezone
value.Steps to reproduce
Here is my code:
The output:
The issue
I'm expecting that the first time value is returned in UTC timezone, and the second time in UTC+5 timezone. Instead, it's always returned as UTC+3 which is my system's timezone. I've tried different versions of the driver, and it works the same.
Further technical details
Npgsql version: 2.2.5 and 3.2.1
PostgreSQL version: 9.6.1
Operating system: Windows 10
The text was updated successfully, but these errors were encountered: