If part of the data that RestKit gets from my server is a timestamp formatted as 2013-05-27 20:32:26 UTC, and later I want to find out the difference between the current time and this date, I do
NSTimeInterval difference = [[NSDate date] timeIntervalSinceDate:dateFromRestKit];
But this always seems to be off for me by 1 hour, and I'm guessing this is because I'm on BST, which is UTC+1. So I think that RestKit is ignoring the timezone specified in the date string, and is instead parsing the date using the current system timezone.
I understand that there may be some technical reason it ignores the time zone, but I found all this time stuff really difficult to get my ahead around so I'm not sure.
How can I work out the correct difference between the times?
Even if your timestamp contains the UTC format , try to specify the timezone for it again.
If you want the resulting difference of two date timezone in 'UTC' then , convert the other one in UTC format and then find the time Interval.
Do let me know , if any query. Or if possible , post your code , to get more clear about your question. (:
Related
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.
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.
I want to present a date to the user in the dates own timezone. So without it being converted to the users timezone.
Basically what happens: I retrieve a string '2015-04-01T15:35:00-04:00' from the backend, and I convert it to a NSDate. Later on I want to show the user the time: 15:35.
But NSDateFormatter converts the date to my system time zone (+02:00) which results in showing 21:35.
I've searched all over the internet to find out I can skip this convert, but I can't find anything.
What do I miss?
Help is really appreciated.
You will have to save the original timezone in addition to the NSDate representation and use it when you want to present the time in the original timezone.
NSDate keeps the date/time relative to GMT (UTC).
Q1: I want to convert a unix timestamp (INT) to monetdb timestamp ('YYYY-MM-DD HH:MM:SS') format
but it is giving me the GMT time not my actual time.
When I do
select (epoch(cast(current_timestamp as timestamp))-epoch(timestamp '2013-04-25 11:49:00'))
where 2013-04-25 11:49:00 is my systems current time it gives the same difference
I tried using
set time zone interval '05:30' HOUR TO MINUTE;
but it did not change the result
How can I solve this problem??
Example Problem:
I wanted to convert unix timestamp 1366869289 which should be around "2013-04-25 11:25:00" but monetdb gives "2013-04-25 05:55:00"
Knowing nothing about MonetDB, but a lot about timezones, I decided to look in their documentation to see what kind of datatypes are supported and how conversions are handled.
I found this page on Temporal data types. Based on that, I can conclude that a timestamp in MonetDB is always intended to reference UTC/GMT time - which is consistent with other systems.
In order to get a value that is for a particular time zone, they offer the following example:
SET TIME ZONE INTERVAL '1' HOUR TO MINUTE
I assume this means to set the database to offset all times by 1 hour, effectively placing the values all in UTC+01:00, such as is the offset for British Summer Time.
The page also goes on to point out the problems that can arise with using just and offset to adjust time values (see TimeZone != Offset in the TimeZone tag wiki). It also offers a list of various named time zones. But it does not show how to set a time zone to one of the named values. Also, their list appears to be proprietary, and incomplete. While at first glance they appear to have similarities to the IANA/Olson time zone database - the identifiers they specify are not valid TZDB names.
There are some other functions listed on this page, without much explanation. One that looks promising for your needs is LOCALTIMESTAMP. Perhaps this will take the local time zone into account, which appears to be what you were looking for.
I could not find any additional details specific to MonetDB date/time/timezone handling. The documentation appears to be fairly incomplete. You might want to reach out to their mailing list.
This should be really simple, but I'm having an embarrassing amount of trouble with it.
In PostgreSQL 9.1, I need to intepret a field stored as a DATE in the DB as if it were a TIMESTAMPTZ representing midnight UTC on that date. I'd like to do it in a clean and readable way that someone can come along, look at, and understand what's happening.
The only ways I've found to do it so far are both very ugly. One converts it to a TIMESTAMP WITHOUT TIME ZONE then creates a TIMESTAMP WITH TIME ZONE from it by interpreting it as if it were UTC:
SELECT CAST(DATE '2012-01-01' AS TIMESTAMP WITHOUT TIME ZONE) AT TIME ZONE 'utc'
The other way is worse:
('2012-01-01'::date)::timestamptz - (current_timestamp AT TIME ZONE 'UTC' - current_timestamp)
in that it converts the date to a timestamp for midnight local time, then subtracts the time zone offset. I couldn't find any way to get that offset as an interval natively (which seems crazy) so I landed up getting it by comparing current_timestamp in local time with current_timestamp in UTC.
The only other way I could work out used extract to get the date parts and assembled a new timestamptz from them. I won't even show that one, it's too ugly.
Both approaches feel all kinds of weird and wrong. Is there any sane way - standard or no - to convert in a readable and easily understood way from a DATE to a timestamptz of midnight UTC on that date?
I'm looking for something like (imaginary, won't work)
'2012-01-01'::date AS TIMESTAMPTZ IN TIME ZONE '00:00';
or
to_timestamp('2012-01-01'::date, '00:00'::time, 'UTC');
Please point out the stupidly obvious thing I'm missing.
Note that I'm testing to make sure the date is truly right internally, not just at display, with extract(epoch from $1) where $1 is the converted date.
Your first approach is correct. And it's not that ugly, is it? In simplified Postgres syntax:
SELECT '2012-1-1'::date::timestamp AT TIME ZONE 'UTC';
Applied to a variable or column it looks even more elegant:
SELECT mydate::timestamp AT TIME ZONE 'UTC';
If you are going to enter the date manually, you can shortcut to:
SELECT '2012-1-1 0:0'::timestamp AT TIME ZONE 'UTC'
The result will always be displayed according to the local timezone of the client (i.e. with the according offset), but that has no influence on the value.
Note: I don't know much about PSQL, but I've some experience with date/time matters.
Your first way feels right to me. You're effectively going from "local date" to "local date/time" to "date/time in a particular time zone". Those are all reasonable steps, and ones I'd expect to see in normal date/time APIs.
This approach never introduces the system default time zone as far as I can tell, which is a thoroughly good thing. It performs one logical step at a time, assuming that the cast the sensible thing.
You don't need to worry about the local date/time being either ambiguous or missing in the target time zone, as UTC doesn't have any DST transitions.
Basically, it looks fine. If it works and performs as well as you need it to, I'd stick with it.