我正在尝试将RFC3339格式的日期时间传递给API,但由于格式不正确而被拒绝。有没有其他方法可以转换为正确的格式?
require 'cgi'
require 'date'
require 'uri'
startTime=CGI.escape(DateTime.new(2016, 6, 6, 15, 47, 40).strftime("%Y-%m-%dT%H:%M:%SZ"))
endTime=CGI.escape(DateTime.now.strftime("%Y-%m-%dT%H:%M:%SZ"))
puts startTime #start=2014-06-19T15%3A47%3A40Z me:2016-05-19T16%3A47%3A04-04%3A00
puts endTime
hist_data=getData(startTime,endTime)
def getData(startTime,endTime)
base="https://api-fxtrade.oanda.com/v1/candles?instrument="
curr="EUR_USD"
granularity="H1"
#https://api-fxtrade.oanda.com/v1/candles?instrument=EUR_USD&start=2014-06-19T15%3A47%3A40Z&end=2014-06-19T15%3A47%3A50Z
myurl = "#{ base }#{ curr }&candleFormat=bidask&granularity=#{ granularity }&dailyAlignment=0&alignmentTimezone=America%2FNew_York&start=#{startTime}&end=#{endTime}"
puts myurl
response =HTTParty.get(URI::encode(myurl))
#{"time"=>"2016-06-03T20:00:00.000000Z", "openBid"=>1.1355, "openAsk"=>1.13564, "highBid"=>1.13727, "highAsk"=>1.13752, "lowBid"=>1.13541, "lowAsk"=>1.13554, "closeBid"=>1.13651, "closeAsk"=>1.13684, "volume"=>2523, "complete"=>true}
response
end
但是,当我使用此代码时,结束网站 URL 是有效的。我的代码的完整输出给出:
https://api-fxtrade.oanda.com/v1/candles?instrument=EUR_USD&candleFormat=bidask&granularity=H1&dailyAlignment=0&alignmentTimezone=America%2FNew_York&start=2016-06-06T15%3A47%3A40Z&end=2016-06-08T21%3A53%3A44Z
知道为什么它在运行该方法时不起作用,但在我只是粘贴 URL 时有效吗?我认为这是一个编码问题,但我肯定在方法中对 URL 进行编码。
正如我在上面的评论中所说,通过尝试自己对查询参数进行编码并使用插值/串联来构建 URL,您自己会让事情变得非常困难。
我猜问题是您使用CGI.escape
单独编码查询参数,然后使用 URI.encode
第二次集体编码。换句话说,您正在对它们进行双重编码。
顺便说一下,CGI.escape
和URI.encode
或多或少地做同样的事情(前者已被弃用)。目前尚不清楚为什么同时使用两者,但这没有实际意义,因为您不应该使用两者。你应该让HTTParty为你做这件事。
HTTParty.get
提供一个基本 URL,并使用 :query
选项向其传递您的(原始,即未编码)查询参数的哈希值,它将为您正确完成所有编码。作为副作用,它可以编写更干净的代码:
require "httparty"
require "date"
DATETIME_FMT = "%FT%TZ" # RFC 3339
BASE_URI = "https://api-fxtrade.oanda.com/v1/candles"
DEFAULT_PARAMS = {
instrument: "EUR_USD",
candleFormat: "bidask",
granularity: "H1",
dailyAlignment: 0,
alignmentTimezone: "America/New_York",
}.freeze
def get_data(start_time, end_time)
params = DEFAULT_PARAMS.merge(
start: start_time.strftime(DATETIME_FMT),
end: end_time.strftime(DATETIME_FMT)
)
HTTParty.get(BASE_URI, query: params)
end
start_time = DateTime.new(2016, 6, 6, 15, 47, 40)
end_time = DateTime.now
hist_data = get_data(start_time, end_time)