Is there a SQL function to convert to PST or PDT depending on the date? - sql

I would like to convert times from pacific to UTC. However, I must first convert the times to either PST or PDT depending on the date. Is there a SQL function that can do this, or does anyone have any advice for creating this function?

The link you provided is pretty much useless as a guide to timestamps. If you are going to work with timezones then store your timestamps in a timestamp with time zone field. The timezone will not actually be stored but the timestamp will be stored as a UTC. Whenever a timestamp is entered it is rotated to a UTC value. This makes working with value easier down the road. If you want to take into account DST transitions you will need to use full timezone names e.g. US/Pacific, as they cover the two offsets(PST/PDT) that constitute the standard/daylight savings timezones. As you found using the offset PST(-08) or PDT(-07) gets you a fixed offset regardless of date.

Related

How to update a date with a time zone in postgresql?

I want to update a date with a timezone (+2 hours) but it ends up as UTC (0 hours)
Date type is 'timestamp-with-timezone'
Query...
update table set date = '2022-05-25 13:28+02:00'
will end up as this in the database.
2022-05-25 11:28:00+00
What's wrong here?
tl;dr
Nothing wrong. Postgres stores values of TIMESTAMP WITH TIME ZONE in UTC, always an offset from UTC of zero. Any submitted offset or zone is used to adjust to UTC.
Details
Date type is 'timestamp-with-timezone'
No such type in standard SQL, nor in Postgres.
I’ll assume you meant TIMESTAMP WITH TIME ZONE.
it ends up as UTC (0 hours)
Read the fine manual. You are seeing documented behavior.
Postgres always stores values in a column of type TIMESTAMP WITH TIME ZONE in UTC, that is, with an offset of zero hours-minutes-seconds.
Any time zone or offset provided with an input is used to adjust into UTC. That provided zone or offset is then discarded.
So the name of the type TIMESTAMP WITH TIME ZONE is a misnomer. First, the authors of the SQL were thinking in terms of offset, not real time zones. Second, any submitted time zone is not stored. A submitted zone is used to adjust and then discarded.
If you need to track the original offset or zone, add an extra column. You’ll have to add code to store the offset amount or the time zone name.
update table set date = '2022-05-25 13:28+02:00' will end up as this in the database. 2022-05-25 11:28:00+00 What's wrong here?
Nothing is wrong. That is a feature, not a bug. Both of those strings represent the very same simultaneous moment.
FYI, database engines vary widely in their behavior handling date-time types and behaviors.
Some do as Postgres does regarding TIMESTAMP WITH TIME ZONE, adjusting to UTC and then discarding any provided time zone or offset. Some others may not.
The SQL standard barely touches on the topic of date-time handling. It declares a few types, and does that poorly with incomplete coverage of all cases. And the standard neglects to define behavior.
So, be very careful when it comes to date-time handling in your database work. Read very carefully the documentation for your particular database engine. Do not make assumptions. Run experiments to validate your understanding. And know that writing portable SQL code for date-time may not be feasible.

How do you return a timestamp from setTimezone function?

I want to be able to convert the current UTC time to a user's timezone, and get the value as a timestamp. Simple.
I seem to be having some difficulty though... this is what I've tried:
Carbon::now()->setTimezone('America/Los_Angeles'); // this works, but returns the time in the format "Y-m-d H:i:s"
So then I tried this:
Carbon::now()->setTimezone('America/Los_Angeles')->timestamp; // for some reason doing this seems to revert the timezone conversion and instead returns the timestamp for the current UTC time? :/
So, I'm using this workaround:
$converted_time = Carbon::now()->setTimezone('America/Los_Angeles');
return Carbon::createFromFormat('Y-m-d H:i:s', $converted_time)->timestamp;
...which gives me what I need, but seems unnecessary. Is there a better way to do this (in one line)?
Thanks.
The Unix Timestamp is per definition the number of second since 1st January 1970 UTC.
If you're trying to calculate the number of second since an other date (like 1st January in Los Angeles), you're calculating something else that is not Unix Timestamp.
To make sense, it's very important that the timestamp as a number would be a non-ambigus representation of a single second that can be used safely worldwide and still represent the same moment. If you have a number that can be different moment regarding from which timezone you're looking at it, you're likely not using the right tool, and would get more safety to store date-time + timezone.
So the very first question, is why would you need to get the number of second since 1st January in Los Angeles?
You can read more here about how to properly work with UTC and why to avoid having a strong dependence in your back-end with calculations in other timezones:
https://kylekatarnls.medium.com/always-use-utc-dates-and-times-8a8200ca3164

Datetime Offset Conversion in SQL

I’m working with a table that uses date time offset. I have a value that looks like 2020-01-02 13:30:00 -07:00.
Is the time in my time zone 13:30 or do I need to subtract 7 hours from it. I saw people do it differently on YouTube.
In MS SQLServer, the last section of the string representation that you posted of the DateTimeOffset describes the time zone. So, if you are currently located in time zone -7:00 (e.g., Arizona, USA), then the time portion of the string refers to your local time, not UTC. See the Microsoft documentation:
For example, 1999-12-12 12:30:30.12345 -07:00 should be represented [in UTC] as
1999-12-12 19:30:30.12345Z
Someone would subtract the offset from the number only if they want to manually get the UTC value, but that would might produce errors if the data come from a daylight saving time (DST) region, so you would need to enforce DST handling at the time of entry. SQLServer already stores the data in UTC behind the scenes:
The data is stored in the database and processed, compared, sorted,
and indexed in the server as in UTC.

Hibernate DST Date mapping issue for timestamps without time zone

I've a problem with storing java.util/sql.Date in PostgreSQL using hibernate: I'm storing dates as timestamp without time zone type. Now, in most cases everything is alright, as I'm mapping it in entities as java.util(sql).Date.
However, I encountered one problem I don't know how to overcome yet:
On March 30th there was a time change (Daylight Saving Time started). In my country it meant switching from local 2am to local 3am.
In my database I have few entries with times between 2 and 3 am, such as
"2014-03-30 02:15:55"
Now, what Java does is it takes this date and displays it as 3:15:55 am, because of the time change. However, I desperately need it to be 02:15:55, exactly how it's stored in the database (basically meaning don't use the +02:00 timezone BEFORE 3am, but use it AFTER). I'm afraid about 26th October as well, that's when the DST ends.
Is this possible using Hibernate and/or Spring? I'd love a global config for such case.
Best,
Marcin
You need to store dates in UTC timezone to ignore DST. See this question How to store date/time and timestamps in UTC time zone with JPA and Hibernate for solutions

Convert UTC date/time values to local time values in SQL Server and DB2

I would like to convert the date/time values stored in UTC-0 (GMT) to a user preferred time zone value by passing in the time zone (e.g EST, CST etc). However, SQL Server doesn't seem to have a method that takes in a time zone, but does honor the offset. I was wondering if any one had any luck doing so, so that the date/time value reflects the DST change, when a SQL query is issues against the table that contains these values. Oracle is the only database, that seems to honor the Time Zone as well as offset. Please advice.