Skip to content

Instantly share code, notes, and snippets.

@line-o
Last active June 19, 2019 13:27
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save line-o/13c8224f7fa8938f80b6a640da134eeb to your computer and use it in GitHub Desktop.
Save line-o/13c8224f7fa8938f80b6a640da134eeb to your computer and use it in GitHub Desktop.
xquery implementation to format dateTime in Internet Message Format

IMFD/IETF date helper module

This is an xquery module for parsing datestrings in Internet Message Format (or IETF-Dates) to datetimes. There is a function defined in the xquery 3.1 spec fn:parse-ietf-date which effectively replaces imfd:to-dateTime if implemented.

This module also supports formatting xs:dateTime to this format.

xquery version "3.1";
import module namespace imfd='http://existsolutions.com/apps/imfd' at '/db/temp/imfd.xqm';
let $now := current-dateTime()
let $tz := timezone-from-dateTime($now)
let $imfd := imfd:format($now)
let $gmt := imfd:to-dateTime($imfd)
let $reversed := adjust-dateTime-to-timezone($gmt + $tz, $tz)
return (
$now,
$imfd,
$gmt,
$reversed
)
xquery version "3.1";
(:~
convert xs:dateTime to IMF-fixdate format and back
This format is a fixed-length and single-zone subset of the date and time
specification used by the Internet Message Format [RFC5322].
HTTP-date = IMF-fixdate / obs-date
An example of the preferred format is
Sun, 06 Nov 1994 08:49:37 GMT ; IMF-fixdate
@author Juri Leino <juri@existsolutions.com>
~:)
module namespace imfd='http://existsolutions.com/apps/ib/imfd';
declare variable $imfd:month-map := 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
function imfd:gmt ($date as xs:dateTime) as xs:dateTime {
adjust-dateTime-to-timezone($date, xs:dayTimeDuration('PT0H'))
};
declare
function imfd:format ($date as xs:dateTime) as xs:string {
$date
=> imfd:gmt()
=> format-dateTime("[FNn,3-3], [D01] [MNn,3-3] [Y04] [H01]:[m01]:[s01] GMT")
};
(:~
implements a subset of fn:parse-ietf-date()
parses only IMF-fixdate
:)
declare
function imfd:to-dateTime ($imf-date as xs:string?) as xs:dateTime {
if (empty($imf-date))
then (xs:dateTime('1970-01-01T00:00:00'))
else (
let $parts := tokenize(substring-after($imf-date, ', '), ' ')
let $day := $parts[1]
let $month := $imfd:month-map($parts[2])
let $year := $parts[3]
let $time := $parts[4]
(: $parts[5] MUST be GMT :)
return xs:dateTime(``[`{$year}`-`{$month}`-`{$day}`T`{$time}`Z]``)
)
};
xquery version "3.1";
import module namespace imfd='http://existsolutions.com/apps/imfd' at '/db/temp/imfd.xqm';
(
"1970-01-01T00:00:00.000+00:00",
"1970-01-02T00:00:00.000+00:00",
"1970-01-03T00:00:00.000+00:00",
"1970-01-04T00:00:00.000+00:00",
"1970-01-05T00:00:00.000+00:00",
"1970-01-06T00:00:00.000+00:00",
"1970-01-07T00:00:00.000+00:00",
"1970-02-08T00:00:00.000+00:00",
"1970-03-08T00:00:00.000+00:00",
"1970-04-08T00:00:00.000+00:00",
"1970-05-08T00:00:00.000+00:00",
"1970-06-08T00:00:00.000+00:00",
"1970-07-08T00:00:00.000+00:00",
"1970-08-08T00:00:00.000+00:00",
"1970-09-09T00:00:00.000+00:00",
"1970-10-10T00:00:00.000+00:00",
"1970-11-11T00:00:00.000+00:00",
"1970-12-12T00:00:00.000+00:00",
"1970-12-12T00:00:00.000+08:00",
"1970-12-12T00:00:00.000+01:30",
"1970-12-12T00:00:00.000-07:00",
current-dateTime()
)
=> for-each(xs:dateTime(?))
=> for-each(imfd:format(?))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment