2016-06-09 125 views
0

我想將RFC3339格式的DateTime傳遞給API,但由於格式不正確而不斷被拒絕。有沒有不同的方式來轉換爲正確的格式?DateTime到RFC3339格式化問題爲URL

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。

+0

我真的不知道,但因爲它是那麼容易去嘗試,我建議*不*調用'URI ::編碼'看看會發生什麼。 –

+1

請勿使用字符串插值/連接構造URI查詢參數。這種方式只有絕望和瘋狂。由於您使用的是HTTParty,因此您不需要 - 也不應該執行任何*手動編碼/轉義。使用':query'選項將查詢參數作爲哈希傳遞給'HTTParty.get'。 –

回答

2

正如我在上面的評論中所說的,通過嘗試自己對查詢參數進行編碼並使用插值/連接來構建URL,可能會讓事情變得非常困難。

我猜想,問題是,你正在使用URI.encode單獨使用CGI.escape,然後第二次集體編碼的查詢參數。換句話說,你要對它們進行雙重編碼。

順便說一下,CGI.escapeURI.encode做了同樣的事情,或多或少(前者是deprecated)。目前還不清楚你爲什麼同時使用這兩種方法,但這是不實際的,因爲你不應該使用它們。你應該讓HTTParty爲你做。

HTTParty.get一個基準網址,並通過: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) 
+0

感謝這個非常全面的答案,它完美的作品。 – Rilcon42