2013-01-10 23 views
0

我遇到了這個問題:我從各種網頁獲取RSS源,然後我需要按日期排序。我使用xquery進行xml操作和eXist數據庫來存儲rss/xml。 這是我的代碼:如何使用xquery從xml比較GMT和EST時間

for $item in subsequence(collection('/db/bla/user/feed')//item[contains(title, $search)], $start, $num) 
       let $title:= $item/title/text() 
       let $desc:= $item/description/text() 
       let $link := $item/link/text() 
       let $date:= $item/pubDate/text() 
       order by $date 

這是行不通的。而且我認爲問題出現在格林尼治標準時間和東部標準時間的不同時間,所以按日期排序並不適用。 請幫助,我卡在這裏。

在此先感謝!

編輯:

這裏是日期和時間的格式i。從pubdate的標籤抓取:

Mon, 10 Dec 2012 13:32:24 EST 

Mon, 10 Dec 2012 13:32:24 GMT 
+0

看起來你需要解析dateTime。幾個API具有內置的這些類型的函數:MarkLogic,Java,.NET等,因此您必須決定是否要在XQuery之外解析dateTime或在XQuery中從頭開始編寫dateTime,在這種情況下應該可能是一個不同的問題。 – wst

+0

您使用的是什麼版本? –

+0

@Ranon我可以使用版本3.0和版本1.0,因爲兩個版本都支持eXist數據庫版本2.0我認爲...現在我使用1.0來滿足我的需求 – user1598696

回答

2

嘗試鑄造$date作爲一個實際的日期/時間:

let $date:= xs:dateTime($item/pubDate/text()) 

如果日期的格式/時間是一致的,你可以實現自己的轉換器。在您評論的例子中,會給您帶來最多問題的兩個部分是月份和時區。該月需要爲數字,您需要將時區轉換爲等效的UTC偏移量。

下面是一個例子:

declare variable $months := ('jan','feb','mar','apr','may','jun','jul','aug','sep','oct','nov','dec'); 
declare variable $timezoneMap := 
    <map> 
     <tz> 
      <numeric>-05:00</numeric> 
      <alpha>est</alpha> 
     </tz> 
    </map>; 

declare function local:formatDate($origdate as xs:string) as xs:dateTime { 
    let $dateTokens := tokenize($origdate,' ') 
    let $timezone := $timezoneMap/tz[lower-case($dateTokens[6])=alpha]/numeric/text() 
    let $month := string(index-of($months,lower-case($dateTokens[3]))) 
    let $newDate := concat($dateTokens[4],'-',if (string-length($month)=1) then concat('0',$month) else $month,'-',$dateTokens[2], 
          'T',$dateTokens[5],$timezone) 
    return 
     xs:dateTime($newDate) 
}; 

然後,您可以使用這樣的功能:

let $date:= local:formatDate($item/pubDate) 

另外,如果你使用XQuery 3.0,你可以使用maps的時區和月:

declare namespace map = "http://www.w3.org/2005/xpath-functions/map"; 
declare variable $months := map{"jan":="01","feb":="02","mar":="03","apr":="04","may":="05","jun":="06", 
           "jul":="07","aug":="08","sep":="09","oct":="10","nov":="11","dec":="12"}; 
declare variable $timezoneMap := map{"est":="-05:00"}; 

declare function local:formatDate($origdate as xs:string) as xs:dateTime { 
    let $dateTokens := tokenize($origdate,' ') 
    let $newDate := concat($dateTokens[4],'-',$months(lower-case($dateTokens[3])),'-',$dateTokens[2], 
          'T',$dateTokens[5],$timezoneMap(lower-case($dateTokens[6]))) 
    return 
     xs:dateTime($newDate) 
}; 
+0

感謝您的幫助。但它不起作用。我得到這個例外: .... 錯誤:FORG0001:非法的詞法形式爲日期時間值'星期一,2012年12月10日13:32:24 EST'星期一,2012年12月10日13:32: 24美國東部時間 user1598696

+0

啊啊是啊,這不是一個XS:日期時間。 –

+0

任何其他想法? – user1598696

1

在XQuery中構建一些日期格式解析器可能不是最好的理念;你將不得不自己處理所有時區轉換的東西(更糟的是:夏令時...)。

官方方式:日期時間,模塊

eXist的DB具有基於java.text.SimpleDateFormat其自身的DateTime-模塊。該模塊在使用前必須編譯和激活,並且不包含在eXists當前的穩定版本中(但在1.4.3開發人員版本和版本2預發行版中)。

買者,它使用系統的默認語言環境,這在我的情況不是英語(這樣認識的日期慘敗)。

如果你設法實現它(如果你不這樣做,這可能是上Database Administrator,一個SO姊妹網站另一個問題),你應該能夠運行這段代碼的格式解析日期給出:

import module namespace datetime = "http://exist-db.org/xquery/datetime"; 
datetime:parse-dateTime('Mon, 10 Dec 2012 13:32:24 GMT', 'EEE, d MMM yyyy HH:mm:ss Z') 

的骯髒的黑客:接口技術的Java

如果您運行期存在之一些舊版本或者不能使用該模塊其他原因,你可以激活Java綁定在conf.xml和直接調用這個函數:

declare namespace sdtf="java:java.text.SimpleDateFormat"; 
declare namespace date="java:java.util.Date"; 

(: Parse given date format to java date :)  
let $parse := sdtf:new('EEE, d MMM yyyy HH:mm:ss Z') 
(: Output as close to XQuery's xs:dateTime as possible :) 
let $format := sdtf:new("yyyy-MM-dd'T'HH:mm:ss.SSSZ") 
let $javadate := sdtf:parse($parse, 'Mon, 10 Dec 2012 13:32:24 GMT') 
(: Use regex to insert missing ':' and finally cast to xs:dateTime :) 
return xs:dateTime(fn:replace(sdtf:format($format, $javadate), '(.*)(\d{2})', '$1:$2')) 

再次提醒,如果java語言環境不是默認設置,請記得將其設置爲英文。

我想這應該在至少Saxon(定義了這個java綁定)和BaseX(我在這裏實際測試過)中運行正常。

1

您可以使用Ryan Grimm的基於XQuery的日期解析器模塊。它是爲MarkLogic而設計的,但小修改也可以在其他系統上工作。見https://github.com/marklogic/commons/blob/master/dates/date-parser.xqy

正如模塊狀態的說明,其支持的日期格式:

  1. 二零零六年六月三十日09:39:08 -0500
  2. 4月16日13時49分06秒2003 +0200
  3. 年8月4 11時44分58秒EDT 2003
  4. 98年1月4日0:41 EDT
  5. 10月25日 - 2004年17點06分46秒-0500
  6. 週一,09月23日0102 23點十四分26秒0900