Skip to content

Instantly share code, notes, and snippets.

@neilerdwien
Created March 15, 2017 21:45
Show Gist options
  • Save neilerdwien/2fb2d197ca9f9f6b5ff36672827cd163 to your computer and use it in GitHub Desktop.
Save neilerdwien/2fb2d197ca9f9f6b5ff36672827cd163 to your computer and use it in GitHub Desktop.
parseRfc922Datetime function: Parse a date/time in RFC822 format and return an xs:dateTime value
<!-- Parse a date/time in RFC822 format and return an xs:dateTime value.
*
* If no input string is supplied, or the string is not a valid RFC822 date/time
* value, return the empty sequence.
*
* Background:
*
* The original email standard, RFC822, specifies the format of the Date header.
* See https://www.w3.org/Protocols/rfc822/#z28 for details.
*
* This date format is also used in other contexts, specifically in the pubDate
* elements of Really Simple Syndication (RSS) feeds.
*
* Example: Tue, 27 Jan 2015 08:00:00 +0000
*
* Note, RFC822 has been superceeded by RFC2822: https://tools.ietf.org/html/rfc2822#page-14
-->
<xsl:function name="ksufn:parseRfc822DateTime" as="xs:dateTime?">
<xsl:param as="xs:string?" name="rfc822datetime" />
<xsl:variable name="months">
<month name="Jan" value="01" /><month name="Feb" value="02" /><month name="Mar" value="03" />
<month name="Apr" value="04" /><month name="May" value="05" /><month name="Jun" value="06" />
<month name="Jul" value="07" /><month name="Aug" value="08" /><month name="Sep" value="09" />
<month name="Oct" value="10" /><month name="Nov" value="11" /><month name="Dec" value="12" />
</xsl:variable>
<xsl:analyze-string select="$rfc822datetime" regex="^\s*(\w+,\s*)?(\d+)\s*(\w+)\s*(\d+)\s*((\d+):(\d+)(:(\d+))?)\s+(.*)\s*$">
<!-- regex-group: 11111 222 333 444 55555555555555555555 -->
<xsl:matching-substring>
<xsl:try>
<xsl:variable name="YYYY" as="xs:string" select="if (string-length(regex-group(4)) eq 2) then '20' || regex-group(4) else regex-group(4)" />
<xsl:variable name="MM" as="xs:string" select="$months/month[@name=regex-group(3)]/@value" />
<xsl:variable name="tz" as="xs:string" select="''" /> <!-- ignore timezones for now. -->
<xsl:variable name="iso8601string" as="xs:string" select="concat($YYYY, '-', $MM, '-', regex-group(2), 'T', regex-group(5), ' ', $tz)" />
<xsl:value-of select="xs:dateTime($iso8601string)" />
<xsl:catch />
</xsl:try>
</xsl:matching-substring>
<!-- Might be useful for debugging:
<xsl:non-matching-substring><xsl:message>Error '{$rfc822datetime}', '{.}'</xsl:message></xsl:non-matching-substring>
-->
</xsl:analyze-string>
<!-- If the input string does not match, the empty sequence is returned. -->
</xsl:function>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment