ruby - DateTime 到 RFC3339 格式化问题作为 URL

标签 ruby datetime

我试图将 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

但是当我使用此代码时,结束网站网址是有效的。我的代码的完整输出如下:

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 再次整体编码。编码。换句话说,您对它们进行了双重编码。

顺便说一句, CGI.escapeURI.encode 或多或少做了同样的事情(前者是 deprecated )。目前尚不清楚为什么要同时使用两者,但这是没有意义的,因为你不应该使用其中任何一个。您应该让 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)

关于ruby - DateTime 到 RFC3339 格式化问题作为 URL,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37715708/

相关文章:

c# - 使用 Linq 按日期获取数据

javascript - 为应用程序脚本触发器设置本地日期时间

date - 将 “Fri Apr 29 06:01:46 EDT 2016”转换为HIVE中的日期格式?

ruby - 如何在不访问HTTP层的情况下模拟浏览器X509客户端证书验证

ruby - Gem::InstallError: nokogiri 要求 Ruby 版本 >= 1.9.2

ruby-on-rails - 所有 gem 命令都会失败并出现 "cannot load such file"错误

sql - ruby 外部化 SQL 模块

python - 如何在 Pandas 中创建一个 mm-yyyy 列?

mysql - MySQL日期时间自动发送邮件

ruby - 无法从 Cucumber 2.3.2 中的 scene.file 获取场景的文件名