I have a XML document. I am getting date from XML in this '2011-08-01' format.
I have to display the same date using either Java Script or XSL in 'August 08th,2011' format.
The XML tag is like this:
<DatelineDate>2011-08-01</DatelineDate>
Please help me to do this.

- 59
- 1
- 6
4 Answers
XSLT 1.0 is not a great technology for date formatting. You either have to do this manually with string processing, or via some XSLT parser specific extensions, for example the microsoft ms:format-date function. However, XSLT 2.0 does have the format-date as standard.
I would recommend using JavaScript instead. See this related question:
Where can I find documentation on formatting a date in JavaScript?
-
ColinE: Absolute statements are almost always wrong. Your statement starting with "XSLT is not a great technology ..." isn't correct in the case of any version of XSLT greater than one. Please, edit and correct. – Dimitre Novatchev Jan 04 '12 at 13:01
-
@Dimitre Novatchev - updated to clarify. However, based on the question given, I would still choose JavaScript for simplicity and portability. – ColinE Jan 04 '12 at 13:27
-
ColinE: Great. As for personal preferences, the OP obviously is interested in an XSLT solution. – Dimitre Novatchev Jan 04 '12 at 13:32
-
@Dimitre the OP is interested in both, and related questions on SO indicate that many believe XSLT 1.0 is not great for date formatting http://stackoverflow.com/questions/500915/format-a-date-in-xml-via-xslt – ColinE Jan 04 '12 at 13:39
-
ColinE: The author has specified "XSLT" -- not just "XSLT 1.0". – Dimitre Novatchev Jan 04 '12 at 13:41
-
@Dimitre sure, however I stand by my remark that *in general* (i.e. in the lack of further information) JavaScript is a better bet. This does not mean to say I have anything against XSLT, it is a great technology, one which I have used on numerous occasions. However, picking an appropriate technology for a problem, when you are faced with a choice, is an important decision. – ColinE Jan 04 '12 at 13:45
-
ColinE: I understand your argument, however, *in general* a person isn't supposed and maynot be using Javascript. These are personal preferences and while I fully respect your own, different people have the right to have different preferences. A good answer doesn't try to impose its author's personal preferences by saying "Technology A is better than technology B". A good answer will just provide solutions (in one or more technologies) and will leave it to the asking person to decide based on his own personal preferences. – Dimitre Novatchev Jan 04 '12 at 13:52
I. XSLT 2.0 solution:
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xsl:output method="text"/>
<xsl:template match="DatelineDate">
<xsl:sequence select="format-date(xs:date(.), '[MNn] [D1o], [Y]')"/>
</xsl:template>
</xsl:stylesheet>
when this transformation is applied on the provided XML document:
<DatelineDate>2011-08-01</DatelineDate>
the wanted, correct result is produced:
August 1st, 2011
Note: Saxon CE makes XSLT 2.0 available in the five major browsers.
II. XSLT 1.0 solution:
This is a simple and understandable solution, that doesn't rely on tricks and unreadable, hardcoded offsets.
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:my="my:my">
<xsl:output method="text"/>
<xsl:strip-space elements="*"/>
<my:months>
<m num="1">January</m>
<m num="2">February</m>
<m num="3">March</m>
<m num="4">April</m>
<m num="5">May</m>
<m num="6">June</m>
<m num="7">July</m>
<m num="8">August</m>
<m num="9">September</m>
<m num="10">October</m>
<m num="11">November</m>
<m num="12">December</m>
</my:months>
<xsl:variable name="vMonthNames" select=
"document('')/*/my:months/*"/>
<xsl:template match="DatelineDate">
<xsl:variable name="vYear"
select="substring-before(., '-')"/>
<xsl:variable name="vdMonth" select=
"substring-before(substring-after(., '-'), '-')"/>
<xsl:variable name="vdDay" select=
"substring-after(substring-after(., '-'), '-')"/>
<xsl:variable name="vMonthName" select=
"$vMonthNames[@num = number($vdMonth)]"/>
<xsl:variable name="vordDaySuffix">
<xsl:choose>
<xsl:when test=
"$vdDay mod 10 = 1
and
not($vdDay = 11)">st</xsl:when>
<xsl:when test="$vdDay mod 10 = 2">nd</xsl:when>
<xsl:when test="$vdDay mod 10 = 3">rd</xsl:when>
<xsl:otherwise>th</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:value-of select=
"concat($vMonthName,
' ',
$vdDay, $vordDaySuffix,
', ',
$vYear
)
"/>
</xsl:template>
</xsl:stylesheet>
When this transformation is applied on the same XML document (above), again the wanted, correct result is produced:
August 01st, 2011

- 240,661
- 26
- 293
- 431
-
The XSLT 1.0 solution in this answer produces incorrect results for some dates. – Flynn1179 Jan 04 '12 at 13:20
-
Sorry, I just assumed it would be obvious. I could tell at a glance that `August 11st, 2011` probably wouldn't be acceptable. – Flynn1179 Jan 04 '12 at 13:29
-
@Flynn1179: Thanks. Please, accept that not all people are native English speakers, so such linguistic peculiarities aren't obvious. I edited my answer to account for such cases. – Dimitre Novatchev Jan 04 '12 at 13:39
Here's a simple template I use in XSLT 1.0 sometimes
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:variable name="months" select="'January February March April May June July August SeptemberOctober December '" />
<xsl:variable name="dayord" select="'-stndrdthththththththththththththththththstndrdthththththththst'" />
<xsl:template match="DatelineDate">
<xsl:value-of select="normalize-space(concat(
substring($months,substring(.,6,2) * 9 - 8, 8),
' ',
substring(.,9,2) + 0,
substring($dayord,substring(.,9,2)*2,2),
', ',
substring(.,1,4)
))" />
</xsl:template>
</xsl:stylesheet>
The substrings are a little convoluted, but they basically pick out the appropriate month name and date suffix from two variables. NB: The spacing in those variables is important, the month names MUST be 9 characters apart. The +0
on the 3rd line of that concat is just a simple trick to treat it as a number rather than the text 01
; Leave that out if you actually prefer the 01
formatting.

- 11,925
- 6
- 38
- 74