Author:
buzzomatic
Version:
1.0
Release Date:
7 May 2009
Category:
Date & Time

Description

An alternative to the Format Date/Time utility that provides more formatting rules with an alternate syntax.

XSLT

View Raw
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:date="http://exslt.org/dates-and-times" extension-element-prefixes="date">
<!--
	
	Description:
	
	This is a date formatting utility. The named template "format-date" takes 2 parameters:
	
	1. date - [required] takes an ISO date (2005-12-01)
	2. format - [optional] takes a format string.
	
	
	Date formats:
	
	%ds;	Day suffix, lower case: st, nd, rd, th.
	%DS;	Day suffix, upper case: ST, ND, RD, TH.
	
	%d;		Day of month, no leading zero.
	%0d;	Day of month, with leading zero.
	%_d;	Day of month, with leading space.
	%d-;	Day of week, shorthand: Mon, Tue, Wed.
	%d+;	Day of week, full length: Monday.
	%dy;	Day of year, no leading zero.
	%0dy;	Day of year, with leading zero.
	%_dy;	Day of year, with leading space.
	
	%wm;	Week of month, no leading zero.
	%0wm;	Week of month, with leading zero.
	%_wm;	Week of month, with leading space.
	
	%m;		Month of year, no leading zero.
	%0m;	Month of year, with leading zero.
	%m0;	Month of year, shorthand: Jan, Mar, Sep.
	%m+;	Month of year, full length: January.
	
	%y2;	Year in 2 digits.
	%y+;	Year in 4 digits.
	
	
	Time formats:
	
	#ts;	AM/PM time suffix in lower case.
	#TS;	AM/PM time suffix in upper case.
	
	#s;		Seconds, no leading zero.
	#0s;	Seconds, with leading zero.
	#_s;	Seconds, with leading space.
	
	#m;		Minutes, no leading zero.
	#0m;	Minutes, with leading zero.
	#_m;	Minutes, with leading space.
	
	#h;		12 Hours, no leading zero.
	#0h;	12 Hours, with leading zero.
	#_h;	12 Hours, with leading space.
	#H;		24 Hours, no leading zero.
	#0H;	24 Hours, with leading zero.
	#_H;	24 Hours, with leading space.
	
-->
	
	<date:days>
		<date:day id="1" shorthand="Sun">Sunday</date:day>
		<date:day id="2" shorthand="Mon">Monday</date:day>
		<date:day id="3" shorthand="Tue">Tuesday</date:day>
		<date:day id="4" shorthand="Wed">Wednesday</date:day>
		<date:day id="5" shorthand="Thu">Thursday</date:day>
		<date:day id="6" shorthand="Fri">Friday</date:day>
		<date:day id="7" shorthand="Sat">Saturday</date:day>
	</date:days>
	
	<date:months>
		<date:month shorthand="Jan">January</date:month>
		<date:month shorthand="Feb">February</date:month>
		<date:month shorthand="Mar">March</date:month>
		<date:month shorthand="Apr">April</date:month>
		<date:month shorthand="May">May</date:month>
		<date:month shorthand="Jun">June</date:month>
		<date:month shorthand="Jul">July</date:month>
		<date:month shorthand="Aug">August</date:month>
		<date:month shorthand="Sep">September</date:month>
		<date:month shorthand="Oct">October</date:month>
		<date:month shorthand="Nov">November</date:month>
		<date:month shorthand="Dec">December</date:month>
	</date:months>
	
	<xsl:template name="format-date">
		<xsl:param name="date" />
		<xsl:param name="format" select="'%d;%ds; %m+;, %y+;'" />
		
		<xsl:call-template name="date-controller">
			<xsl:with-param name="date" select="$date" />
			<xsl:with-param name="format" select="$format" />
		</xsl:call-template>
	</xsl:template>
	
	<xsl:template name="date-controller">
		<xsl:param name="date" />
		<xsl:param name="format" />
		
	<!--
		Jump X characters:
	-->
		<xsl:variable name="skip">
			<xsl:choose>
			<!--
				Damn, end of line:
			-->
				<xsl:when test="$format = ''">0</xsl:when>
				
			<!--
				Date formats:
			-->
				<xsl:when test="starts-with($format, '%ds;')">4</xsl:when>
				<xsl:when test="starts-with($format, '%DS;')">4</xsl:when>
				<xsl:when test="starts-with($format, '%0dy;')">5</xsl:when>
				<xsl:when test="starts-with($format, '%_dy;')">5</xsl:when>
				<xsl:when test="starts-with($format, '%dy;')">4</xsl:when>
				<xsl:when test="starts-with($format, '%d-;')">4</xsl:when>
				<xsl:when test="starts-with($format, '%d+;')">4</xsl:when>
				<xsl:when test="starts-with($format, '%0d;')">4</xsl:when>
				<xsl:when test="starts-with($format, '%_d;')">4</xsl:when>
				<xsl:when test="starts-with($format, '%d;')">3</xsl:when>
				
				<xsl:when test="starts-with($format, '%0wm;')">5</xsl:when>
				<xsl:when test="starts-with($format, '%_wm;')">5</xsl:when>
				<xsl:when test="starts-with($format, '%wm;')">4</xsl:when>
				<xsl:when test="starts-with($format, '%0wy;')">5</xsl:when>
				<xsl:when test="starts-with($format, '%_wy;')">5</xsl:when>
				<xsl:when test="starts-with($format, '%wy;')">4</xsl:when>
				
				<xsl:when test="starts-with($format, '%m-;')">4</xsl:when>
				<xsl:when test="starts-with($format, '%m+;')">4</xsl:when>
				<xsl:when test="starts-with($format, '%0m;')">4</xsl:when>
				<xsl:when test="starts-with($format, '%_m;')">4</xsl:when>
				<xsl:when test="starts-with($format, '%m;')">3</xsl:when>
				
				<xsl:when test="starts-with($format, '%y2;')">4</xsl:when>
				<xsl:when test="starts-with($format, '%y+;')">4</xsl:when>
				
			<!--
				Time formats:
			-->
				<xsl:when test="starts-with($format, '#ts;')">4</xsl:when>
				<xsl:when test="starts-with($format, '#TS;')">4</xsl:when>
				
				<xsl:when test="starts-with($format, '#0s;')">4</xsl:when>
				<xsl:when test="starts-with($format, '#_s;')">4</xsl:when>
				<xsl:when test="starts-with($format, '#s;')">3</xsl:when>
				
				<xsl:when test="starts-with($format, '#0m;')">4</xsl:when>
				<xsl:when test="starts-with($format, '#_m;')">4</xsl:when>
				<xsl:when test="starts-with($format, '#m;')">3</xsl:when>
				
				<xsl:when test="starts-with($format, '#0h;')">4</xsl:when>
				<xsl:when test="starts-with($format, '#_h;')">4</xsl:when>
				<xsl:when test="starts-with($format, '#h;')">3</xsl:when>
				<xsl:when test="starts-with($format, '#0H;')">4</xsl:when>
				<xsl:when test="starts-with($format, '#_H;')">4</xsl:when>
				<xsl:when test="starts-with($format, '#H;')">3</xsl:when>
				
			<!--
				Just some filler text:
			-->
				<xsl:otherwise>1</xsl:otherwise>
			</xsl:choose>
		</xsl:variable>
		
	<!--
		Get output:
	-->
		<xsl:variable name="out">
			<xsl:choose>
			<!--
				Damn, end of line:
			-->
				<xsl:when test="$format = ''">
					<!-- Nothing to do... -->
				</xsl:when>
				
			<!--
				Date formats:
			-->
				<xsl:when test="starts-with($format, '%ds;')">
					<xsl:call-template name="format-day-suffix">
						<xsl:with-param name="date" select="$date" />
						<xsl:with-param name="case" select="'lower'" />
					</xsl:call-template>
				</xsl:when>
				<xsl:when test="starts-with($format, '%DS;')">
					<xsl:call-template name="format-day-suffix">
						<xsl:with-param name="date" select="$date" />
						<xsl:with-param name="case" select="'upper'" />
					</xsl:call-template>
				</xsl:when>
				<xsl:when test="starts-with($format, '%0dy;')">
					<xsl:call-template name="format-day-year">
						<xsl:with-param name="date" select="$date" />
						<xsl:with-param name="prefix" select="'0'" />
					</xsl:call-template>
				</xsl:when>
				<xsl:when test="starts-with($format, '%_dy;')">
					<xsl:call-template name="format-day-year">
						<xsl:with-param name="date" select="$date" />
						<xsl:with-param name="prefix" select="' '" />
					</xsl:call-template>
				</xsl:when>
				<xsl:when test="starts-with($format, '%dy;')">
					<xsl:call-template name="format-day-year">
						<xsl:with-param name="date" select="$date" />
					</xsl:call-template>
				</xsl:when>
				<xsl:when test="starts-with($format, '%d-;')">
					<xsl:call-template name="format-day-shorthand">
						<xsl:with-param name="date" select="$date" />
					</xsl:call-template>
				</xsl:when>
				<xsl:when test="starts-with($format, '%d+;')">
					<xsl:call-template name="format-day-name">
						<xsl:with-param name="date" select="$date" />
					</xsl:call-template>
				</xsl:when>
				<xsl:when test="starts-with($format, '%0d;')">
					<xsl:call-template name="format-day-number">
						<xsl:with-param name="date" select="$date" />
						<xsl:with-param name="prefix" select="'0'" />
					</xsl:call-template>
				</xsl:when>
				<xsl:when test="starts-with($format, '%_d;')">
					<xsl:call-template name="format-day-number">
						<xsl:with-param name="date" select="$date" />
						<xsl:with-param name="prefix" select="' '" />
					</xsl:call-template>
				</xsl:when>
				<xsl:when test="starts-with($format, '%d;')">
					<xsl:call-template name="format-day-number">
						<xsl:with-param name="date" select="$date" />
						<xsl:with-param name="prefix" select="''" />
					</xsl:call-template>
				</xsl:when>
				
				<xsl:when test="starts-with($format, '%0wm;')">
					<xsl:call-template name="format-week-month">
						<xsl:with-param name="date" select="$date" />
						<xsl:with-param name="prefix" select="'0'" />
					</xsl:call-template>
				</xsl:when>
				<xsl:when test="starts-with($format, '%_wm;')">
					<xsl:call-template name="format-week-month">
						<xsl:with-param name="date" select="$date" />
						<xsl:with-param name="prefix" select="' '" />
					</xsl:call-template>
				</xsl:when>
				<xsl:when test="starts-with($format, '%wm;')">
					<xsl:call-template name="format-week-month">
						<xsl:with-param name="date" select="$date" />
					</xsl:call-template>
				</xsl:when>
				<xsl:when test="starts-with($format, '%0wy;')">
					<xsl:call-template name="format-week-year">
						<xsl:with-param name="date" select="$date" />
						<xsl:with-param name="prefix" select="'0'" />
					</xsl:call-template>
				</xsl:when>
				<xsl:when test="starts-with($format, '%_wy;')">
					<xsl:call-template name="format-week-year">
						<xsl:with-param name="date" select="$date" />
						<xsl:with-param name="prefix" select="' '" />
					</xsl:call-template>
				</xsl:when>
				<xsl:when test="starts-with($format, '%wy;')">
					<xsl:call-template name="format-week-year">
						<xsl:with-param name="date" select="$date" />
					</xsl:call-template>
				</xsl:when>
				
				<xsl:when test="starts-with($format, '%m-;')">
					<xsl:call-template name="format-month-shorthand">
						<xsl:with-param name="date" select="$date" />
						<xsl:with-param name="length" select="3" />
					</xsl:call-template>
				</xsl:when>
				<xsl:when test="starts-with($format, '%m+;')">
					<xsl:call-template name="format-month-name">
						<xsl:with-param name="date" select="$date" />
					</xsl:call-template>
				</xsl:when>
				<xsl:when test="starts-with($format, '%0m;')">
					<xsl:call-template name="format-month-number">
						<xsl:with-param name="date" select="$date" />
						<xsl:with-param name="prefix" select="'0'" />
					</xsl:call-template>
				</xsl:when>
				<xsl:when test="starts-with($format, '%_m;')">
					<xsl:call-template name="format-month-number">
						<xsl:with-param name="date" select="$date" />
						<xsl:with-param name="prefix" select="' '" />
					</xsl:call-template>
				</xsl:when>
				<xsl:when test="starts-with($format, '%m;')">
					<xsl:call-template name="format-month-number">
						<xsl:with-param name="date" select="$date" />
						<xsl:with-param name="prefix" select="''" />
					</xsl:call-template>
				</xsl:when>
				
				<xsl:when test="starts-with($format, '%y2;')">
					<xsl:call-template name="format-year-number">
						<xsl:with-param name="date" select="$date" />
						<xsl:with-param name="offset" select="3" />
					</xsl:call-template>
				</xsl:when>
				<xsl:when test="starts-with($format, '%y+;')">
					<xsl:call-template name="format-year-number">
						<xsl:with-param name="date" select="$date" />
						<xsl:with-param name="offset" select="1" />
					</xsl:call-template>
				</xsl:when>
				
			<!--
				Time formats:
			-->
				<xsl:when test="starts-with($format, '#ts;')">
					<xsl:call-template name="format-time-suffix">
						<xsl:with-param name="date" select="$date" />
						<xsl:with-param name="case" select="'lower'" />
					</xsl:call-template>
				</xsl:when>
				<xsl:when test="starts-with($format, '#TS;')">
					<xsl:call-template name="format-time-suffix">
						<xsl:with-param name="date" select="$date" />
						<xsl:with-param name="case" select="'upper'" />
					</xsl:call-template>
				</xsl:when>
				
				<xsl:when test="starts-with($format, '#0s;')">
					<xsl:call-template name="format-second-number">
						<xsl:with-param name="date" select="$date" />
						<xsl:with-param name="prefix" select="'0'" />
					</xsl:call-template>
				</xsl:when>
				<xsl:when test="starts-with($format, '#_s;')">
					<xsl:call-template name="format-second-number">
						<xsl:with-param name="date" select="$date" />
						<xsl:with-param name="prefix" select="' '" />
					</xsl:call-template>
				</xsl:when>
				<xsl:when test="starts-with($format, '#s;')">
					<xsl:call-template name="format-second-number">
						<xsl:with-param name="date" select="$date" />
					</xsl:call-template>
				</xsl:when>
				
				<xsl:when test="starts-with($format, '#0m;')">
					<xsl:call-template name="format-minute-number">
						<xsl:with-param name="date" select="$date" />
						<xsl:with-param name="prefix" select="'0'" />
					</xsl:call-template>
				</xsl:when>
				<xsl:when test="starts-with($format, '#_m;')">
					<xsl:call-template name="format-minute-number">
						<xsl:with-param name="date" select="$date" />
						<xsl:with-param name="prefix" select="' '" />
					</xsl:call-template>
				</xsl:when>
				<xsl:when test="starts-with($format, '#m;')">
					<xsl:call-template name="format-minute-number">
						<xsl:with-param name="date" select="$date" />
					</xsl:call-template>
				</xsl:when>
				
				<xsl:when test="starts-with($format, '#0h;')">
					<xsl:call-template name="format-hour-number">
						<xsl:with-param name="date" select="$date" />
						<xsl:with-param name="prefix" select="'0'" />
						<xsl:with-param name="mode" select="12" />
					</xsl:call-template>
				</xsl:when>
				<xsl:when test="starts-with($format, '#_h;')">
					<xsl:call-template name="format-hour-number">
						<xsl:with-param name="date" select="$date" />
						<xsl:with-param name="prefix" select="' '" />
						<xsl:with-param name="mode" select="12" />
					</xsl:call-template>
				</xsl:when>
				<xsl:when test="starts-with($format, '#h;')">
					<xsl:call-template name="format-hour-number">
						<xsl:with-param name="date" select="$date" />
						<xsl:with-param name="mode" select="12" />
					</xsl:call-template>
				</xsl:when>
				<xsl:when test="starts-with($format, '#0H;')">
					<xsl:call-template name="format-hour-number">
						<xsl:with-param name="date" select="$date" />
						<xsl:with-param name="prefix" select="'0'" />
						<xsl:with-param name="mode" select="24" />
					</xsl:call-template>
				</xsl:when>
				<xsl:when test="starts-with($format, '#_H;')">
					<xsl:call-template name="format-hour-number">
						<xsl:with-param name="date" select="$date" />
						<xsl:with-param name="prefix" select="' '" />
						<xsl:with-param name="mode" select="24" />
					</xsl:call-template>
				</xsl:when>
				<xsl:when test="starts-with($format, '#H;')">
					<xsl:call-template name="format-hour-number">
						<xsl:with-param name="date" select="$date" />
						<xsl:with-param name="mode" select="24" />
					</xsl:call-template>
				</xsl:when>
				
				<!--
					Just some filler text:
				-->
				<xsl:otherwise>
					<xsl:value-of select="substring($format, 1, 1)" />
				</xsl:otherwise>
			</xsl:choose>
		</xsl:variable>
		
		<xsl:value-of select="$out" />
		
		<xsl:if test="$skip > 0">
			<xsl:call-template name="date-controller">
				<xsl:with-param name="date" select="$date" />
				<xsl:with-param name="format" select="substring($format, 1 + number($skip))" />
			</xsl:call-template>
		</xsl:if>
	</xsl:template>
	
	<xsl:template name="format-day-number">
		<xsl:param name="date" />
		<xsl:param name="prefix" select="''" />
		
		<xsl:variable name="day" select="number(substring($date, 9, 2))" />
		
		<xsl:value-of select="format-number($day, concat($prefix, '0'))" />
	</xsl:template>
	
	<xsl:template name="format-day-year">
		<xsl:param name="date" />
		<xsl:param name="prefix" select="'-'" />
		
		<xsl:variable name="day" select="date:day-in-year($date)" />
		
		<xsl:choose>
			<xsl:when test="string-length($day) = 2">
				<xsl:value-of select="format-number($day, concat($prefix, '00'))" />
			</xsl:when>
			<xsl:when test="string-length($day) = 1">
				<xsl:value-of select="format-number($day, concat($prefix, $prefix, '0'))" />
			</xsl:when>
			<xsl:otherwise>
				<xsl:value-of select="$day" />
			</xsl:otherwise>
		</xsl:choose>
	</xsl:template>
	
	<xsl:template name="format-day-suffix">
		<xsl:param name="date" />
		<xsl:param name="case" select="'lower'" />
		
		<xsl:variable name="day" select="substring($date, 9, 2)" />
		<xsl:variable name="day-suffix">
			<xsl:choose>
				<xsl:when test="(substring($day, 2) = 1) and not(substring($day, 1, 1) = 1)">st</xsl:when>
				<xsl:when test="(substring($day, 2) = 2) and not(substring($day, 1, 1) = 1)">nd</xsl:when>
				<xsl:when test="(substring($day, 2) = 3) and not(substring($day, 1, 1) = 1)">rd</xsl:when>
				<xsl:otherwise>th</xsl:otherwise>
			</xsl:choose>
		</xsl:variable>
		
		<xsl:choose>
			<xsl:when test="$case = 'upper'">
				<xsl:value-of select="translate($day-suffix, 'stndrh', 'STNDRH')" />
			</xsl:when>
			<xsl:otherwise>
				<xsl:value-of select="$day-suffix" />
			</xsl:otherwise>
		</xsl:choose>
	</xsl:template>
	
	<xsl:template name="format-day-name">
		<xsl:param name="date" />
		
		<xsl:value-of select="document('')/*/date:days/date:day[@id = date:day-in-week($date)]" />
	</xsl:template>
	
	<xsl:template name="format-day-shorthand">
		<xsl:param name="date" />
		
		<xsl:value-of select="document('')/*/date:days/date:day[@id = date:day-in-week($date)]/@shorthand" />
	</xsl:template>
	
	<xsl:template name="format-week-month">
		<xsl:param name="date" />
		<xsl:param name="prefix" select="''" />
		
		<xsl:variable name="week" select="date:week-in-month($date)" />
		
		<xsl:value-of select="format-number($week, concat($prefix, '0'))" />
	</xsl:template>
	
	<xsl:template name="format-week-year">
		<xsl:param name="date" />
		<xsl:param name="prefix" select="''" />
		
		<xsl:variable name="week" select="date:week-in-year($date)" />
		
		<xsl:value-of select="format-number($week, concat($prefix, '0'))" />
	</xsl:template>
	
	<xsl:template name="format-month-number">
		<xsl:param name="date" />
		<xsl:param name="prefix" select="''" />
		
		<xsl:variable name="month" select="number(substring($date, 6, 2))" />
		
		<xsl:value-of select="format-number($month, concat($prefix, '0'))" />
	</xsl:template>
	
	<xsl:template name="format-month-name">
		<xsl:param name="date" />
		
		<xsl:value-of select="document('')/*/date:months/date:month[date:month-in-year($date)]" />
	</xsl:template>
	
	<xsl:template name="format-month-shorthand">
		<xsl:param name="date" />
		
		<xsl:value-of select="document('')/*/date:months/date:month[date:month-in-year($date)]/@shorthand" />
	</xsl:template>
	
	<xsl:template name="format-year-number">
		<xsl:param name="date" />
		<xsl:param name="offset" select="3" />
		
		<xsl:variable name="year" select="substring($date, 1, 4)" />
		
		<xsl:value-of select="substring($year, $offset)" />
	</xsl:template>
	
	<xsl:template name="format-time-suffix">
		<xsl:param name="date" />
		<xsl:param name="case" select="'lower'" />
		
		<xsl:variable name="hour" select="number(substring-before($date/@time, ':'))" />
		<xsl:variable name="suffix">
			<xsl:choose>
				<xsl:when test="$hour &lt; 12">am</xsl:when>
				<xsl:otherwise>pm</xsl:otherwise>
			</xsl:choose>
		</xsl:variable>
		
		<xsl:choose>
			<xsl:when test="$case = 'upper'">
				<xsl:value-of select="translate($suffix, 'apm', 'APM')" />
			</xsl:when>
			<xsl:otherwise>
				<xsl:value-of select="$suffix" />
			</xsl:otherwise>
		</xsl:choose>
	</xsl:template>
	
	<xsl:template name="format-second-number">
		<xsl:param name="date" />
		<xsl:param name="prefix" select="''" />
		
		<xsl:variable name="second-raw" select="number(substring-after(substring-after($date/@time, ':'), ':'))" />
		<xsl:variable name="second">
			<xsl:choose>
				<xsl:when test="$second-raw">
					<xsl:value-of select="$second-raw" />
				</xsl:when>
				<xsl:otherwise>0</xsl:otherwise>
			</xsl:choose>
		</xsl:variable>
		
		<xsl:value-of select="format-number($second, concat($prefix, '0'))" />
	</xsl:template>
	
	<xsl:template name="format-minute-number">
		<xsl:param name="date" />
		<xsl:param name="prefix" select="''" />
		
		<xsl:variable name="minute-raw">
			<xsl:choose>
				<xsl:when test="substring-before(substring-after($date/@time, ':'), ':')">
					<xsl:value-of select="substring-before(substring-after($date/@time, ':'), ':')" />
				</xsl:when>
				<xsl:otherwise>
					<xsl:value-of select="substring-after($date/@time, ':')" />
				</xsl:otherwise>
			</xsl:choose>
		</xsl:variable>
		<xsl:variable name="minute">
			<xsl:choose>
				<xsl:when test="number($minute-raw)">
					<xsl:value-of select="$minute-raw" />
				</xsl:when>
				<xsl:otherwise>0</xsl:otherwise>
			</xsl:choose>
		</xsl:variable>
		
		<xsl:value-of select="format-number($minute, concat($prefix, '0'))" />
	</xsl:template>
	
	<xsl:template name="format-hour-number">
		<xsl:param name="date" />
		<xsl:param name="prefix" select="''" />
		<xsl:param name="mode" />
		
		<xsl:variable name="hour-raw" select="number(substring-before($date/@time, ':'))" />
		<xsl:variable name="hour">
			<xsl:choose>
				<xsl:when test="$mode = 12">
					<xsl:value-of select="$hour-raw mod 12" />
				</xsl:when>
				<xsl:otherwise>
					<xsl:value-of select="$hour-raw" />
				</xsl:otherwise>
			</xsl:choose>
		</xsl:variable>
		
		<xsl:value-of select="format-number(number($hour), concat($prefix, '0'))" />
	</xsl:template>
</xsl:stylesheet>

Discuss this XSLT Utility

Symphony • Open Source XSLT CMS

Server Requirements

  • PHP 5.3-5.6 or 7.0-7.3
  • PHP's LibXML module, with the XSLT extension enabled (--with-xsl)
  • MySQL 5.5 or above
  • An Apache or Litespeed webserver
  • Apache's mod_rewrite module or equivalent

Compatible Hosts

Sign in

Login details