XSLT - format date

I had someone ask today how to format a date in xslt 1.0.  I thought it was worth posting the answer I gave.  I hope you find it useful.  It's amazing how many lines of code it takes for this, but it's surprising fast. 

convert
a date represented as "Jan-14-2006 08:55:22 (CST)" to "2006-01-14T08:55:22".

XML Sample

<?xml version="1.0" encoding="utf-8"?>
<
doc>
  <
longdate>Jan-14-2006 08:55:22</longdate>
</
doc>

XSLT

<?xml version="1.0" encoding="utf-8"?>

<xsl:stylesheet version="1.0"

xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

  <xsl:template match="/">

    <doc>

      <xsl:element name="newdate">

        <xsl:call-template name="FormatDate">

          <xsl:with-param name="DateTime" select="doc/longdate"/>

        </xsl:call-template>

      </xsl:element>

    </doc>

  </xsl:template>

 

  <xsl:template name="FormatDate">

    <xsl:param name="DateTime" />

    <!-- new date format 2006-01-14T08:55:22 -->

    <xsl:variable name="mo">

      <xsl:value-of select="substring($DateTime,1,3)" />

    </xsl:variable>

    <xsl:variable name="day-temp">

      <xsl:value-of select="substring-after($DateTime,'-')" />

    </xsl:variable>

    <xsl:variable name="day">

      <xsl:value-of select="substring-before($day-temp,'-')" />

    </xsl:variable>

    <xsl:variable name="year-temp">

      <xsl:value-of select="substring-after($day-temp,'-')" />

    </xsl:variable>

    <xsl:variable name="year">

      <xsl:value-of select="substring($year-temp,1,4)" />

    </xsl:variable>

    <xsl:variable name="time">

      <xsl:value-of select="substring-after($year-temp,' ')" />

    </xsl:variable>

    <xsl:variable name="hh">

      <xsl:value-of select="substring($time,1,2)" />

    </xsl:variable>

    <xsl:variable name="mm">

      <xsl:value-of select="substring($time,4,2)" />

    </xsl:variable>

    <xsl:variable name="ss">

      <xsl:value-of select="substring($time,7,2)" />

    </xsl:variable>

    <xsl:value-of select="$year"/>

    <xsl:value-of select="'-'"/>

    <xsl:choose>

      <xsl:when test="$mo = 'Jan'">01</xsl:when>

      <xsl:when test="$mo = 'Feb'">02</xsl:when>

      <xsl:when test="$mo = 'Mar'">03</xsl:when>

      <xsl:when test="$mo = 'Apr'">04</xsl:when>

      <xsl:when test="$mo = 'May'">05</xsl:when>

      <xsl:when test="$mo = 'Jun'">06</xsl:when>

      <xsl:when test="$mo = 'Jul'">07</xsl:when>

      <xsl:when test="$mo = 'Aug'">08</xsl:when>

      <xsl:when test="$mo = 'Sep'">09</xsl:when>

      <xsl:when test="$mo = 'Oct'">10</xsl:when>

      <xsl:when test="$mo = 'Nov'">11</xsl:when>

      <xsl:when test="$mo = 'Dec'">12</xsl:when>

    </xsl:choose>

    <xsl:value-of select="'-'"/>

    <xsl:if test="(string-length($day) &lt; 2)">

      <xsl:value-of select="0"/>

    </xsl:if>

    <xsl:value-of select="$day"/>

    <xsl:value-of select="'T'"/>

    <xsl:value-of select="$hh"/>

    <xsl:value-of select="':'"/>

    <xsl:value-of select="$mm"/>

    <xsl:value-of select="':'"/>

    <xsl:value-of select="$ss"/>

  </xsl:template>

</xsl:stylesheet>

Cheers,

John Workman

Print | posted @ Thursday, February 8, 2007 10:51 PM

Comments on this entry:

Gravatar # re: XSLT - format date
by Robert S. Robbins at 2/17/2007 11:03 AM

Thanks for this XSLT! I am working with the LiveVideo API which returns XML and I found your template useful in reformatting the date. I did need to edit it to get the date in the format I prefer but your code provided the essential trick to make it work.
Gravatar # re: XSLT - format date
by Kyle at 4/2/2007 5:18 PM

Thanks John.

I've modified to convert "1/20/2007 10:22:28 PM" to "January 20, 2007" ... to save anyone who finds it useful a few minutes.

<xsl:template name="FormatDate">
<!-- expected date format 1/20/2007 10:22:28 PM [OR] 01/20/2007 10:22:28 PM -->
<xsl:param name="DateTime" />
<!-- new date format January 20, 2007 -->
<xsl:variable name="mo">
<xsl:value-of select="substring-before($DateTime,'/')" />
</xsl:variable>
<xsl:variable name="day-temp">
<xsl:value-of select="substring-after($DateTime,'/')" />
</xsl:variable>
<xsl:variable name="day">
<xsl:value-of select="substring-before($day-temp,'/')" />
</xsl:variable>
<xsl:variable name="year-temp">
<xsl:value-of select="substring-after($day-temp,'/')" />
</xsl:variable>
<xsl:variable name="year">
<xsl:value-of select="substring($year-temp,1,4)" />
</xsl:variable>

<xsl:choose>
<xsl:when test="$mo = '1' or $mo = '01'">January</xsl:when>
<xsl:when test="$mo = '2' or $mo = '02'">February</xsl:when>
<xsl:when test="$mo = '3' or $mo = '03'">March</xsl:when>
<xsl:when test="$mo = '4' or $mo = '04'">April</xsl:when>
<xsl:when test="$mo = '5' or $mo = '05'">May</xsl:when>
<xsl:when test="$mo = '6' or $mo = '06'">June</xsl:when>
<xsl:when test="$mo = '7' or $mo = '07'">July</xsl:when>
<xsl:when test="$mo = '8' or $mo = '08'">August</xsl:when>
<xsl:when test="$mo = '9' or $mo = '09'">September</xsl:when>
<xsl:when test="$mo = '10'">October</xsl:when>
<xsl:when test="$mo = '11'">November</xsl:when>
<xsl:when test="$mo = '12'">December</xsl:when>
</xsl:choose>
<xsl:value-of select="' '"/>
<xsl:if test="(string-length($day) &lt; 2)">
<xsl:value-of select="0"/>
</xsl:if>
<xsl:value-of select="$day"/>
<xsl:value-of select="', '"/>
<xsl:value-of select="$year"/>
</xsl:template>
Gravatar # re: XSLT - format date
by Hans at 9/26/2007 5:52 AM

Hi!
John, this date formating template is great! Thanx so much. Exactly the input I needed to get my problem solved.
I've chanced it in order to convert a XML dateTime -String into european date format.

<!-- converts FROM 2001-12-31T12:00:00
TO new format 17.09.2007 13:48:18 -->
<xsl:template name="FormatDate">
<xsl:param name="DateTime" />

<xsl:variable name="year">
<xsl:value-of select="substring($DateTime,1,4)" />
</xsl:variable>

<xsl:variable name="month-temp">
<xsl:value-of select="substring-after($DateTime,'-')" />
</xsl:variable>

<xsl:variable name="month">
<xsl:value-of select="substring-before($month-temp,'-')" />
</xsl:variable>

<xsl:variable name="day-temp">
<xsl:value-of select="substring-after($month-temp,'-')" />
</xsl:variable>

<xsl:variable name="day">
<xsl:value-of select="substring($month-temp,1,2)" />
</xsl:variable>



<xsl:variable name="time">
<xsl:value-of select="substring-after($DateTime,'T')" />
</xsl:variable>

<xsl:variable name="hh">
<xsl:value-of select="substring($time,1,2)" />
</xsl:variable>

<xsl:variable name="mm">
<xsl:value-of select="substring($time,4,2)" />
</xsl:variable>

<xsl:variable name="ss">
<xsl:value-of select="substring($time,7,2)" />
</xsl:variable>


<xsl:value-of select="$day"/>
<xsl:value-of select="'.'"/> <!--18.-->
<xsl:value-of select="$month"/>
<xsl:value-of select="'.'"/> <!--18.03.-->
<xsl:value-of select="$year"/>
<xsl:value-of select="' '"/> <!--18.03.1976 -->
<xsl:value-of select="$hh"/>
<xsl:value-of select="':'"/> <!--18.03.1976 13: -->
<xsl:value-of select="$mm"/>
<xsl:value-of select="':'"/> <!--18.03.1976 13:24 -->
<xsl:value-of select="$ss"/> <!--18.03.1976 13:24:55 -->

</xsl:template>

cheers

Hans :)
Gravatar # re: XSLT - format date
by Brent Wilcox at 10/24/2007 3:28 PM

How do you convert the date format coming from pubDate in an RSS feed?

Example: Tue, 23 Oct 2007 09:35:08 -0400

Please and thank you.
Gravatar # re: XSLT - format date
by Brent Wilcox at 10/29/2007 10:03 AM


Ok, figure it out, I think.. Here it is:


<xsl:template name="FormatDate">
<!-- expected date format Thu, 25 Oct 2007 10:47:09 -0400 -->
<xsl:param name="DateTime" />
<!-- new date format 25 October 2007 -->
<xsl:variable name="day-temp">
<xsl:value-of select="substring-after($DateTime,', ')" />
</xsl:variable>
<xsl:variable name="day">
<xsl:value-of select="substring-before($day-temp,' ')" />
</xsl:variable>
<xsl:variable name="mo-temp">
<xsl:value-of select="substring-after($day-temp,' ')" />
</xsl:variable>
<xsl:variable name="mo">
<xsl:value-of select="substring-before($mo-temp,' ')" />
</xsl:variable>
<xsl:variable name="year-temp">
<xsl:value-of select="substring-after($mo-temp,' ')" />
</xsl:variable>
<xsl:variable name="year">
<xsl:value-of select="substring-before($year-temp,' ')" />
</xsl:variable>
<xsl:value-of select="'[ '"/>
<xsl:if test="(string-length($day) &lt; 2)">
<xsl:value-of select="0"/>
</xsl:if>
<xsl:value-of select="$day"/>
<xsl:value-of select="' '"/>
<xsl:choose>
<xsl:when test="$mo = 'jan' or $mo = 'Jan'">January</xsl:when>
<xsl:when test="$mo = 'feb' or $mo = 'Feb'">February</xsl:when>
<xsl:when test="$mo = 'mar' or $mo = 'Mar'">March</xsl:when>
<xsl:when test="$mo = 'apr' or $mo = 'Apr'">April</xsl:when>
<xsl:when test="$mo = 'may' or $mo = 'May'">May</xsl:when>
<xsl:when test="$mo = 'jun' or $mo = 'Jun'">June</xsl:when>
<xsl:when test="$mo = 'jul' or $mo = 'Jul'">July</xsl:when>
<xsl:when test="$mo = 'aug' or $mo = 'Aug'">August</xsl:when>
<xsl:when test="$mo = 'sep' or $mo = 'Sep'">September</xsl:when>
<xsl:when test="$mo = 'oct' or $mo = 'Oct'">October</xsl:when>
<xsl:when test="$mo = 'nov' or $mo = 'Nov'">November</xsl:when>
<xsl:when test="$mo = 'dec' or $mo = 'Dec'">December</xsl:when>
</xsl:choose>
<xsl:value-of select="' '"/>
<xsl:value-of select="$year"/>
<xsl:value-of select="' ]'"/>
</xsl:template>
Gravatar # re: XSLT - format date
by Pushkar at 11/14/2007 5:21 PM

How do I use this wonderful logic to alter how the pubdate is displayed?
Gravatar # re: XSLT - format date
by Thomas Garp at 4/22/2008 7:59 AM

Are you all out of your minds!!? This solution is incredibly ugly, especially if you happen to have code that has to run in different cultures. You can never depend on a date format being the exact same in all situations. With this solution you need a Format function for each special case of date format. In my opinion such code is setting the whole idea of using XSLT back to the graveyard. It reminds me of the old VB date functions, where you had to concatenate the date parts, in order to obtain the needed format.
The only sane solution is to format the date elsewhere, BEFORE sending it to the xslt, at least until XSLT offers a better solution to formatting dates.
Gravatar # re: XSLT - format date
by Chris H at 5/12/2008 9:03 AM

Okay, this page has helped me out a lot - Thanks very much!

My requirement was to pass a date in (always formatted YYYYMMDD) and bring out different values dependant on a second input parameter, here is the template

----------------

<xsl:template name="FormatDate">
<xsl:param name="InDate" />
<xsl:param name="InWhat" select="None" />

<xsl:variable name="DayNum">
<xsl:value-of select="number(substring($rundate,7,2))" />
</xsl:variable>
<xsl:variable name="MonthNum">
<xsl:value-of select="number(substring($rundate,5,2))" />
</xsl:variable>
<xsl:variable name="Year">
<xsl:value-of select="number(substring($rundate,1,4))" />
</xsl:variable>

<xsl:variable name="a" select="floor( ( 14 - $MonthNum ) div 12 )"/>
<xsl:variable name="y" select="$Year - $a"/>
<xsl:variable name="m" select="$MonthNum + 12 * $a - 2"/>
<xsl:variable name="DayWeekNum" select="( $DayNum + $y + floor( $y div 4 ) - floor( $y div 100 ) + floor( $y div 400 ) +
floor( ( 31 * $m) div 12 ) ) mod 7"/>

<xsl:variable name="DayNameLong">
<xsl:choose>
<xsl:when test="$DayWeekNum = 1">Monday</xsl:when>
<xsl:when test="$DayWeekNum = 2">Tuesday</xsl:when>
<xsl:when test="$DayWeekNum = 3">Wednesday</xsl:when>
<xsl:when test="$DayWeekNum = 4">Thursday</xsl:when>
<xsl:when test="$DayWeekNum = 5">Friday</xsl:when>
<xsl:when test="$DayWeekNum = 6">Saturday</xsl:when>
<xsl:when test="$DayWeekNum = 7">Sunday</xsl:when>
</xsl:choose>
</xsl:variable>

<xsl:variable name="ReturnVal">
<xsl:choose>
<xsl:when test="$InWhat = 'DayNum'">
<xsl:value-of select="$DayNum"/>
</xsl:when>
<xsl:when test="$InWhat = 'MonthNum'">
<xsl:value-of select="$DayNameLong"/>
</xsl:when>
<xsl:when test="$InWhat = 'Year'">
<xsl:value-of select="$DayNameLong"/>
</xsl:when>
<xsl:when test="$InWhat = 'DayWeekNum'">
<xsl:value-of select="$DayNameLong"/>
</xsl:when>
<xsl:when test="$InWhat = 'DayNameLong'">
<xsl:value-of select="$DayNameLong"/>
</xsl:when>
<xsl:when test="$InWhat = 'All'">
<xsl:value-of select="$DayNameLong"/>
</xsl:when>
<xsl:when test="$InWhat = 'None'">
<xsl:value-of select="'You must request something!'"/>
</xsl:when>
</xsl:choose>
</xsl:variable>

<xsl:value-of select="$ReturnVal"/>

</xsl:template>

-----------------


and using some code along the lines of
---------
<xsl:attribute name="text">
<xsl:call-template name="FormatDate">
<xsl:with-param name="InDate" select="$rundate"/>
<xsl:with-param name="InWhat" select="'DayNameLong'"/>
</xsl:call-template>
</xsl:attribute>
--------

gets me just what I need.

Note to the last poster - I doubt we are allout of our minds. If I can build a solution purely in XSLT then surely this is the best solution, if I need a full blown program lanague to hold hand with XSL then what is the point of any of this?

Cheers

Chris

Gravatar # re: XSLT - format date
by Ted at 6/19/2008 1:11 PM

Can you tell me how to adapt this with XML input date:
YYYY-MM-DD

and to ouput:

[January, February etc] YYYY

unless input MM=00, when output should just be YYYY

Cheers.
Gravatar # re: XSLT - format date
by John Workman at 6/19/2008 10:03 PM

Since there are only twelve months, the easiest way to do this is with a choose statement. Something like the following. Now if there is a chance you will get -03- and -3-, you will have to check for both. If not, you are safe with:

<xsl:choose>
<xsl:when test="$mm = '01'">
<xsl:value-of select="January"/>
</xsl:when>
<xsl:when test="$mm = '02'">
<xsl:value-of select="February"/>
</xsl:when>...

Hopefully this is what you were looking for.
Cheers,
John
Gravatar # re: XSLT - format date
by Ted at 6/20/2008 3:19 PM

Hi John, thanks for the reply.

My case is simpler than Chris's. I can use his first bit to pull the day, month, year from my input date YYYY-MM-DD

But then the output depends on how complete the date is. e.g.:

If the input is 1983-00-00 then only year is recorded, so output should be 1983

If the input is 1995-08-00 then year and month are recorded, so output should be August 1995

If input is 2007-12-25 then output should 25 December 2007

There is never a case where day and year but month are recorded.

I hope this clarifies things!

cheers,
Ted
Gravatar # re: XSLT - format date
by John Workman at 6/21/2008 12:29 AM

Ted -
I haven't fully tested this out (since it's after midnight), but it should be very close.

<xsl:template name="formatDate">
<xsl:param name="DateTime" />
<!-- date format 1998-03-15 -->
<xsl:variable name="year">
<xsl:value-of select="substring-before($DateTime,'-')" />
</xsl:variable>
<xsl:variable name="mo-temp">
<xsl:value-of select="substring-after($DateTime,'-')" />
</xsl:variable>
<xsl:variable name="mo">
<xsl:value-of select="substring-before($mo-temp,'-')" />
</xsl:variable>
<xsl:variable name="day">
<xsl:value-of select="substring-after($mo-temp,'-')" />
</xsl:variable>
<xsl:if test="$day != '00'">
<xsl:value-of select="$day"/>
<xsl:value-of select="' '"/>
</xsl:if>
<xsl:choose>
<xsl:when test="$mo = '1' or $mo = '01'">January </xsl:when>
<xsl:when test="$mo = '2' or $mo = '02'">February </xsl:when>
<xsl:when test="$mo = '3' or $mo = '03'">March </xsl:when>
<xsl:when test="$mo = '4' or $mo = '04'">April </xsl:when>
<xsl:when test="$mo = '5' or $mo = '05'">May </xsl:when>
<xsl:when test="$mo = '6' or $mo = '06'">June </xsl:when>
<xsl:when test="$mo = '7' or $mo = '07'">July </xsl:when>
<xsl:when test="$mo = '8' or $mo = '08'">August </xsl:when>
<xsl:when test="$mo = '9' or $mo = '09'">September </xsl:when>
<xsl:when test="$mo = '10'">October </xsl:when>
<xsl:when test="$mo = '11'">November </xsl:when>
<xsl:when test="$mo = '12'">December </xsl:when>
<xsl:when test="$mo = '0' or $mo = '00'"></xsl:when><!-- do nothing -->
</xsl:choose>
<xsl:value-of select="$year"/>
</xsl:template>
Gravatar # re: XSLT - format date
by mthor at 6/23/2008 11:00 AM

hey guys, I am just wondering how I can remove the T from the string below and or change the T to a space

2008-06-04T11:14:42.043000000
Gravatar # re: XSLT - format date
by John Workman at 6/23/2008 11:28 AM

Try using the translate function:
http://msdn.microsoft.com/en-us/library/ms256119.aspx

You can replace "T" with " "
Gravatar # re: XSLT - format date
by karthik at 6/25/2008 8:27 AM

i am not getting this worked out as u have given the xslt and also the xml john.The first post john
please help me out
Gravatar # re: XSLT - format date
by karthik at 6/26/2008 3:07 AM

hey john its working cool thank u and can we get the system date i mean to ask u the current date to be printed
Gravatar # re: XSLT - format date
by d.a.Karthik at 6/26/2008 3:09 AM

can u reply me its urgent pls
Gravatar # re: XSLT - format date
by Ted at 6/26/2008 10:11 AM

karthik - is this what you mean?

http://www.zvon.org/xxl/XSL-Ref/Tutorials/Date-Time/dt1.html
Gravatar # re: XSLT - format date
by Ted at 6/26/2008 10:12 AM

Hi John, thanks hugely for your reply - it worked!

I applied it from my main template with:

Date: <xsl:apply-templates select="date">
<xsl:with-param name="DateTime" select="date" />
</xsl:apply-templates>

I have since discovered some cases just have year e.g. 1996, rather than 1996-00-00

Any way I could factor that in?

Cheers, Ted
Gravatar # re: XSLT - format date
by John Workman at 6/26/2008 11:16 PM

Ah, good catch. The reason this isn't working is because the <xsl:value-of select="substring-before($DateTime,'-')" /> is failing. There is no '-'.

To handle this, I would do something like:

<xsl:choose>
<xsl:when test="$year">
<xsl:value-of select="$year"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$DateTime"/>
</xsl:otherwise>
</xsl:choose>

The first test I believe will be false if the value is null, so it will fall to the otherwise.

When you think through these things, first think of how you would do it in simple javascript if/then/else logic. Then convert to xslt. In this case, I thought "if the year is blank, then use the full datetime. At that point I always want to write xsl:if, followed by xsl:else, but quickly remember that xsl:else doesn't exist and then I use the choose. I hope this helps. If this doesn't work, try $year != '' for the xsl:when.

Thanks for answering the other post!
John
Gravatar # re: XSLT - format date
by Ted at 6/26/2008 11:51 PM

Thank you again John,

It's starting to make more sense now. I'm getting my head round simple logic via windows batch programming (OK, not really programming but the principles apply). IF/ELSE applies, and use of variables, strings, substring substitution etc.

Anyway, thanks for your help and patience with a novice!
Ted
Gravatar # re: XSLT - format date
by sam at 7/20/2008 9:55 PM



how to convert 6/5/2008 1:51 PM into dateTime format


can somebody help please
Gravatar # re: XSLT - format date
by Deepika at 8/4/2008 4:18 AM

Hi John,

How do we convert from DDMMYYYY to YYYYMMDD?
Gravatar # re: XSLT - format date
by Ragahva at 9/2/2008 5:14 PM

I have an issue, how to convert 2008-07-01 to 01-Jul-2008?.

Thanks,
Raghava
Gravatar # re: XSLT - format date
by Jenny at 9/11/2008 1:13 PM

I'm a complete XSLT newbie and I need this code to sort by date. How would that work?
Gravatar # re: XSLT - format date
by User at 10/24/2008 11:41 AM

Can you convert ISO date to the format dd mmm yyyy ?
Gravatar # re: XSLT - format date
by Harish at 12/16/2008 12:40 AM

We can use format-dateTime(xs:dateTime($Mydate),'[D01] [MNn] [Y0001]'). if we have a valid dateTime value and similarly format-date exists
Gravatar # re: XSLT - format date
by Harish at 12/16/2008 12:40 AM

We can use format-dateTime(xs:dateTime($Mydate),'[D01] [MNn] [Y0001]'). if we have a valid dateTime value i.e an ISO date and similarly format-date exists
Gravatar # re: XSLT - format date
by Stlyz3 at 2/3/2009 2:16 PM

I have an XSLT that does transformations for a web service and there are four dates that are in the format mm/dd/yyyyThh:mm:ss and I need to have it in yyyy-mm-dd format. The dates are a part of an XML document that contains over 50 fields. Is there a way to transform the dates and keep the regular XML in tact?
Gravatar # re: XSLT - format date - Chris H
by Topher H at 2/25/2009 5:59 PM

Hey Chris found a bug in your code specifically on May 17, 2009 it returned 0 which caused the function to not return a day of the week. Below is my code which I think fixes this.

<xsl:template name="FormatDate">
<xsl:param name="DateTime" />
<xsl:variable name="mo-temp">
<xsl:value-of select="substring-after($DateTime,'-')" />
</xsl:variable>
<xsl:variable name="mo">
<xsl:value-of select="substring-before($mo-temp,'-')" />
</xsl:variable>
<xsl:variable name="day-temp">
<xsl:value-of select="substring-after($DateTime,'-')" />
</xsl:variable>
<xsl:variable name="day">
<xsl:value-of select="substring-after($day-temp,'-')" />
</xsl:variable>
<xsl:variable name="year">
<xsl:value-of select="substring-before($DateTime,'-')" />
</xsl:variable>
<xsl:variable name="cen">
<xsl:value-of select="substring($year, 1, 2)"/>
</xsl:variable>
<xsl:variable name="abbrYear">
<xsl:value-of select="substring($year, 3, 4)"/>
</xsl:variable>

<xsl:variable name="correctedMonth">
<xsl:choose>
<xsl:when test="$mo = '1' or $mo = '01'">11</xsl:when>
<xsl:when test="$mo = '2' or $mo = '02'">12</xsl:when>
<xsl:when test="$mo = '3' or $mo = '03'">1</xsl:when>
<xsl:when test="$mo = '4' or $mo = '04'">2</xsl:when>
<xsl:when test="$mo = '5' or $mo = '05'">3</xsl:when>
<xsl:when test="$mo = '6' or $mo = '06'">4</xsl:when>
<xsl:when test="$mo = '7' or $mo = '07'">5</xsl:when>
<xsl:when test="$mo = '8' or $mo = '08'">6</xsl:when>
<xsl:when test="$mo = '9' or $mo = '09'">7</xsl:when>
<xsl:when test="$mo = '10'">8</xsl:when>
<xsl:when test="$mo = '11'">9</xsl:when>
<xsl:when test="$mo = '12'">10</xsl:when>
</xsl:choose>
</xsl:variable>

<xsl:variable name="correctedYear">
<xsl:choose>
<xsl:when test="$correctedMonth = '11' or $correctedMonth = '12'">
<xsl:value-of select="$abbrYear - 1"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$abbrYear"/>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>

<xsl:variable name="DayWeekNum" select="($day + floor(2.6 * $correctedMonth - .2) - 2*$cen + $correctedYear + floor($correctedYear div 4) + floor($cen div 4)) mod 7"/>

<xsl:variable name="DayNameLong">
<xsl:choose>
<xsl:when test="$DayWeekNum = 0">Sunday, </xsl:when>
<xsl:when test="$DayWeekNum = 1">Monday, </xsl:when>
<xsl:when test="$DayWeekNum = 2">Tuesday, </xsl:when>
<xsl:when test="$DayWeekNum = 3">Wednesday, </xsl:when>
<xsl:when test="$DayWeekNum = 4">Thursday, </xsl:when>
<xsl:when test="$DayWeekNum = 5">Friday, </xsl:when>
<xsl:when test="$DayWeekNum = 6">Saturday, </xsl:when>
</xsl:choose>
</xsl:variable>

<xsl:value-of select="$DayNameLong"/>
<xsl:choose>
<xsl:when test="$mo = '1' or $mo = '01'">Jan</xsl:when>
<xsl:when test="$mo = '2' or $mo = '02'">Feb</xsl:when>
<xsl:when test="$mo = '3' or $mo = '03'">Mar</xsl:when>
<xsl:when test="$mo = '4' or $mo = '04'">Apr</xsl:when>
<xsl:when test="$mo = '5' or $mo = '05'">May</xsl:when>
<xsl:when test="$mo = '6' or $mo = '06'">June</xsl:when>
<xsl:when test="$mo = '7' or $mo = '07'">July</xsl:when>
<xsl:when test="$mo = '8' or $mo = '08'">Aug</xsl:when>
<xsl:when test="$mo = '9' or $mo = '09'">Sept</xsl:when>
<xsl:when test="$mo = '10'">Oct</xsl:when>
<xsl:when test="$mo = '11'">Nov</xsl:when>
<xsl:when test="$mo = '12'">Dec</xsl:when>
</xsl:choose>

<xsl:value-of select="' '"/>
<xsl:if test="(string-length($day) &lt; 2)">
<xsl:value-of select="0"/>
</xsl:if>
<xsl:value-of select="$day"/>
<xsl:value-of select="', '"/>
<xsl:value-of select="$year"/>
</xsl:template>
Gravatar # re: XSLT - format date
by Jim Frenette at 2/27/2009 2:23 PM

Thanks Chris, Topher -- this was a great start to my date-time.xsl
Gravatar # re: XSLT - format date
by Jim Frenette at 3/3/2009 5:26 PM

Topher, I just found a bug I think. The day of the week not returned for today's date March 3, 2009
Gravatar # re: XSLT - format date
by Isaac at 4/1/2009 11:11 AM

Hi all,
here's my (very modest) mod to do transformation from date format 2001-12-31 into date format 31. Dezember 2001... perhaps useful to someone.

My question tho - so what if you want to pack this thing into a <xsl:for-each select=""> loop and transform all the dates in a (quite long) xml file???

i added the <xsl:for-each select="longdate"> after <xsl:param name="DateTime" /> & closed it just before </xsl:template> and interestly enuf, it ran through the whole thing for as many instances of <longdate> as there were in my xml file, but only returned the first value multiple times, i.e.: 17. March 2009 17. March 2009 17. March 2009 17. March 2009 17. March 2009 17. March 2009

little help? thanks!



<?xml version="1.0" encoding="ISO-8859-1"?>
<!-- Edited by XMLSpy® -->
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method='html' version='1.0' encoding='UTF-8' indent='yes'/>



<!-- START set DateTime method -->
<xsl:template match="/">
<xsl:element name="newdate">
<xsl:call-template name="FormatDate">
<xsl:with-param name="DateTime" select="artikelliste/artikel/longdate"/>
</xsl:call-template>
</xsl:element>
</xsl:template>
<!-- END set DateTime method -->






<!-- START date formating & date write -->
<!-- expected date format 2001-12-31 -->
<!-- new date format 31. Dezember 2001 -->
<xsl:template name="FormatDate">
<xsl:param name="DateTime" />
<xsl:variable name="year">
<xsl:value-of select="substring($DateTime,1,4)" />
</xsl:variable>
<xsl:variable name="month-temp">
<xsl:value-of select="substring-after($DateTime,'-')" />
</xsl:variable>
<xsl:variable name="month">
<xsl:value-of select="substring-before($month-temp,'-')" />
</xsl:variable>
<xsl:variable name="day-temp">
<xsl:value-of select="substring-after($month-temp,'-')" />
</xsl:variable>
<xsl:variable name="day">
<xsl:value-of select="substring($day-temp,1,2)" />
</xsl:variable>


<!-- write day -->
<xsl:value-of select="$day"/>
<xsl:value-of select="'. '"/>

<!-- do month substring replace, write -->
<xsl:choose>
<xsl:when test="$month = '1' or $month = '01'">January</xsl:when>
<xsl:when test="$month = '2' or $month = '02'">February</xsl:when>
<xsl:when test="$month = '3' or $month = '03'">March</xsl:when>
<xsl:when test="$month = '4' or $month = '04'">April</xsl:when>
<xsl:when test="$month = '5' or $month = '05'">May</xsl:when>
<xsl:when test="$month = '6' or $month = '06'">June</xsl:when>
<xsl:when test="$month = '7' or $month = '07'">July</xsl:when>
<xsl:when test="$month = '8' or $month = '08'">August</xsl:when>
<xsl:when test="$month = '9' or $month = '09'">September</xsl:when>
<xsl:when test="$month = '10'">October</xsl:when>
<xsl:when test="$month = '11'">November</xsl:when>
<xsl:when test="$month = '12'">December</xsl:when>
</xsl:choose>

<!-- write space & year -->
<xsl:value-of select="' '"/>
<xsl:value-of select="$year"/>
</xsl:template>
<!-- END date formating & date write -->


</xsl:stylesheet>
Gravatar # re: XSLT - format date
by Isaac at 4/1/2009 12:51 PM

oops - once i actually understood which function was calling and which being called, that made the whole thing a lot easier...

<!-- This is where the FormatDate template is called & executed -->

<xsl:template match="/">
<xsl:for-each select="artikelliste/artikel">
<xsl:call-template name="FormatDate">
<xsl:with-param name="DateTime" select="longdate"/>
</xsl:call-template>
</xsl:for-each>
</xsl:template>
<!-- END FORMAT DATE call & execute -->


<!-- START FormatDate definition & structure -->
<!-- expected date format 2001-12-31 -->
<!-- new date format 31. Dezember 2001 -->
<xsl:template name="FormatDate">
<xsl:param name="DateTime" />

<xsl:variable name="year">
<xsl:value-of select="substring($DateTime,1,4)" />
</xsl:variable>
<xsl:variable name="month-temp">
<xsl:value-of select="substring-after($DateTime,'-')" />
</xsl:variable>
<xsl:variable name="month">
<xsl:value-of select="substring-before($month-temp,'-')" />
</xsl:variable>
<xsl:variable name="day-temp">
<xsl:value-of select="substring-after($month-temp,'-')" />
</xsl:variable>
<xsl:variable name="day">
<xsl:value-of select="substring($day-temp,1,2)" />
</xsl:variable>


<!-- write day -->
<xsl:value-of select="$day"/>
<xsl:value-of select="'. '"/>

<!-- do month substring replace, write -->
<xsl:choose>
<xsl:when test="$month = '1' or $month = '01'">January</xsl:when>
<xsl:when test="$month = '2' or $month = '02'">February</xsl:when>
<xsl:when test="$month = '3' or $month = '03'">March</xsl:when>
<xsl:when test="$month = '4' or $month = '04'">April</xsl:when>
<xsl:when test="$month = '5' or $month = '05'">May</xsl:when>
<xsl:when test="$month = '6' or $month = '06'">June</xsl:when>
<xsl:when test="$month = '7' or $month = '07'">July</xsl:when>
<xsl:when test="$month = '8' or $month = '08'">August</xsl:when>
<xsl:when test="$month = '9' or $month = '09'">September</xsl:when>
<xsl:when test="$month = '10'">October</xsl:when>
<xsl:when test="$month = '11'">November</xsl:when>
<xsl:when test="$month = '12'">December</xsl:when>
</xsl:choose>

<!-- write space & year -->
<xsl:value-of select="' '"/>
<xsl:value-of select="$year"/>

</xsl:template>
<!-- END FormatDate definition & structure -->
Gravatar # re: XSLT - format date
by Isaac at 4/1/2009 12:51 PM

oops - once i actually understood which function was calling and which being called, that made the whole thing a lot easier...

<!-- This is where the FormatDate template is called & executed -->

<xsl:template match="/">
<xsl:for-each select="artikelliste/artikel">
<xsl:call-template name="FormatDate">
<xsl:with-param name="DateTime" select="longdate"/>
</xsl:call-template>
</xsl:for-each>
</xsl:template>
<!-- END FORMAT DATE call & execute -->


<!-- START FormatDate definition & structure -->
<!-- expected date format 2001-12-31 -->
<!-- new date format 31. Dezember 2001 -->
<xsl:template name="FormatDate">
<xsl:param name="DateTime" />

<xsl:variable name="year">
<xsl:value-of select="substring($DateTime,1,4)" />
</xsl:variable>
<xsl:variable name="month-temp">
<xsl:value-of select="substring-after($DateTime,'-')" />
</xsl:variable>
<xsl:variable name="month">
<xsl:value-of select="substring-before($month-temp,'-')" />
</xsl:variable>
<xsl:variable name="day-temp">
<xsl:value-of select="substring-after($month-temp,'-')" />
</xsl:variable>
<xsl:variable name="day">
<xsl:value-of select="substring($day-temp,1,2)" />
</xsl:variable>


<!-- write day -->
<xsl:value-of select="$day"/>
<xsl:value-of select="'. '"/>

<!-- do month substring replace, write -->
<xsl:choose>
<xsl:when test="$month = '1' or $month = '01'">January</xsl:when>
<xsl:when test="$month = '2' or $month = '02'">February</xsl:when>
<xsl:when test="$month = '3' or $month = '03'">March</xsl:when>
<xsl:when test="$month = '4' or $month = '04'">April</xsl:when>
<xsl:when test="$month = '5' or $month = '05'">May</xsl:when>
<xsl:when test="$month = '6' or $month = '06'">June</xsl:when>
<xsl:when test="$month = '7' or $month = '07'">July</xsl:when>
<xsl:when test="$month = '8' or $month = '08'">August</xsl:when>
<xsl:when test="$month = '9' or $month = '09'">September</xsl:when>
<xsl:when test="$month = '10'">October</xsl:when>
<xsl:when test="$month = '11'">November</xsl:when>
<xsl:when test="$month = '12'">December</xsl:when>
</xsl:choose>

<!-- write space & year -->
<xsl:value-of select="' '"/>
<xsl:value-of select="$year"/>

</xsl:template>
<!-- END FormatDate definition & structure -->
Gravatar # re: XSLT - format date
by Leanne at 5/11/2009 12:13 PM

In xslt version 1, how do you grab the current date?
Gravatar # re: XSLT - format date
by John Workman at 5/11/2009 10:48 PM

Here's a solution:

<msxsl:script language="JScript" implements-prefix="script"><![CDATA[

function getDate()
{

return new Date();
}

]]></msxsl:script>
Gravatar # re: XSLT - format date
by Ivan at 6/17/2009 2:15 PM

Thank for this post! Very helpfull! Whole day of work for one minute!
Gravatar # re: XSLT - format date
by Mark at 7/13/2009 10:53 AM

Your code is great! I have a challenge for you guys. Lets outmanouver Microsoft!
I have looked everywhere for a xsl stylesheet that can transform a saved MS Project 2007 to html. They, being mean, left it out of 2007 release and nailed everyone. If you can help me I can send you the project 2007 project xml dump from Microsoft Project and also a xsl file that I have produced that takes me most of the way there. But I am still having problems with date conversion from their 2006-01-14T08:55:22 to normal date and also the duration i.e. it is in this format PT0H0M0S which I would like to simply show days and hours. I can email you the two files if you contact me. Please help as I see many people who would love to have this solution on the net but cant, like me, quite get there. In Project 2003 the feature was File, save as html but, pushing for sharepoint they have taken this func. away.


Markjc@mweb.co.za
Gravatar # re: XSLT - format date
by Michael at 7/21/2009 9:36 AM

thank you for your code. I made some updates to the template which converts an blogger atom.xml into a mini rss reader.

See below for the complete xslt in case anyone would like to do the same.

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0"
xmlns:atom="http://www.w3.org/2005/Atom"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html"/>
<xsl:template match="/atom:feed">
<div>
<h1>Latest News</h1>
<xsl:apply-templates select="atom:entry" />
</div>
</xsl:template>
<xsl:template match="atom:entry">
<xsl:if test="position()&lt;10">
<p>
<span class="date">
<!--Tue 10 July 2009-->
<!--<xsl:value-of select="substring(atom:published,0,11)"/>-->
<xsl:call-template name="FormatDate">
<xsl:with-param name="DateTime" select="substring(atom:published,0,20)"/>
</xsl:call-template>
</span>
<br />
<span class="news-heading">
<xsl:value-of select="atom:title"/>
</span>
<br />
more ...
</p>

</xsl:if>
</xsl:template>

<!-- converts FROM 2001-12-31T12:00:00
TO new format Fri 26 June 2009
-->
<xsl:template name="FormatDate">
<xsl:param name="DateTime" />
<xsl:variable name="year">
<xsl:value-of select="substring($DateTime,1,4)" />
</xsl:variable>
<xsl:variable name="month-temp">
<xsl:value-of select="substring-after($DateTime,'-')" />
</xsl:variable>
<xsl:variable name="month">
<xsl:value-of select="substring-before($month-temp,'-')" />
</xsl:variable>
<xsl:variable name="day-temp">
<xsl:value-of select="substring-after($month-temp,'-')" />
</xsl:variable>
<xsl:variable name="day">
<xsl:value-of select="substring($month-temp,1,2)" />
</xsl:variable>
<xsl:variable name="time">
<xsl:value-of select="substring-after($DateTime,'T')" />
</xsl:variable>
<xsl:variable name="hh">
<xsl:value-of select="substring($time,1,2)" />
</xsl:variable>
<xsl:variable name="mm">
<xsl:value-of select="substring($time,4,2)" />
</xsl:variable>
<xsl:variable name="ss">
<xsl:value-of select="substring($time,7,2)" />
</xsl:variable>

<xsl:value-of select="$day"/>
<!--18 -->
<xsl:value-of select="' '"/>
<xsl:choose>
<xsl:when test="$month = '01'">Jan</xsl:when>
<xsl:when test="$month = '02'">Feb</xsl:when>
<xsl:when test="$month = '03'">Mar</xsl:when>
<xsl:when test="$month = '04'">Apr</xsl:when>
<xsl:when test="$month = '05'">May</xsl:when>
<xsl:when test="$month = '06'">Jun</xsl:when>
<xsl:when test="$month = '07'">Jul</xsl:when>
<xsl:when test="$month = '08'">Aug</xsl:when>
<xsl:when test="$month = '09'">Sep</xsl:when>
<xsl:when test="$month = '10'">Oct</xsl:when>
<xsl:when test="$month = '11'">Nov</xsl:when>
<xsl:when test="$month = '12'">Dec</xsl:when>
</xsl:choose>
<xsl:value-of select="' '"/>
<!--18 Jan-->
<xsl:value-of select="' '"/>
<xsl:value-of select="$year"/>
<xsl:value-of select="' '"/>
<!--18.03.1976 -->
<xsl:value-of select="$hh"/>
<xsl:value-of select="':'"/>
<!--18.03.1976 13: -->
<xsl:value-of select="$mm"/>
<xsl:value-of select="':'"/>
<!--18.03.1976 13:24 -->
<xsl:value-of select="$ss"/>
<!--18.03.1976 13:24:55 -->

</xsl:template>
</xsl:stylesheet>
Gravatar # re: XSLT - format date
by Gian at 10/7/2009 9:53 AM

I have a RSS feed which I would like to display on a webpage, an ASP scripted page. I can just use the buil-in xslt tools from Dreamweaver to di this but the problem is the date format (Tue, 06 Oct 2009 11:25:10 +0200) while I would need 11:25 | 06/10/2009. This script seems to get the job don but I cannot understand how to repeat the date transformation for each node in the rss.

<item><title>Muslera no alla Premier per la Lazio</title><link>http://www.calciomercato.it/news/60644/Muslera-no-alla-Premier-per-la-Lazio.html</link><guid>http://www.calciomercato.it/news/60644/Muslera-no-alla-Premier-per-la-Lazio.html</guid><pubDate>Wed, 07 Oct 2009 13:47:42 +0200</pubDate><description><![CDATA[ Il portiere uruguagio è pronto a rinnovare il suo contratto con il club biancoceleste ]]></description></item>

this is one of the nodes in the rss....any hints?
Gravatar # re: XSLT - format date
by zaenal at 11/3/2009 4:59 PM

Hi,
Great article and exactly what I'm looking for. I'm trying to edit repos-web (XSLT) for Subversion, and try to format "2009-11-03T16:47:32.171875Z" to "4 hours ago", etc.

Thank's for sharing this stuff.

@zaenal
Gravatar # re: XSLT - format date
by Michael Kay at 11/4/2009 1:27 PM

It's amazing that anyone who cares about the number of lines of code should write <xsl:variable name="x"><xsl:value-of select="Y"/></xsl:variable> when you could just write <xsl:variable select="X"/>, which would also be much more efficient. But perhaps you were trying to prove a point.
Gravatar # re: XSLT - format date
by Shane at 12/1/2009 5:23 AM

Thanks John, good stuff.

@Michael - RE: blogger atom.xml

Thanks for the code, saved me some time. Also, FYI...

<xsl:variable name="day">
<xsl:value-of select="substring($month-temp,1,2)" />
</xsl:variable>

Should be:

<xsl:variable name="day">
<xsl:value-of select="substring($day-temp,1,2)" />
</xsl:variable>
Gravatar # re: XSLT - format date
by Joe at 12/2/2009 1:28 PM

Hi All,

I'm very new to XSL, does any one know how I would convert date1 to the same format as date2

date1 = "02/21/2008 00:00:00"
date2 = "28-11-09 16:00:00’,’DD-MM-YY 24HH:MI:SS"

Thanks in advance for your help.

Cheers,
Joe
Gravatar # re: XSLT - format date
by John Workman at 1/15/2010 3:38 PM

Michael - Thanks for point that out. When I wrote this about 4 yrs ago it was word wrapping on my little monitor, and was hard to understand. This was done for readability at that time.

I hope you are doing well. Cheers!
Gravatar # re: XSLT - format date
by Lawrence at 1/19/2010 11:45 AM

This thread has been a tremendous help for me formatting the DATE, but was wondering if anyone had some help for me to format TIME. My problem is that I have single-digit (no leading zero when the hour is less than 10) 12-hour am/pm hours, that I'm trying to convert to two-digit, i.e. '01', instead of just '1', 24-hour hours.

I'm trying to go
FROM old format: September 27, 2008 1:41:03 PM,
TO new format: YYYY-MM-DD HH:mm:ss

As I said, I already have the DATE portion done. I just need to change
"1:41:03 PM", to "13:41:03"

Any help would be greatly appreciated.

Thanks,
LOLLIFFE@getty.edu
Gravatar #  format date
by rajani at 2/8/2010 4:38 PM

hi...
please can anyone let me know how the iso date formats to be converted into regular readable format?
eg: 1985102,1985W155 to be converted into 1985 april 12th friday.Code in c# or any easiest logic to get this..
Gravatar # re: XSLT - format date
by bhaskar at 2/8/2010 6:35 PM

nice post thank you very much
Gravatar # re: XSLT - format date
by harshil at 3/7/2010 9:53 PM

How can I get the last year's date
Gravatar # re: XSLT - format date
by John Workman at 3/7/2010 11:13 PM

Split it, just like the others, subtract on from the year, then put it all back together.
Gravatar # re: XSLT - format date
by Nate Dog at 4/7/2010 6:50 AM

I had to do the (almost) exact opposite of this, as we had a client using a .net web service, and had to convert their timestamp format into DD/MM/YY.
It was much shorter but I'd have never figured it out without your help. Thanks!
<xsl:template name="FormatDate">
<xsl:param name="DateTime" />
<!-- old date format YYYY-MM-DDTHH:MM:SS / want MM/DD/YY-->
<xsl:variable name="year">
<xsl:value-of select="substring($DateTime,1,4)" />
</xsl:variable>
<xsl:variable name="mon">
<xsl:value-of select="substring($DateTime,6,2)" />
</xsl:variable>
<xsl:variable name="day">
<xsl:value-of select="substring($DateTime,9,2)" />
</xsl:variable>
<xsl:value-of select="$mon" />/<xsl:value-of select="$day" />/<xsl:value-of select="$year" />
</xsl:template>
Gravatar # re: XSLT - format date
by sherry at 6/28/2010 6:51 PM

i have this date format read from the XML 7/2/2010 12:00:00 AM
and i need to convert it to 2July, 2010

but when i write <xsl:value-of select="ddwrt:FormatDateTime(string(@TaskDueDate) ,1033 ,'dd MMMM, yyyy ')"/>

it gives error with no result

does anyone have a solution?
Gravatar # re: XSLT - format date
by Balakrishnan at 1/24/2011 12:44 AM

For Format time Refer the Link
http://msdn.microsoft.com/en-us/library/ms256467.aspx
For Format date refer the link
http://msdn.microsoft.com/en-us/library/ms256099.aspx
Gravatar # re: XSLT - format date
by Grant Parks at 2/10/2012 7:35 AM

One trick I didn't see anyone use to translate month names/numbers is to have a "data node" in the XSL itself and use it via the document() function.

Add to XSLT's namespace prefixes:
xmlns:date="#date"

At top level of XSLT:
<date:date>
<date:month abbr="Jan"/>
<date:month abbr="Feb"/>
<date:month abbr="Mar"/>
<date:month abbr="Apr"/>
<date:month abbr="May"/>
<date:month abbr="Jun"/>
<date:month abbr="Jul"/>
<date:month abbr="Aug"/>
<date:month abbr="Sep"/>
<date:month abbr="Oct"/>
<date:month abbr="Nov"/>
<date:month abbr="Dec"/>
</date:date>

Reference in the XSLT:
document('')/xsl:stylesheet/date:date/date:month
Post A Comment
Title:
Name:
Email:
Comment:
Verification: