Is there a conventional timezone for API's? - api

We are working on an API that has an authentication header in which a timestamp has to be processed. Since we might need more use of timestamps in the future and want to be consistent in what timezone we use, I'd like to know if there is a conventional timezone for APIs. UTC+0 for example.
Thanks in advance

In some cases, you will find that HTTP headers (such as the standard Date header) is in RFC5322 format (aka RFC2822, RFC822). For example: Tue, 31 Jan 2017 17:45:00 GMT
In the Date header, the time zone abbreviation is always"GMT" (which is equivalent to UTC for this purpose), even though the RFC5322 format allows for other time zones.
The above format is not really preferred, it's just something we're stuck with. You can certainly use any format you wish for your own HTTP headers though.
A much better format is the RFC3339 format. This is similar to the ISO8601 extended format. An example is: 2017-01-31T17:45:00Z. The Z at the end indicates "Zulu" time, which is the same as GMT or UTC. However, you could also specify a time zone offset from UTC, such as the equivalent local time in the US Pacific time zone: 2017-01-31T09:45:00-08:00
If you have Unix time numbers like 1485884700, the time zone is always UTC. However, this is not a good interchange format because it is not human readable, and offers no context for what epoch or precision is being used. One would have to know those things externally. It is not a good fit for HTTP headers, nor XML or JSON.
If you are talking about the body of your XML/JSON requests, then you should only be using ISO8601. There are a few other formats that people use, but they are not recommended.
With regard to what time zone you should use - that's entirely dependent on context. If you are timestamping - where you take the current time and record it, then you can indeed just work with UTC. I would think for authorization purposes, this would be reasonable. You could also work in a local time, as long as you provided the offset from UTC along with it so there is no ambiguity.
However, you said (in comments) that your data contains information about job vacancies. That sounds to me like you are talking about time in the future - and that is an exception to the "always UTC" rule. Any time you are talking about time in the future, you need to express that in terms of local time, in the most direct form you can, and you also need to provide the identifier (not the offset) of the time zone that applies.
For example, if I am talking about a job vacancy, I might say in my data:
{
"job": "dishwasher",
"available: "2017-02-13",
"start": "08:00",
"end": "16:00",
"tz": "America/New_York"
}
These values would follow the ISO8601 format for date-only and time-only (or if I wanted to combine them 2017-02-13T08:00) - and would not have a time zone specified. Instead, the IANA time zone identifier America/New_York (for US Eastern Time) is provided in a separate field.
This matters because perhaps the job continues into future months. On March 12th, the US Eastern time zone will change from UTC-5 to UTC-4. Therefore, one cannot specify a single offset, nor can you use UTC.
Also, even for a single occurrence, keep in mind that some countries continue to change their minds about what their time zone and DST rules are, which is why there are dozens of updates to the tz database every year. If you were to calculate an offset for a date and time in the future, by the time it rolls around you might find the offset had been changed by the government.

Related

Does the SQL type TIME WITH TIMEZONE make sense?

While doing the mapping of some database columns into Java classes I stumbled onto this obscure SQL-92 Standard type (implemented by PostgreSQL, H2, and HyperSQL afaik). I haven't ever used it, but I wanted to understand how clearly map it to a Java type if I ever find it.
Here are the variants I can see:
Case A: The TIME type, such as 15:20:01. It's a "local time". The time zone is evident to the application so the database doesn't record it.
Case B: The TIME with offset, as in 15:20:01+04:00. It represents a "world time". This time can be converted trivially to UTC, or to any other world clock.
Case C: A TIME with a time zone, such as 15:20:01 EDT. Since the rules to interpret a time strongly depend on the specific date I can't really make any sense of it without the date; but then, if I add the date, it becomes a TIMESTAMP, and that's something totally different.
So, did the SQL Standard get it wrong? Or maybe "TIME with time zone" should be always interpreted as "time with offset" (case B)?
For lots of reasons, that you described well, interpreting a point in time with time of day and variable time zone but without a date is effectively undefined. There are use cases though, where you're establishing a policy within an international context this would be a helpful data type. Everyday at 15:20:01+04:00 the cats need to take a nap. Now the intention isn't to evaluate value in iosolation but within the context of adding it to a baseline date. Standards are all about supporting theoretical possibilities eaven if they're not super common.
Case C, a TIME with a time zone, such as 15:20:01 EDT, can be meaningful for things like store opening hours. Imagine you have a nationwide chain of stores. You want to store each store's standard opening hours in the database. The opening and closing time is a local time with an associated time zone. It isn't a time with a UTC offset (your case B), since it is defined in each store's local time zone, and hence daylight savings–or more rarely a change in the time zone definition–will change the UTC offset without actually changing the value of the opening time column. This store opens at 9am year round, but because its time zone has daylight savings, that is a different UTC offset at different times of year. But we aren't storing a date, because the standard opening/closing times are date-independent. (Maybe we'd have effective-from/effective-to dates, or similar, to track changes to standard opening hours over time.)
It isn't exactly case A, because imagine you have a table of stores, with opening_time and closing_time columns – if they are in different timezones, then case A would make those columns be a mix of data from different time zones, without being explicit about that. Now, given the poor support for case C in most databases, that's probably what happens – you'll probably store the time zone as an additional column. But Case C isn't useless in principle, unlike what many people think.

Trying to reformat timestamp in postgresql

I can't seem to find a question/answer that works for what I'm trying to achieve. Currently, this is how my DB outputs a timestamp:
2015-08-18T19:43:04.738-06:00
However, I would like it to appear as such in the column:
2015-08-18T19:43:04.738 America/Denver
Google has recently changed their formatting options and instead of downloading the output and performing a find/replace, I want an output that doesn't require additional work. I looked on SO and have tried using trim and replace but having no luck.
Thanks for the help in advance!
For whatever reason, the one we've used since February (third from the bottom) no longer works.
2015-08-18T19:43:04.738-06:00 is not quite the right format. Google does not accept milliseconds (which is annoying if they don't just ignore it). You need to send 2015-08-18T19:43:04-06:00. They may have become more strict in what they accept.
Try date_trunc('second', yourtime).
It's not possible to accurately translate an offset like -0600 to a time zone like America/Denver. They say two different things.
-0600 says, with absolute certainty, that this time is 6 hours behind UTC. 12:00:00-06:00 and 18:00:00Z (Z represents UTC) are the same time.
America/Denver means to interpret this timestamp under the rules applicable to the city of Denver, Colorado, USA at that time. To figure out what time it is in UTC you need to look up the offset rules for Denver, Colorado, USA. The offset will change depending on the time of year, usually because of daylight savings time. Because the rules change, it's important to apply the rules as they were at that time.
For example, 2006-03-15 12:00 America/Denver is -0700. But the next year on 2007-03-15 12:00 America/Denver is -0600. Between 2006 and 2007 the daylight savings time rules in the US changed.
Whereas -06:00 avoids all that and simply says the time is offset from UTC by six hours.
You could fake it by simply replacing the offset with America/Denver. So long as you're only sending recent times that should work. You'll be off by at most an hour. But don't do that.
Unless Google Ads specifically needs a time zone there's no point in sending them one. Internally, Postgres is storing your times in UTC anyway and translating them to your server's time zone, America/Denver. Send Google UTC. And, as noted above, chop off the milliseconds.
select date_trunc('second', '2015-08-18T19:43:04.738-06:00'::timestamp with time zone at time zone 'UTC') as datetime;
datetime
---------------------
2015-08-19 01:43:04

Is there a more elegant way to convert this time to my server's local time?

I have a string in the following format:
14:41:21 Dec 15, 2015 PST
I want to convert that to my server's local time, but I think I'm creating an extra step that can be avoided:
Dim testdate As Date
DateTime.TryParseExact(dateinput, "HH:mm:ss MMM dd, yyyy PST", CultureInfo.InvariantCulture, DateTimeStyles.None, testdate)
testdate = TimeZoneInfo.ConvertTimeToUtc(testdate, TimeZoneInfo.FindSystemTimeZoneById("Pacific Standard Time"))
testdate = testdate.ToLocalTime()
I've played around with this but always off by a couple hours either way, and the above is what I've found to work but just wanted to know if there was a better way. Also note it could be deployed on multiple servers, so I don't want to specify the timezone to convert it to explicitly, reason for localtime.
A few things:
If you're going to include fixed text in a format string, put it in single-tick quotes so it can't get misinterpreted as a formatting token. ('PST')
In the general case, time zone abbreviations should only be used for display purposes. They should not be parsed as input, as they could be ambiguous. For example, there are 5 different interpretations of CST. It might be US Central Standard Time, but it could also be China Standard Time, or one of the others. See the list on Wikipedia.
If you have a limited number of time zone abbreviations you want to support, then you could extract it from the string and use a dictionary, select/case statements, or conditional logic to map them. Just be certain you know the entire set of abbreviations you want to support and exactly which time zones you want them to map to. Also be sure to account for daylight time abbreviations, such as PDT.
Note that some older standards, such as RFC 2822 §4.3 indeed hardcode a few abbreviations, so you may choose to support those if you are parsing that particular format. (Yours is similar, but not quite a match.)
Your code is mostly ok, but you should probably check the result of TryParseExact. Otherwise you might as well use ParseExact which will throw an exception on failure instead of just returning false.
You could use ConvertTime with TimeZoneInfo.Local as the destination zone if you wanted to do the conversion in a single step. The code would be slightly smaller, though would have no technical differences.
Are you sure you really want to do this? Relying on the system's local time zone should usually should not be done in server-based applications. That's something more appropriate for desktop and mobile. In general, server-side code should not rely on the system time zone to be anything in particular. Avoid "local time" APIs, including DateTime.Now, TimeZoneInfo.Local, ToLocalTime, and ToUniversalTime (when it assumes the input is local time). It is better to supply the applicable time zone in your business logic or application configuration.

Is there a way to get the user-preference Time Zone value from the Dwolla API?

The Dwolla transaction "Date" field apparently uses this value for generating a timestamp, but I don't see any way to get the "Time Zone" preference from the API?
Zooming out, I'm trying to get the definitive/comparable date for a transaction, but I need to know the timezone of the date string.
While this method doesn't state what the time zone is, others like this one make it clear that the dates are in UTC, so I would guess that all dates are in UTC throughout the API.
The only thing I don't like about their API is they are showing example dates like:
"Date": "8/31/2011 10:19:09 AM"
It's not very smart of them to use M/D/YYYY format, nor to use a 12-hour clock. This is better represented by "2011-08-31T10:19:09Z", which is in ISO format and indicates UTC. If you ever get a chance to speak with them, you should recommend they use this format (ISO-8601).
Just be aware of this when you are parsing it, since the format they are using may or may not be the correct format for your current culture.
Dwolla are making the change to the ISO timestamp on August 4th 2014
This change will be rolled out in 60 days from today, on 9:00 AM CT August 4th, 2014. If you need help making adjustments to your code to parse the new datetime format, let us know and we'll be glad to lend a hand.
https://discuss.dwolla.com/t/api-update-new-timestamp-format-for-clearingdate-parameter/401

How to convert a unix timestamp (INT) to monetdb timestamp ('YYYY-MM-DD HH:MM:SS') local time format

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.