During the process of the service writing the LocaDateTime to the database, in my case, in a spring boot API with java 8, when saving the attribute configured as TIMESTAMP on the database side and LocaDateTime in the API, that date is being saved with 3 hours beyond the current operating system date.
Suppose I try to do this exactly at 10 in the morning, the date saved to the database should be 11 hours, but in my case it is not working that way ...
private LocalDateTime dataLimite;
#PrePersist
public void prepareToSave() {
String str = "1986-04-08 10:00";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm");
LocalDateTime dateTime = LocalDateTime.parse(str, formatter);
this.dataLimite = dateTime.plusHours(1);
}
Apparently it may be noted that it is a problem on the side of the Mysql configuration, but when I test ...
SELECT NOW();
The result is exactly the date and time of the operating system, so what is the real problem that is occurring? How to fix this issue?
LocalDateTime
Read the documentation more closely.
This class does not store or represent a time-zone. Instead, it is a description of the date, as used for birthdays, combined with the local time as seen on a wall clock. It cannot represent an instant on the time-line without additional information such as an offset or time-zone.
The LocalDateTime class in Java cannot be used to represent a moment. It represents potential moments along a range of about 26-27 hours, the range of time zones around the globe.
This class contains a date and a time-of-day, but purposely lacks any concept of time zone or offset-from-UTC. So if you store, for example, noon on the 23rd of January this year, we do not know if you meant noon in Tokyo, Kolkata, Paris, or Montréal… all different moments, hours apart, happening earlier in the east and later in the west.
So you are using the wrong class. For a moment, use Instant, OffsetDateTime, or ZonedDateTime.
TIMESTAMP
Read the documentation more carefully.
The TIMESTAMP type in MySQL 8 is akin to the SQL-standard type TIMESTAMP WITH TIME ZONE. This type represents a moment, a specific point on the timeline.
The documentation explains that a moment submitted to the database is adjusted to UTC for storage.
MySQL converts TIMESTAMP values from the current time zone to UTC for storage, and back from UTC to the current time zone for retrieval.
This explains your problem. You were implicitly relying on the current default time zone to be assigned to an object of the wrong type in Java that lacked any time zone. Never write code that relies on the current default time zone (or locale) of your server, as that lies outside your control as a programmer. Instead, always specify explicitly your desired/expected time zone. Or better, just work in UTC whenever possible.
For best results stick to UTC when exchanging values with the database.
OffsetDateTime odt = OffsetDateTime.now( ZoneOffset.UTC ) ;
myPreparedStatement.setObject( … , odt ) ;
Retrieval.
OffsetDateTime odt = myResultSet.getObject( … , OffsetDateTime.class ) ;
To view that moment through the wall-clock time used by the people of a particular region, apply a ZoneId to get a ZonedDateTime.
ZoneId z = ZoneId.of( "Australia/Sydney" ) ;
ZonedDateTime zdt = odt.atZoneSameInstant( z ) ;
Related
I want save date with UTC time zone in sql server 2014. I have used ZonedDateTime zonedDateTime = ZonedDateTime.now(ZoneId.of("UTC")) to get the current date time and persisting this to db using Hibernate session object. While debugging I can see that in Java program date is fine like this 2019-09-25T13:22:29.573Z[UTC], but after saving in database column it is something like this 2019-09-25 18:53:23.3630000. It's automatically converting the time part according to system time. Can anyone please suggest what is the issue? I have used datetime2 datatype while creating this column in database.
Wrong type
You are using the wrong data type for your column.
The type datetime2 cannot represent a moment. That type stores only a date and a time-of-day, but lacks the context of a time zone or offset-from-UTC. So if you store “noon on the 23rd of January in 2020”, we cannot know if you meant noon in Tokyo Japan, noon in Tunis Tunisia, or noon in Toledo Ohio US, three different moments several hours apart. This wrong type is akin to the SQL standard type TIMESTAMP WITHOUT TIME ZONE. The equivalent class in Java is LocalDateTime.
If you already have data stored, you will need to refactor your database. Basically, add a new column of the correct type, copy data over for each row, converting as you go. Of course, this only works if you know the intended time zone that was absent from each value saved.
Right type
While I don’t use Microsoft SQL Server, according to the doc you should be using a column of type datetimeoffset to record a moment. This type adjusts any submitted value into UTC for queries and sorting, while also recording the offset. This type is akin to the SQL standard type TIMESTAMP WITH TIME ZONE.
Generally best to store your moments in UTC, an offset of zero hours-minutes-seconds.
The Instant class represents a moment in UTC.
Instant instant = Instant.now() ;
If you have a ZonedDateTime, you can extract an Instant.
Instant instant = zdt.toInstant() ;
We would like to save that Instant directly to the database. Unfortunately the JDBC 4.2 soec does not require support for either of the two most commonly used java.time classes: Instant and ZonedDateTime. The spec does require support for OffsetDateTime. So we convert.
OffsetDateTime odt = instant.atOffset( ZoneOffset.UTC ) ;
Submit to database.
myPreparedStatement.setObject( … , odt ) ;
Retrieve.
OffsetDateTime odt = MyResultSet.getObject( … , OffsetDateTime.class ) ;
Extract an Instant to make clear in your code that you want UTC.
Instant instant = odt.toInstant() ;
See this moment through the wall-clock-time used by the people of a particular region (a time zone).
ZoneId z = ZoneId.of( "Asia/Kolkata" ) ;
ZonedDateTime zdt = instant.atZone( z ) ;
The dates with timestamps are inserted/saved into the database with datatype datetime in Central Time (CT) regardless of the timezone. When I access the application in eastern timezone and retrieve those dates from my time zone, which is Eastern Time (ET), I would like the dates to render in my Eastern Time zone and not central time. For example, if the stored date is 2018-11-19 13:08:44 in the database in Central Time, I need to get it back as 2018-11-19 14:08:44 if I connect from Eastern or 2018-11-19 12:08:44 if I connect from Mountain Time Zone. I have a Java bean and I need to set the retrieved date converted to my timezone and display the date in a csv file. How do I accomplish this? Java is the server side language. Thank you very much.
You have not provided enough detail to give you precise help. But here are some general guidelines.
Data type of column
To record moments, your database table column must be defined with a type akin to the SQL standard TIMESTAMP WITH TIME ZONE. The equivalent in MySQL seems to be TIMESTAMP.
Beware of tools with an anti-feature of dynamically applying a default time zone to the value extracted from the database. This creates the illusion of the stored value having that particular time zone. This is certainly not the case in MySQL 8 where TIMESTAMP is documented as always being stored in UTC.
Do not use the type TIMESTAMP WITHOUT TIME ZONE as that records only the date and time-of-day but no context of time zone or offset-from-UTC. The equivalent in MySQL seems to be DATETIME.
UTC is your friend
Generally best to track moments as seen through UTC, that is, with an offset-from-UTC of zero hours-minutes-seconds. You should learn to think of UTC as the One True Time, all other zones and offsets are but mere variations. All programmers and sysadmins should be working in UTC for their logging, debugging, data storage, and data exchange. Apply a time zone only as required by business logic or for presentation to the user.
inserted/saved into the database with datatype datetime in Central Time (CT) regardless of the timezone
I have no idea what that means.
If you want to track moments, specific points on the timeline, you must have a time zone or offset-from-UTC. As I suggested, using UTC itself is strongly recommended.
In java.time, the Instant class represents a moment in UTC, always in UTC.
Instant instant = Instant.now() ; // Capture current moment in UTC.
Oddly, the JDBC 4.2 standard does not require support for the two most commonly used java.time classes: Instant and ZonedDateTime. The third class for moments, OffsetDateTime, is required. No matter, we can easily convert. Specify an offset of zero using the constant ZoneOffset.UTC.
OffsetDateTime odt = instant.toOffset( ZoneOffset.UTC ) ;
Or skip the Instant.
OffsetDateTime odt = OffsetDateTime.now( ZoneOffset.UTC ) ;
Send to the database.
myPreparedStatement.setObject( … , odt ) ;
Retrieve from the database.
OffsetDateTime odt = myResultSet.getObject( … , OffsetDateTime.class ) ;
Notice that all this code is working in UTC exclusively. No time zones involved, just an offset of zero hours-minutes-seconds.
Time zones
Central Time (CT) …Eastern Time (ET) …
These are not time zones. These are pseudo-zones, commonly used in the media, but never to be used in your programming.
Specify a proper time zone name in the format of Continent/Region, such as America/Montreal, Africa/Casablanca, or Pacific/Auckland. Never use the 2-4 letter abbreviation such as EST or IST as they are not true time zones, not standardized, and not even unique(!).
ZoneId
While ZoneOffset is for mere offsets (a number of hours-minutes-seconds), the ZoneId class is for time zones (a history of past, present, and future changes to the offset used by the people of a particular region).
ZoneId z = ZoneId.of( "America/Montreal" ) ;
ZonedDateTime
We can apply a ZoneId to an Instant or OffsetDateTime to view that moment through the wall-clock time (offset) used by the people of that region.
ZonedDateTime zdt = odt.atZoneSameInstant( z ) ;
Text
To create strings in standard ISO 8601 format representing the value of our java.time objects, simply call toString.
To generate text in other custom formats, or even to automatically localize, see the DateTimeFormatter and DateTimeFormatterBuilder classes. Search Stack Overflow as this has been covered many many times already.
Refactoring
You mentioned "datetime" in your Question. If you meant that your column is literally of type DATETIME, you have a mess on your hands. You should refactor your database to use proper types.
For that refactoring, extract the values from that column, retrieving as the Java type LocalDateTime. This class is for a date and time-of-day but lacking the context of a zone or offset. As such, this value is not a moment, is not a point on the timeline.
LocalDateTime ldt = myResultSet.getObject( … , LocalDateTime.class ) ; // Retrieving value from a MySQL 8 column of type `DATETIME`.
You claim to know the time zone intended, but not recorded, for those values. Keep in mind that you are only guessing. You do not really know for sure what the original zone/offset was, as that value was discarded.
But if you are certain of the intended zone, specify as a ZoneId. By "Central Time (CT)" I will assume you meant a time zone such as America/Chicago.
ZoneId zChicago = ZoneId.of( "America/Chicago" ) ;
Apply this ZoneId object to each retrieved LocalDateTime object.
ZonedDateTime zdt = ldt.atZone( zChicago ) ;
Convert our ZonedDateTime to an OffsetDateTime given the support required by the JDBC 4.2 spec. (Your JDBC driver may optionally support ZonedDateTime, so you could try that if you like.)
OffsetDateTime odt = zdt.toOffsetDateTime() ; // Stripping away the rich time zone information, trading it for simply a number of hours-minutes-seconds ahead/behind UTC.
Send to the database in a new column of type TIMESTAMP, as should have originally been done when the database was designed.
myPreparedStatement.setObject( … , odt ) ;
Notice that the OffsetDateTime object we are sending is not in UTC. That object will carry the offset used by the Chicago-region at that time-of-day on that date (several hours behind UTC). Of course that offset varies because of politician-imposed anomalies such as Daylight Saving Time (DST).
But you should not have to worry about the offset in the OffsetDateTime. Your MySQL-specific JDBC driver should take care of converting to UTC per the requirements of that type as defined in MySQL. You should do a bit of testing to be sure this is working properly, and according to your understanding. If while debugging you want to see the moment of this OffsetDateTime in UTC, convert to an Instant: odt.toInstant().toString().
When you have finished populating the new column of type TIMESTAMP, drop the old column of type DATETIME.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 3 years ago.
Improve this question
I have heard that postgres supports storing of datetime and time with both timezone and without timezone. Now an application running in JST timezone has to store time on database side. Now for wherever i have read it is suggested that you shall always keep things stored in UTC which can work in case of datetime because upon receiving datetime on application layer i can manipulate it according to my preferred timezone. But if i only want time stored on database side then for that as well shall i store it as UTC time ? If yes then 1 am in JST will result in 4 pm UTC of previous day. so could someone please suggest me what shall be the preferred way of storing time in database ?
As suggest in one of the answer if i read the time in LocalTime then if i store time as 12:00 JST then upon reading on application side it will be 12:00 JST or 12:00 UTC.
If there is even a remote possibility that times will ever be in more than one time zone, then you need to store them in a common well-known time zone, and UTC is the best choice for that.
If you're absolute certain, beyond any shadow of doubt, that the application will only ever be used in a single time zone, and that both application and database servers will run in that time zone, then you can store the times in that local time zone.
Since such certainty is rare, it is recommended to use UTC.
If the original time zone must be retained, you need a separate column to store the time zone, so it can be re-applied when loaded from the database.
tl;dr
Apparently you want to store a time-of-day without a date and without a time zone.
Use the Java class java.time.LocalTime and the standard SQL type TIME WITHOUT TIME ZONE.
LocalTime.of( 15 , 30 )
…and…
myPreparedStatement.setObject( … , LocalTime.of( 15 , 30 ) )
Details
Be aware that an offset-from-UTC is merely a number of hours-minutes-seconds, nothing more. A time zone is much more. A time zone is a history of the past, present, and future changes to the offset used by the people of a particular region.
I have heard that postgres supports storing of datetime and time with both timezone and without timezone.
Actually the SQL standard defines:
TIMESTAMP WITH TIME ZONETrack a moment, a specific point on the timeline. Represents a date, a time-of-day, and an offset-from-UTC or a time zone. Common implementations use UTC.
TIMESTAMP WITHOUT TIME ZONETracks a date and time-of-day but without the context of an offset or zone. So this type cannot represent a moment, is not a point on the timeline. For example, for a value of "noon on the 23rd of January in 2020", we do not know if this means noon in Tokyo, noon in Paris, or noon in Montréal — all very different moments, hours apart.
Now an application running in JST timezone
JST is not a true time zone. Proper time zones have a name in Continent/Region format. Never use the 3-4 letter pseudo-zones such as EST or IST as they are not true time zones, not standardized, and not even unique(!).
ZoneId z = ZoneId.of( "Africa/Tunis" ) ;
If by JST you meant the time in Japan, use Asia/Tokyo.
ZoneId z = ZoneId.of( "Asia/Tokyo" ) ;
to store time on database side to be aware of the time slots.
I have no idea what that means.
Now for wherever i have read it is suggested that you shall always keep things stored in UTC
When tracking actual moments, yes, generally best to do so in UTC, that is, an offset-from-UTC of zero hours-minutes-seconds. Think of UTC as The One True Time, and other offsets & zones as mere variations, as localization issues for presentation of data to users. Do most of your business logic, data storage, data exchange, debugging, and logging in UTC. Keep a second clock on your desk set to UTC, seriously. Programmers and sysadmins should learn to think and work in UTC, leaving behind your parochial time zone while on the job.
which can work in case of datetime because upon receiving datetime on application layer i am manipulate it according to my preferred timezone.
Yes, as discussed above, work your logic in UTC (generally) and present localized to the zone expected by the user. When crucial, confirm with the user their desired time zone. And make a habit of always including the zone/offset info when displaying a date or time, to avoid ambiguity and confusion.
But if i only want time stored on database side then for that as well shall i store it as UTC time. If yes then 1 am in JST will result in 4 pm UTC of previous day. Can someone suggest how shall i store time alone in database side.
Do you mean you want to store just the time-of-day without a date and without a time zone? If so, use:
LocalTime in Java.
TIME WITHOUT TIME ZONE in standard SQL.
The SQL standard bizarrely defines a TIME WITH TIME ZONE type, but this makes no sense. Just think about it. And don’t be surprised; this is not the only anti-feature in the SQL standard. Postgres does offer this type, as following the standard is one of the primary goals of Postgres. Likewise, the java.time framework in Java includes a java.time.OffsetTime class to be compatible, but you will never use it.
Postgres has excellent date-time handling, and does offer the TIME WITHOUT TIME ZONE data types.
LocalTime localTime = LocalTime.of( 15 , 30 ) ;
myPreparedStatement.setObject( … , localTime ) ;
Retrieval.
LocalTime localTime = myResultSet.getObject( … , LocalTime.class ) ;
You might want to apply that time-of-day to a date and time zone to determine a moment by instantiating a ZonedDateTime.
ZoneId z = ZoneId.of( "Asia/Tokyo" ) ;
LocalDate localDate = LocalDate.of( 2019 , Month.JANUARY , 23 ) ;
ZonedDateTime zdt = ZonedDateTime.of( localDate, localTime, z ) ;
See that same moment through the wall-clock time of UTC. Same moment, same point on the timeline, but different wall-clock time.
Instant instant = zdt.toInstant() ;
And adjust to another time zone if desired. Again, same moment, same point on the timeline, but different wall-clock time.
ZonedDateTime zdtMontréal = instant.atZone( ZoneId.of( "America/Montreal" ) ) ;
Perhaps you want to see the time-of-day in Québec for that moment.
LocalTime localTimeMontréal = zdtMontréal.toLocalTime() ;
Here is a table of the various date-time types in Java and in standard SQL.
We store a date in a sqlserver db table as varchar.
When this is read in the java code as a String and then parsed to a Date, it gets read as UTC (java code is in servers that are in UT). And on reconverting the date to ET, it goes 4 hours behind. How do I handle storing the date in ET in this db column so it gets read as ET in the java code.
We are researching around offsets, but not understanding exactly what to do.
Varchar date in table 03/29/2019 23:23:03 //we want this date to be in ET
SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss");
Date beginDate = sdf.parse("03/29/2019 23:23:03");
//The problem is when this code executes, the server is in UTC. So beginDate //is read as 03/29/2019 23:23:03 UTC instead of 03/29/2019 23:23:03 ET
Expected 03/29/2019 23:23:03 ET
Actual 03/29/2019 23:23:03 UTC
First, you need to be aware that a Date object doesn't have a time zone at all. It's just an instant in time. So even when you've parsed the value correctly, it'll represent the right instant in time, but you may need to convert it back to Eastern Time later on.
Second, you need to be aware that storing values like this introduces ambiguity - if you store a value of (say) 11/03/2019 01:30, that local time occurs twice - once before the daylight saving transition and once afterwards. If you're always storing times in the past, you should at least consider storing UTC instead - although that's not always the right answer, particularly not if you're storing future date/time values.
For the parsing part, you just need to set the time zone in the Calendar used by SimpleDateFormat. For example:
SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss", Locale.US);
sdf.setTimeZone(TimeZone.getTimeZone("America/New_York");
Date beginDate = sdf.parse("03/29/2019 23:23:03");
Finally, I'd strongly advise you to start migrating your code to use java.time if at all possible. It's a much nicer API than the java.util.Date etc API.
Use a datetime datatype of your database engine (DBMS), not varchar for date and/or time. With many DBMSs, the timestamp with timezone type defined in the SQL standard is the correct type to use. I don’t know SQL Server well enough to tell precisely what you should use there. Make sure you store date and time in UTC.
If you cannot get around the requirement to store as varchar, store in ISO 8601 format in UTC. For example 2019-03-30T03:23:03Z.
If you also cannot get around the requirement to store in Eastern Time, make sure you are clear whether North American Eastern Time or Australian Eastern Time is intended. Store date and time with UTC offset, for example 2019-03-29T23:23:03-04:00.
If you also cannot get around the requirement to store in the format 03/29/2019 23:23:03 (without offset), be aware that in the fall when summer time (DST) ends and the clocks are moved back, you are storing ambiguous times.
Under all circumstances prefer java.time, the modern Java date and time API. The answer by Basil Bourque shows you how, I don’t need to repeat that.
java.time
The Answer by Jon Skeet is correct. As he mentioned, you should be using the java.time classes defined by JSR 310. These modern classes years ago supplanted the terrible date-time classes such as Date and SimpleDateFormat. Here is some example code in that direction.
Varchar date in table 03/29/2019 23:23:03 //we want this date to be in ET
Parse the string as a LocalDateTime because our input lacks an indicator of offset-from-UTC or time zone.
Define a formatting pattern to match the input.
DateTimeFormatter f = DateTimeFormatter.ofPattern( "MM/dd/uuuu HH:mm:ss" ) ;
Parse.
LocalDateTime ldt = LocalDateTime.parse( input , f ) ;
If you are absolutely certain this date and time was intended for a particular time zone, apply a ZoneId to get a ZonedDateTime.
ZoneId z = ZoneId.of( "America/New_York" ) ;
ZonedDateTime zdt = ldt.atZone( z ) ;
Adjust to UTC by extracting an Instant.
Instant instant = zdt.toInstant() ;
Your JDBC driver may not accept a Instant. So convert to an OffsetDateTime where the offset is set to zero hours-minutes-seconds (in other words, UTC itself).
OffsetDateTime odt = instant.atOffset( ZoneOffset.UTC ) ;
Write to a column of type TIMESTAMP WITH TIME ZONE in your database. As of JDBC 4.2 and later, we can directly exchange java.time objects with a database.
myPreparedStatement.setObject( … , odt ) ;
And retrieval.
OffsetDateTime odt = myResultSet.getObject( … , OffsetDateTime.class ) ;
Adjust to your desired time zone.
ZonedDateTime zdt = odt.atZoneSameInstant( z ) ;
Now you have the pieces needed to do some database-refactoring, to replace that varchar column with a proper TIMESTAMP WITH TIME ZONE column.
I have a column in the database (PostgreSQL).
I want to insert the current time in GMT in this column.
When getting the current time and inserting it into the DB
it's inserted in the server timezone GMT-5 although that time was in GMT+0.
Any ideas how to insert this time in the database in GMT timezone?
Always UTC in Postgres
Understand that Postgres always stores values in a column of type TIMESTAMP WITH TIME ZONE in UTC, that is, with an offset from UTC of zero hours-minutes-seconds.
So the name is bit of a misnomer, in that no time zone is actually being stored. Instead, any time zone or offset indicator arriving with an input is used by Postgres to adjust to UTC. After adjustment, the UTC value is stored to the table while the zone/offset indicator is discarded. If you care about the original time zone, you must write that yourself to a second column.
What makes things confusing is tooling and middleware such as the psql console client app. These often are opinionated, choosing to inject some default time zone adjustment onto retrieved values. So while the Postgres database always retrieves a date-time in UTC from any TIMESTAMP WITH TIME ZONE column, you may see otherwise on your receiving end. Such a feature, while well-intentioned, is an unfortunate anti-feature to my mind.
Fortunately, I have not seen any JDBC driver that performs such an adjustment. You should always get a UTC value when retrieving an OffsetDateTime from a TIMESTAMP WITH TIME ZONE column (described below). But test your particular JDBC driver to be sure.
JDBC and the java.time classes
The modern solution for date-time handling in Java is the java.time classes.
To capture the current moment, use Instant. This class represents a moment as seen in UTC.
Instant instant = Instant.now() ; // Capture the current moment as seen in UTC.
However, despite Instant being the most basic and probably the most commonly used java.time class, the JDBC 4.2 team made the inexplicable decision to not require its support. (Nor is ZonedDateTime support required, by the way.)
Instead, the JDBC 4.2 spec requires support for OffsetDateTime. Fortunately, conversion between Instant and OffsetDateTime is trivial.
OffsetDateTime odt = instant.atOffset( ZoneOffset.UTC ) ;
Or you can skip the Instant class is this case.
OffsetDateTime odt = OffsetDateTime.now( ZoneOffset.UTC ) ;
Write to the database.
myPreparedStatement.setObject( … , odt ) ;
Retrieve from the database.
OffsetDateTime odt = myResultSet.getObject( … , OffsetDateTime.class ) ;
This OffsetDateTime object will carry an assigned offset from UTC of zero hours-minutes-seconds — commonly called just “UTC” as an abbreviation.
Extract an Instant if needed.
Instant instant = odt.toInstant() ;
Or adjust into a time zone.
ZoneId z = ZoneId.of( "Asia/Tokyo" ) ;
ZonedDateTime zdt = odt.atZoneSameInstant( z ) ;
A caution regarding possible data-loss: The resolution in java.time is nanoseconds. Capturing the current moment is likely limited to microseconds because today’s commonly-used hardware clocks go no finer. Nevertheless, a java.time object such as OffsetDateTime may carry nanoseconds. Meanwhile, Postgres date-time values have a resolution of microseconds. So if using a java.time object with any nanos present, writing that value with Postgres will truncate the nanos, resulting in a different value to be retrieved later.
I think paragraph 8.5.1.2 of the manual might be enlightening. It states that by default time is assumed to be without timezone and if one is given it is silently ignored.
In order to make things clear I think it is best to explicitely cast the time :
pti=> select timestamp with time zone '20100610T180000-5';
timestamptz
------------------------
2010-06-11 01:00:00+02
(1 row)
pti=> select timestamp with time zone '20100610T180000PST';
timestamptz
------------------------
2010-06-11 04:00:00+02
(1 row)
As is evident the time with time zone is properly converted from localtime to server time.
SELECT current_timestamp AT TIME ZONE 'gmt-5';