Subject: Re: [xsl] Function converting RFC 2822 date to xsd:dateTime From: "Martynas Jusevičius martynas@xxxxxxxxxxxxx" <xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx> Date: Tue, 9 Apr 2019 08:09:23 -0000 |
Thanks all, parse-ietf-date() makes most sense indeed. That is what I went with: <xsl:try> <triple> <xsl:copy-of select="$subject"/> <uri>&nmo;sentDate</uri> <plainLiteral><xsl:sequence select="parse-ietf-date($date-time)"/></plainLiteral> </triple> <xsl:catch> <xsl:message><xsl:value-of select="$err:description"/> Message ID: <xsl:value-of select="$subject"/></xsl:message> </xsl:catch> </xsl:try> </xsl:template> On Tue, Apr 9, 2019 at 5:45 AM Syd Bauman s.bauman@xxxxxxxxxxxxxxxx <xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx> wrote: > > Martynas -- > > As Michael Kay brought up, switching to XSLT 3.0 and using > parse-ietf-date() is probably the best way to go. And I don't pretend > to be a good enough programmer to know if there are improvements to > be made to your algorithm. But when dealing with unwieldy stuff like > this, I find it very helpful to name bits of code and to use > whitespace liberally, especially within the regular expression (using > the 'x' flag). > > Here is an XSLT 2.0 program that runs a modified version of your > function. The only other changes I've made to the function are: > * signature of $months is now '+', not '*' > * different mechanism for inserting colon into TZ > * return a dateTime even when there's an error in parsing > > ####################### > <?xml version="1.0" encoding="UTF-8"?> > <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" > xmlns:xs="http://www.w3.org/2001/XMLSchema" > exclude-result-prefixes="#all" > xmlns:aex="http://idunno.example.org/" > version="2.0"> > > <xsl:param name="dt" select="'Tue, 9 Apr 2019 00:07:24 +1200 (NZST)'" as="xs:string"/> > > <xsl:output method="text"/> > > <xsl:template match="/"> > <xsl:text>Result: </xsl:text> > <xsl:value-of select="aex:rfc2822dateTime-to-dateTime( $dt )"/> > <xsl:text>
</xsl:text> > </xsl:template> > > <xsl:function name="aex:rfc2822dateTime-to-dateTime" as="xs:dateTime"> > <xsl:param name="date-time" as="xs:string"/> > <xsl:variable name="months" as="xs:string+" select=" > 'Jan', 'Feb', 'Mar','Apr', 'May', 'Jun', > 'Jul', 'Aug', 'Sep','Oct', 'Nov', 'Dec'"/> > <xsl:analyze-string select="$date-time" flags="x" regex=" > ^ > (?: (Sun|Mon|Tue|Wed|Thu|Fri|Sat),\s+ )? > ( 0[1-9] | [1-2]?[0-9] | 3[01] ) > \s+ > (Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec) > \s+ > ( 19[0-9]{{2}} | [2-9][0-9]{{3}} ) > \s+ > ( 2[0-3] | [0-1][0-9] ) > : > ( [0-5][0-9] ) > (?: :( 60 | [0-5][0-9] ) )? > \s+ > ( > [-\+] > [0-9]{{2}}[0-5][0-9] > | > (?: UT | GMT | (?:E|C|M|P) (?:ST|DT) | [A-IK-Z] ) > ) > (\s+|\(([^\(\)]+|\\\(|\\\))*\))*$"> > <xsl:matching-substring> > <xsl:variable name="day" select="regex-group(1)"/><!-- unused --> > <xsl:variable name="date" select="xs:integer( regex-group(2) )"/> > <xsl:variable name="month" select="index-of( $months, regex-group(3) )"/> > <xsl:variable name="year" select="xs:integer( regex-group(4) )"/> > <xsl:variable name="hour" select="xs:integer( regex-group(5) )"/> > <xsl:variable name="minute" select="xs:integer( regex-group(6) )"/> > <xsl:variable name="second" select="xs:integer( regex-group(7) )"/> > <xsl:variable name="timezone" select="replace( regex-group(8),'^(...)(.*)$','$1:$2' )"/> > <xsl:variable name="dateTimeString" select="concat( > format-number( $year,'0001'), > '-', > format-number( $month,'01'), > '-', > format-number( $date,'01'), > 'T', > format-number( $hour,'01'), > ':', > format-number( $minute,'01'), > ':', > format-number( $second,'01'), > $timezone )"/> > <xsl:value-of select="$dateTimeString"/> > </xsl:matching-substring> > <xsl:non-matching-substring> > <xsl:message>Invalid RFC 2822 datetime: <xsl:value-of select="$date-time"/></xsl:message> > <!-- > 2 points to anyone who can say what happened at the date and time > I've chosen to return in case of error. 2 hints: 1) I made up the > seconds, to my knowledge it was only recorded to the minute; 2) it > was pronounced "seventeen October nineteen forty-five" in the musical. > --> > <xsl:value-of select="xs:dateTime('1945-10-17T23:10:30-03:00')"/> > </xsl:non-matching-substring> > </xsl:analyze-string> > </xsl:function> > > </xsl:stylesheet> > ####################### > > Hope this is at least food for thought, if not outright helpful.
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
Re: [xsl] Function converting RFC 2, Syd Bauman s.bauman@ | Thread | [xsl] Transforming large XML docume, Mukul Gandhi gandhi. |
Re: [xsl] Transforming large XML do, Martin Honnen martin | Date | Re: [xsl] Transforming large XML do, Mukul Gandhi gandhi. |
Month |