I have had a look at various suggestions on here but none really help my problem. Due to the sources my XML comes from i can receive dates in the following three formats;
04-04-2014(DD-MM-YYYY)
04-Apr-2014(DD-MMM-YYYY)
2014-04-04(YYYY-MM-DD)
I would like to have a function or simple command that will change all of these (other than the third, yet able to recognize that the third is correct) into YYYY-MM-DD
I have a long winded When/when/when to do this currently, but there must be an easier way. My current XSLT does the following;
<xsl:choose>
<xsl:when test="contains(date, 'Jan')">
<xsl:value-of select="concat(substring(date,6),'-01-',substring(date,1,2))" />
</xsl:when>
<xsl:when test="contains(date, 'Feb')">
<xsl:value-of select="concat(substring(date,6),'-02-',substring(date,1,2))" />
</xsl:when>
<xsl:when test="contains(date, 'Mar')">
<xsl:value-of select="concat(substring(date,6),'-03-',substring(date,1,2))" />
</xsl:when>
<xsl:when test="contains(date, 'Apr')">
<xsl:value-of select="concat(substring(date,6),'-04-',substring(date,1,2))" />
</xsl:when>
<xsl:when test="contains(date, 'May')">
<xsl:value-of select="concat(substring(date,6),'-05-',substring(date,1,2))" />
</xsl:when>
<xsl:when test="contains(date, 'Jun')">
<xsl:value-of select="concat(substring(date,6),'-06-',substring(date,1,2))" />
</xsl:when>
<xsl:when test="contains(date, 'Jul')">
<xsl:value-of select="concat(substring(date,6),'-07-',substring(date,1,2))" />
</xsl:when>
<xsl:when test="contains(date, 'Aug')">
<xsl:value-of select="concat(substring(date,6),'-08-',substring(date,1,2))" />
</xsl:when>
<xsl:when test="contains(date, 'Sep')">
<xsl:value-of select="concat(substring(date,6),'-09-',substring(date,1,2))" />
</xsl:when>
<xsl:when test="contains(date, 'Oct')">
<xsl:value-of select="concat(substring(date,6),'-10-',substring(date,1,2))" />
</xsl:when>
<xsl:when test="contains(date, 'Nov')">
<xsl:value-of select="concat(substring(date,6),'-11-',substring(date,1,2))" />
</xsl:when>
<xsl:when test="contains(date, 'Dec')">
<xsl:value-of select="concat(substring(date,6),'-12-',substring(date,1,2))" />
</xsl:when>
<xsl:when test="string-length($dateStart) = 2">
<xsl:value-of select="concat(substring(date,7),'-',substring(date,4,2),'-',substring(date,1,2))" />
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="date"/>
</xsl:otherwise>
</xsl:choose>
So this will check if the date contains any months as JAN,Feb etc. and then if not, check if the first number up to - is 2 characters (DD) and format, other wise it assumes it is YYYY-MM-DD already and outputs it as it is.
I have tried - <xsl:value-of select = "format-dateTime(date, '[Y0001]-[MN]-[D01]')"/>
But this complains that the Dates year is not long enough (as date is being treated as a datetime, which should be in format YYYY-MM-DD
Thanks to Ian roberts Answer below, i created the below to deal with a few more scenarios and group the outputs together;
<xsl:variable name="months" select="('Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec')" />
<xsl:analyze-string select="date" flags="x"
regex="^(
(dd)-(dd)-(dddd)
| (dd)-([A-Za-z]{{3}})-(dddd)
| (dddd)-(dd)-(dd)
| (dddd)-([A-Za-z]{{3}})-(dd)
| (dd)([A-Za-z]{{3}})(dddd)
| (dddd)([A-Za-z]{{3}})(dd))$">
<xsl:matching-substring>
<xsl:value-of select="if (regex-group(4)) then concat(regex-group(4),'-',regex-group(3),'-',regex-group(2)) else ''"/>
<xsl:value-of select="if (regex-group(7)) then concat(regex-group(7),'-',format-number(index-of($months, regex-group(6)), '00'),'-',regex-group(5)) else ''"/>
<xsl:value-of select="if (regex-group(8)) then concat(regex-group(8),'-',regex-group(9),'-',regex-group(10)) else ''"/>
<xsl:value-of select="if (regex-group(11)) then concat(regex-group(11),'-',format-number(index-of($months, regex-group(12)), '00'),'-',regex-group(13)) else ''"/>
<xsl:value-of select="if (regex-group(16)) then concat(regex-group(16),'-',format-number(index-of($months, regex-group(15)), '00'),'-',regex-group(14)) else ''"/>
<xsl:value-of select="if (regex-group(17)) then concat(regex-group(17),'-',format-number(index-of($months, regex-group(18)), '00'),'-',regex-group(19)) else ''"/>
</xsl:matching-substring>
</xsl:analyze-string>
See Question&Answers more detail:os