How do I convert a time string like
20101115083000 +0200
to
2010-11-15 08:30:00 +0200
using XSLT?
How do I convert a time string like
20101115083000 +0200
to
2010-11-15 08:30:00 +0200
using XSLT?
We use templates:
<xsl:template name="format-date-time">
<xsl:param name="date" select="'%Y-%m-%dT%H:%M:%S%z'"/>
<xsl:value-of select="substring($date, 9, 2)"/>
<xsl:text>/</xsl:text>
<xsl:value-of select="substring($date, 6, 2)"/>
<xsl:text>/</xsl:text>
<xsl:value-of select="substring($date, 1, 4)"/>
<xsl:text> </xsl:text>
<xsl:value-of select="substring($date, 12, 2)"/>
<xsl:text>:</xsl:text>
<xsl:value-of select="substring($date, 15, 2)"/>
<xsl:text>:</xsl:text>
<xsl:value-of select="substring($date, 18, 2)"/>
</xsl:template>
We call these templates like this:
<xsl:call-template name="format-date-time">
<xsl:with-param name="date" select="./Startdate"/>
</xsl:call-template>
./Startdate is an XML date, but with the substring technique, I think you could solve your problem too.
If you have XSLT 2.0, you can use date parsing and formatting functions.
If you have XSLT 1.0, but can use EXSLT, it provides similar functions.
These would be less transparent to use than @Peter's explicit code, but maybe more robust if your input format can vary.
Here is a most generic formatDateTime processing. Input and output format are completely configyrable and passed as parameters:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="/">
<xsl:call-template name="convertDateTime">
<xsl:with-param name="pDateTime" select="."/>
</xsl:call-template>
</xsl:template>
<xsl:template name="convertDateTime">
<xsl:param name="pDateTime"/>
<xsl:param name="pInFormat">
<year offset="0" length="4"/>
<month offset="4" length="2"/>
<day offset="6" length="2"/>
<hour offset="8" length="2"/>
<minutes offset="10" length="2"/>
<seconds offset="12" length="2"/>
<zone offset="15" length="5"/>
</xsl:param>
<xsl:param name="pOutFormat">
<y/>-<mo/>-<d/> <h/>:<m/>:<s/> <z/>
</xsl:param>
<xsl:variable name="vInFormat" select=
"document('')/*/xsl:template[@name='convertDateTime']
/xsl:param[@name='pInFormat']"/>
<xsl:variable name="vOutFormat" select=
"document('')/*/xsl:template[@name='convertDateTime']
/xsl:param[@name='pOutFormat']"/>
<xsl:apply-templates select="$vOutFormat/node()"
mode="_convertDateTime">
<xsl:with-param name="pDateTime" select="$pDateTime"/>
<xsl:with-param name="pInFormat" select="$vInFormat"/>
</xsl:apply-templates>
</xsl:template>
<xsl:template match="y" mode="_convertDateTime">
<xsl:param name="pDateTime"/>
<xsl:param name="pInFormat"/>
<xsl:value-of select=
"substring($pDateTime,
1+$pInFormat/year/@offset,
$pInFormat/year/@length)"/>
</xsl:template>
<xsl:template match="mo" mode="_convertDateTime">
<xsl:param name="pDateTime"/>
<xsl:param name="pInFormat"/>
<xsl:value-of select=
"substring($pDateTime,
1+$pInFormat/month/@offset,
$pInFormat/month/@length)"/>
</xsl:template>
<xsl:template match="d" mode="_convertDateTime">
<xsl:param name="pDateTime"/>
<xsl:param name="pInFormat"/>
<xsl:value-of select=
"substring($pDateTime,
1+$pInFormat/day/@offset,
$pInFormat/day/@length)"/>
</xsl:template>
<xsl:template match="h" mode="_convertDateTime">
<xsl:param name="pDateTime"/>
<xsl:param name="pInFormat"/>
<xsl:value-of select=
"substring($pDateTime,
1+$pInFormat/hour/@offset,
$pInFormat/hour/@length)"/>
</xsl:template>
<xsl:template match="m" mode="_convertDateTime">
<xsl:param name="pDateTime"/>
<xsl:param name="pInFormat"/>
<xsl:value-of select=
"substring($pDateTime,
1+$pInFormat/minutes/@offset,
$pInFormat/minutes/@length)"/>
</xsl:template>
<xsl:template match="s" mode="_convertDateTime">
<xsl:param name="pDateTime"/>
<xsl:param name="pInFormat"/>
<xsl:value-of select=
"substring($pDateTime,
1+$pInFormat/seconds/@offset,
$pInFormat/seconds/@length)"/>
</xsl:template>
<xsl:template match="z" mode="_convertDateTime">
<xsl:param name="pDateTime"/>
<xsl:param name="pInFormat"/>
<xsl:value-of select=
"substring($pDateTime,
1+$pInFormat/zone/@offset,
$pInFormat/zone/@length)"/>
</xsl:template>
</xsl:stylesheet>
when this transformation is applied to the following XML document:
<dateTime>20101115083000 +0200</dateTime>
the wanted, correct result is produced:
2010-11-15 08:30:00 +0200