How to document "Retry-After" HTTP-Date format in OpenAPI? - swagger

Trying to document a response header of Retry-After in HTTP-Date format in OpenAPI (as described here and here).
Also here you can find the syntax which is in use: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Date
Syntax:
Date: <day-name>, <day> <month> <year> <hour>:<minute>:<second> GMT
My question is what is the best way to describe this header and which format is the correct one when using OpenAPI 3?
date/date-time/http-date?

OpenAPI and JSON Schema do not have a built-in format for dates in this format. However, format is an open-valued keyword so you can specify any value you like, such as format: http-date or even
format: <day-name>, <day> <month> <year> <hour>:<minute>:<second> GMT
Tools that don't recognize the given format value will ignore it and use just the type.
That said, I suggest that you use type: string without format and optionally provide an example value. Or you can make it oneOf of string and integer to reflect the alternative format Retry-After: 120. (However, a simple type: string also works in this case.)
Example using type: string:
responses:
'429':
description: Rate limit exceeded
headers:
Retry-After:
description: Indicates how long the client should wait before making a follow-up request.
schema:
type: string
# example: 'Wed, 21 Oct 2022 07:28:00 GMT'
# optionally add examples for both date and delay-seconds
examples:
http-date:
value: 'Wed, 21 Oct 2022 07:28:00 GMT'
delay-seconds:
value: '120'
Example using type: string + type: integer:
schema:
oneOf:
- type: string
example: 'Wed, 21 Oct 2022 07:28:00 GMT'
description: A date after which to retry.
- type: integer
minimum: 0
example: 120
description: The seconds to delay after the response is received.

Related

How to define double data type in OpenAPI (Swagger)?

For integers, I use
userId:
type: integer
format: int32
But what if I want to assign the double type?
I tried looking through Swagger documentation but couldn't find the answer.
We can write as
userId:
type: number
format: double

Why can't go parse the time represented by the provided formats?

Consider this example:
package main
import (
"fmt"
"time"
)
func main() {
fmt.Println(time.Parse(time.RFC3339, time.RFC3339))
}
The output is:
0001-01-01 00:00:00 +0000 UTC parsing time "2006-01-02T15:04:05Z07:00": extra text: 07:00
Why can't time.Parse() handle a layout as a value? What's missing here?
UPDATE: Cutting off the time zone value (but not the 'Z' delimiting the time from the zone) fixes it:
fmt.Println(time.Parse(time.RFC3339, "2015-09-15T11:50:00Z"))
Why can't time.Parse() handle time zone info when using time.RFC3339 as the layout string?
http://play.golang.org/p/p3fHfJNHVK
UPDATE: JimB's answer led me to read from RFC3339 and I found these examples that clarify further:
Here are some examples of Internet date/time format.
1985-04-12T23:20:50.52Z
This represents 20 minutes and 50.52 seconds after the 23rd hour of
April 12th, 1985 in UTC.
1996-12-19T16:39:57-08:00
This represents 39 minutes and 57 seconds after the 16th hour of
December 19th, 1996 with an offset of -08:00 from UTC (Pacific
Standard Time). Note that this is equivalent to 1996-12-20T00:39:57Z
in UTC.
The time.RFC3339 format is a case where the format string itself isn't a valid time. You can't have a Z and an offset in the time string, but the format string has both because the spec can contain either type of timezone specification.
Both of these are valid RFC3339 times:
"2015-09-15T14:00:12-00:00"
"2015-09-15T14:00:13Z"
And the time package needs to be able to parse them both using the same RFC3339 format string.
As noted, 2006-01-02T15:04:05Z07:00 is an invalid IETF RFC-3339 time format. Here's an explanation.
The reason you cannot have both Z and an offset is that they are both ways to represent a time offset. Z is equivalent to +00:00 indicating a zero hour/minute offset, or no offset. You cannot say both +00:00 offset and +07:00 offset in the same time representation.
The following is the Z definition in the RFC-3339 Section 2:
https://www.rfc-editor.org/rfc/rfc3339#section-2
Z A suffix which, when applied to a time, denotes a UTC
offset of 00:00; often spoken "Zulu" from the ICAO
phonetic alphabet representation of the letter "Z".
Of note, while Z is equivalent to +00:00, they are both different from -00:00 which indicates known UTC time with an unknown offset, as described in RFC-3339 Section 4.3:
https://www.rfc-editor.org/rfc/rfc3339#section-4.3
4.3. Unknown Local Offset Convention
If the time in UTC is known, but the offset to local time is unknown,
this can be represented with an offset of "-00:00". This differs
semantically from an offset of "Z" or "+00:00", which imply that UTC
is the preferred reference point for the specified time. RFC2822
[IMAIL-UPDATE] describes a similar convention for email.

Change Format Date From "Fri, 18 Jul 2014" to 7/18/14 Rails

I am parsing an xls file and it has changed all my dates to this format "Fri, 18 Jul 2014" and i need it back to this format "7/18/2014" or to "2014-07-18 17:00:00"
I have tried to use Chronic.parse() with no luck
You would first need to use Date.parse to turn your string into a Date object and then use Date#strftime.
Date.parse("Fri, 18 Jul 2014").strftime("%m/%d/%Y")
A good website for playing around with the different formatting options is:
http://www.foragoodstrftime.com/
You also have the localize() method of I18n (a Rails' guide of Internationalization):
I18n.localize(Date.current)
Uses the format defined for the current language in:
date:
formats:
default: "%Y-%m-%d"
short: "%b %d"
long: "%B %d, %Y"
# other formats' usage:
I18n.localize(Date.current, format: :long)
.localize has the same shorthand as .translate:
# in your views, you can simply do
Post's was created on <%= l(post.created_at, format: :long) %>
This method is very usefull since it relies on the end-user's language and can be easily changed. There is tons of helpers helping you dealing with Language AND dates (datetimes):
http://apidock.com/rails/ActionView/Helpers/DateHelper/distance_of_time_in_words
http://apidock.com/rails/v4.0.2/ActionView/Helpers/DateHelper/time_ago_in_words
All using I18n translation system in order to follow each language's specification/translation.

How do I parse a translated date in Ruby on Rails?

I have configured an application in Ruby on Rails with translations to Spanish.
Now I need to parse a translated date, for example:
Jueves, 22 de Noviembre del 2012
I'm trying to do it this way:
Date.strptime('Jueves, 22 de Noviembre, 2012', '%A, %e de %B, %Y')
But it throws an invalid date error.
How can I do it?
Date::parse should understand Spanish. However, that de seems to throw the parser off. If you could get it into this format, this will work
Date.parse "Jueves, 22 Noviembre, 2012"
=> Thu, 22 Nov 2012
I had a very similar problem and I wrote a gem specifically for the purpose of parsing any non-English textual dates (that use Gregorian calendar), it's called Quando.
The gem readme is very informative and has code examples, but in short, this is how it works:
require 'quando'
Quando.configure do |c|
# First, tell the library how to identify Spanish months in your dates:
c.jan = /enero/i
c.feb = /febrero/i
c.mar = /marzo/i
c.apr = /abril/i
c.may = /mayo/i
c.jun = /junio/i
c.jul = /julio/i
c.aug = /agosto/i
c.sep = /septiembre/i
c.oct = /octubre/i
c.nov = /noviembre/i
c.dec = /diciembre/i
# Then, define pattern matchers for different date variations that you need to parse.
# c.day is a predefined regexp that matches numbers from 1 to 31;
# c.month_txt is a regexp that combines all month names that you previously defined;
# c.year is a predefined regexp that matches 4-digit numbers;
# c.dlm matches date parts separators, like . , - / etc. See readme for more information.
c.formats = [
/#{c.day} \s #{c.month_txt} ,\s #{c.year} $/xi, # matches "22 Mayo, 2012" or similar
/#{c.year} - #{c.month_txt} - #{c.day}/xi, # matches "2012-Mayo-22" or similar
# Add more matchers as needed. The higher in the order take preference.
]
end
# Then parse the date:
Quando.parse('Jueves, 22 Noviembre, 2012') # => #<Date: 2012-11-22 …>
You can redefine the matchers for date parts and formats partially or entirely, both globally or just for a single parser instance (to preserve your global settings), and use all the power of regular expressions.
There are more examples in the readme and in the source code. Hope you'll find the library useful.
So, the answer is: it's not possible, at least right now.
The only way to have it working, is by using javascript on the client side, and convert the format to another one before sending the field to the server. Then Rails will not have any problem parsing it.

How can I parse a non-ISO8601 timestamp to format as ISO8601 in XSLT?

If I have a document in XSLT containing timestamps in some known format, how can I parse these timestamps in the template so that I can then format them in say ISO8601?
Example formats:
UNIX epoch millis
yyMMddHHmmssZ (Using Java SimpleDateFormat format string)
Is there a difference in how to do this in XSLT 1.0 vs. 2.0?
With XSLT 2.0 you have date and dateTime data types to compute dates, for instance to convert a UNIX epoch milliseconds value since 1970 to dateTime see http://p2p.wrox.com/xslt/79802-convert-format-unix-timestamp.html, you can do e.g. xs:dateTime('1970-01-01T00:00:00') + $N * xs:dayTimeDuration('PT0.001S'). Then you can format such a dateTime with the function format-dateTime http://www.w3.org/TR/xslt20/#format-date.

Resources