Search code examples
xslt-1.0xslt-2.0date-format

XSLT date format translation from eg: Aug 23 2018 to 23/08/2018


How to do date format translation from e.g: Aug 23 2018 to 23/08/2018 using XSLT?


Solution

  • XSLT 1.0 does not have any date functions and you will need to use string manipulation functions to convert from one format to another and translate Aug to 08 using some processing logic.

    XSLT 2.0 does have format-date() function however the input format expected by this function is YYYY-MM-DD which can then be converted into formats shown in these examples.

    You can use the below options for converting the date format

    Input XML

    <inputDate>Aug 23 2018</inputDate>
    

    XSLT 1.0

    <xsl:template match="inputDate">
        <xsl:variable name="day" select="substring(., 5, 2)" />
        <xsl:variable name="mth" select="substring(., 1, 3)" />
        <xsl:variable name="year" select="substring(., 8, 4)" />
    
        <!-- Convert 3 char month name to digit -->
        <xsl:variable name="month" select="string-length(substring-before('JanFebMarAprMayJunJulAugSepOctNovDec', $mth)) div 3 + 1" />
        <!-- Format the number to 2 digits -->
        <xsl:variable name="mthNum" select="format-number($month, '00')" />
    
        <formattedDate>
            <xsl:value-of select="concat($day,'/',$mthNum,'/',$year)" />
        </formattedDate>
    </xsl:template>
    

    XSLT 2.0

    Here the solution has used regex to match with the input date format. You can use a different approach as well.

    <xsl:template match="inputDate">
        <!-- Define array of months -->
        <xsl:variable name="months" select="('Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec')" />
        <!-- Define regex to match input date format -->        
        <xsl:analyze-string regex="^(([A-Za-z]{{3}}) (\d\d) (\d\d\d\d))$" select=".">
            <!-- Align the regex groups according to the output format -->
            <xsl:matching-substring>
                <formattedDate>
                    <xsl:value-of select="regex-group(3)" />
                    <xsl:text>/</xsl:text>
                    <xsl:value-of select="format-number(index-of($months, regex-group(2)), '00')" />
                    <xsl:text>/</xsl:text>
                    <xsl:value-of select="regex-group(4)" />
                </formattedDate>
            </xsl:matching-substring>
        </xsl:analyze-string>
    </xsl:template>
    

    Output from both these templates

    <formattedDate>23/08/2018</formattedDate>