Monday, August 24, 2020

Date Functions in XSLT

 

Date Functions in XSLT

In XSLT (eXtensible Stylesheet Language Transformations), you can use various functions to manipulate and format dates. Here are some common date functions and techniques in XSLT:

1. Current Date and Time:
To get the current date and time, you can use the current-dateTime() function:
<xsl:value-of select="current-dateTime()"/>

2. Date Formatting:
To format a date, you can use the format-date() function.

example:
<xsl:value-of select="format-date(current-dateTime(), '[D01]/[M01]/[Y] [H01]:[m01]:[s01] [P]')"/>

This will format the current date and time as "DD/MM/YYYY HH:MM:SS AM/PM".

3. Extracting Parts of a Date:
To extract specific parts of a date (year, month, day, etc.), you can use functions like:

year-from-dateTime(dateTime): Extracts the year from a dateTime.
month-from-dateTime(dateTime): Extracts the month from a dateTime.
day-from-dateTime(dateTime): Extracts the day from a dateTime.
hours-from-dateTime(dateTime): Extracts the hours from a dateTime.
minutes-from-dateTime(dateTime): Extracts the minutes from a dateTime.
seconds-from-dateTime(dateTime): Extracts the seconds from a dateTime.

example:
<xsl:value-of select="year-from-dateTime(current-dateTime())"/>

4. Duration Functions:
years-from-duration(duration): Extracts the number of years from a duration.
months-from-duration(duration): Extracts the number of months from a duration.
days-from-duration(duration): Extracts the number of days from a duration.
hours-from-duration(duration): Extracts the number of hours from a duration.
minutes-from-duration(duration): Extracts the number of minutes from a duration.
seconds-from-duration(duration): Extracts the number of seconds from a duration.

5. Date Arithmetic:
XSLT 2.0 introduced functions like adjust-dateTime-to-timezone() and adjust-dateTime-for-duration() that allow you to perform date arithmetic operations.

adjust-dateTime-to-timezone(dateTime, timezone): Adjusts the given dateTime value to the specified timezone.
adjust-dateTime-to-timezone(dateTime): Adjusts the given dateTime value to the implicit timezone.
adjust-dateTime-for-duration(dateTime, duration): Adjusts the given dateTime value by adding the specified duration.

6. Date Comparison:
You can compare dates using standard comparison operators (<, >, =, !=). 

example:
<xsl:if test="current-dateTime() &gt;= xs:dateTime('2023-01-01T00:00:00Z')">
    <!-- Do something if the current date is on or after January 1, 2023 -->
</xsl:if>

7. Custom Date Functions:
You can also create your own custom date functions in XSLT. For example, a template that converts a date from one format to another.

<xsl:template match="date">
    <xsl:variable name="formattedDate">
        <xsl:call-template name="formatDate">
            <xsl:with-param name="dateString" select="."/>
        </xsl:call-template>
    </xsl:variable>
    <formattedDate><xsl:value-of select="$formattedDate"/></formattedDate>
</xsl:template>


<xsl:template name="formatDate">
    <xsl:param name="dateString"/>
    <!-- Date formatting logic goes here -->
</xsl:template>

In this example, the <date> element's text content is passed to the formatDate template, which can then manipulate the date as needed before returning the formatted result.


Convert DD-MMM-YYYY to YYYYMMDD format in xslt:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> 
  <xsl:strip-space elements="*"/>
  <xsl:output method="xml" indent="yes"/> 
  <xsl:template match="/root">
    <xsl:copy>
      <xsl:apply-templates/>
    </xsl:copy>
  </xsl:template> 
  <xsl:template match="date">
    <xsl:copy>
      <xsl:call-template name="date">
        <xsl:with-param name="dd-mmm-yyyy" select="."/>
      </xsl:call-template>
    </xsl:copy>
  </xsl:template> 
  <xsl:template name="date">
    <xsl:param name="dd-mmm-yyyy"/>
    <xsl:variable name="dd" select="substring-before($dd-mmm-yyyy, '-')"/>
    <xsl:variable name="mmm-yyyy" select="substring-after($dd-mmm-yyyy, '-')"/>
    <xsl:variable name="mmm" select="substring-before($mmm-yyyy, '-')"/>
    <xsl:variable name="yyyy" select="substring-after($mmm-yyyy, '-')"/>
    <xsl:value-of select="$yyyy"/>
    <xsl:choose>
      <xsl:when test="$mmm = 'JAN'">01</xsl:when>
      <xsl:when test="$mmm = 'FEB'">02</xsl:when>
      <xsl:when test="$mmm = 'MAR'">03</xsl:when>
      <xsl:when test="$mmm = 'APR'">04</xsl:when>
      <xsl:when test="$mmm = 'MAY'">05</xsl:when>
      <xsl:when test="$mmm = 'JUN'">06</xsl:when>
      <xsl:when test="$mmm = 'JUL'">07</xsl:when>
      <xsl:when test="$mmm = 'AUG'">08</xsl:when>
      <xsl:when test="$mmm = 'SEP'">09</xsl:when>
      <xsl:when test="$mmm = 'OCT'">10</xsl:when>
      <xsl:when test="$mmm = 'NOV'">11</xsl:when>
      <xsl:when test="$mmm = 'DEC'">12</xsl:when>
    </xsl:choose>
    <xsl:value-of select="$dd"/>
  </xsl:template> 
</xsl:stylesheet>

Applied to this XML data

<?xml version="1.0" encoding="UTF-8"?>
<root>
  <date>10-JAN-2013</date>
  <date>04-JUL-1776</date>
  <date>31-DEC-1999</date>
</root>

Produces this output

<?xml version="1.0" encoding="utf-8"?>
<root>
   <date>20130110</date>
   <date>17760704</date>
   <date>19991231</date>
</root>

This template simply converts from dd/MM/yyyy to yyyy-MM-dd; and also from dd/MM/yyyy HH:mm:ss to yyyy-MM-ddTHH:mm:ss.

<!--

  Template Name: Date

  Description: Takes a date in the format dd/MM/yyyy and outputs it in the format yyyy-mm-dd

  Additionally will take a datetime in the format dd/MM/yyyy HH:mm:ss and output in the format

 yyyy-MM-ddTHH:mm:ss

  -->

  <xsl:template name="date">
    <xsl:param name="slashFormattedDate"/>
    <xsl:param name="hasTime"/>
    <xsl:variable name="dd" select="substring-before($slashFormattedDate, '/')"/>
    <xsl:variable name="monthYear" select="substring-after($slashFormattedDate, '/')"/>
    <xsl:variable name="mm" select="substring-before($monthYear, '/')"/>
    <xsl:variable name="yyyyTemp" select="substring-after($monthYear, '/')"/>
    <xsl:variable name="yyyy">
      <xsl:choose>
        <xsl:when test="$hasTime='Y'">
          <xsl:value-of select="substring-before($yyyyTemp, ' ')"/>
        </xsl:when>
        <xsl:otherwise>
          <xsl:value-of select="$yyyyTemp"/>
        </xsl:otherwise>
      </xsl:choose>
    </xsl:variable>
    <xsl:choose>
      <xsl:when test="$hasTime='Y'">
        <xsl:value-of select="$yyyy"/>-<xsl:value-of select="$mm"/>-<xsl:value-of select="$dd"/>T<xsl:value-of select="substring-after($yyyyTemp, ' ')"/>
      </xsl:when>
      <xsl:otherwise>
        <xsl:value-of select="$yyyy"/>-<xsl:value-of select="$mm"/>-<xsl:value-of select="$dd"/>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>

 

Date Conversion YYYYMMDD to YYYY-MM-DD

<xsl:stylesheet
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    version="1.0"> 
    <xsl:output omit-xml-declaration="yes"/> 
    <xsl:template match="root">
        <xsl:value-of select="concat(substring(., 1, 4), '-', substring(., 5, 2), '-', substring(., 7, 2))"/>
    </xsl:template> 
</xsl:stylesheet> 

Note:

format-date(xs:date('1971-10-18'),'[Y0001]-[M01]-[D01]') which would return 1971-10-18

replace('19711018','(\d{4})(\d{2})(\d{2})','$1-$2-$3').) 

the value comes from an xml its format is "yyyy-mm-dd" and I want to change it to "dd-mm-yyyy" using a version of xslt 1.0 

<td align="center" class="Estilo2">
  <xsl:variable name="dt" select="Valores/Valor/@fechaPagoCuota"/>
  <xsl:value-of select="concat(
    substring($dt,9,2),'-',
    substring($dt,6,2),'-',
    substring($dt,1,4))" />
</td> 

Convert  mm/dd/yyyy or  m/d/yyyy into  yyyy-mm-dd using XSLT 1.0/XPATH 1.0..

Given this input:

<?xml version="1.0"?>
<dates>
  <date>11/12/2012</date>
  <date>3/4/2011</date>
</dates> 

Transformed by this style-sheet

<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/> 
      <xsl:template match="dates">
        <xsl:copy>
        <xsl:apply-templates select="*" />
        </xsl:copy>
      </xsl:template> 
      <xsl:template match="date">
        <xsl:copy>
        <xsl:value-of select="
           concat(
           substring-after(substring-after(.,'/'),'/') , '-',
           format-number( number( substring-before(.,'/')), '00') , '-',
           format-number( substring-before(substring-after(.,'/'),'/'), '00')
           )
          " />
        </xsl:copy>
      </xsl:template> 
</xsl:stylesheet>

 will produce this desired output ...

<dates>
 <date>2012-11-12</date>
 <date>2011-03-04</date>
</dates> 

Or

My XSLT shown below should work. It does not use hard-coded lengths or indexes, but instead splits the date string on '/' to work out where the day, month and year components are.

XSLT: 

<?xml version="1.0" encoding="utf-8"?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" /> 
    <xsl:template match="/">
        <xsl:apply-templates />
    </xsl:template> 
        <!-- match the date and invoke formatDate to format it -->
    <xsl:template match="date">
        <xsl:element name="date">
            <xsl:call-template name="formatDate">
                <xsl:with-param name="dateParam" select="." />
            </xsl:call-template>
        </xsl:element>
    </xsl:template> 
    <xsl:template name="formatDate">
        <xsl:param name="dateParam" />
        <!-- input format mm/dd/yyyy or m/d/yyyy -->
        <!-- output format yyyy-mm-dd --> 
        <!-- parse out the day, month and year -->
        <xsl:variable name="month" select="substring-before($dateParam,'/')" />
        <xsl:variable name="day" select="substring-before(substring-after($dateParam,'/'),'/')" />
        <xsl:variable name="year" select="substring-after(substring-after($dateParam,'/'),'/')" /> 
        <!-- now print them out. Pad with 0 where necessary. -->
        <xsl:value-of select="$year" />
        <xsl:value-of select="'-'" />
        <xsl:if test="string-length($month) = 1">
            <xsl:value-of select="'0'" />
        </xsl:if>
        <xsl:value-of select="$month" />
        <xsl:value-of select="'-'" />
        <xsl:if test="string-length($day) = 1">
            <xsl:value-of select="'0'" />
        </xsl:if>
        <xsl:value-of select="$day" />
    </xsl:template> 
    <xsl:template match="node()|@*">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()" />
        </xsl:copy>
    </xsl:template> 
</xsl:stylesheet>
Input:

<input>
    <date>04/30/2012</date>
    <date>4/1/2012</date>
</input>

Output:

<?xml version="1.0" encoding="UTF-8"?>
<input>
    <date>2012-04-30</date>
    <date>2012-04-01</date>
</input> 

Format: DD-MMM-YYYY becomes YYYY-MM-DD
Example: 27-AUG-1987 becomes 1987-08-27

Using this XSL v1.0: 

<xsl:template match="/">
  <html lang="en">
    <head>
      <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
      <title>Date Conversion</title>
    </head>
    <body>
      <xsl:call-template name="date">
        <xsl:with-param name="dd-mmm-yyyy" select="$XMLDOC/PersonalInformation/DateOfBirth"/>
      </xsl:call-template>
    </body>
  </html>
</xsl:template> 
<xsl:template name="date">
  <xsl:param name="dd-mmm-yyyy"/> 
  <xsl:variable name="dd" select="substring-before($dd-mmm-yyyy, '-')"/>
  <xsl:variable name="mmm-yyyy" select="substring-after($dd-mmm-yyyy, '-')"/>
  <xsl:variable name="mmm" select="substring-before($mmm-yyyy, '-')"/>
  <xsl:variable name="yyyy" select="substring-after($mmm-yyyy, '-')"/> 
  <xsl:value-of select="$yyyy"/>
  <xsl:text>-</xsl:text> 
  <xsl:choose>
    <xsl:when test="$mmm = 'JAN'">01</xsl:when>
    <xsl:when test="$mmm = 'FEB'">02</xsl:when>
    <xsl:when test="$mmm = 'MAR'">03</xsl:when>
    <xsl:when test="$mmm = 'APR'">04</xsl:when>
    <xsl:when test="$mmm = 'MAY'">05</xsl:when>
    <xsl:when test="$mmm = 'JUN'">06</xsl:when>
    <xsl:when test="$mmm = 'JUL'">07</xsl:when>
    <xsl:when test="$mmm = 'AUG'">08</xsl:when>
    <xsl:when test="$mmm = 'SEP'">09</xsl:when>
    <xsl:when test="$mmm = 'OCT'">10</xsl:when>
    <xsl:when test="$mmm = 'NOV'">11</xsl:when>
    <xsl:when test="$mmm = 'DEC'">12</xsl:when>
  </xsl:choose> 
  <xsl:text>-</xsl:text>
  <xsl:value-of select="$dd"/>
</xsl:template> 
dd/mm/yyyy
<xsl:stylesheet xmlns:ex="http://exslt.org/dates-and-times" extension-element-prefixes="ex">
<xsl:value-of select="ex:date-time()"/>
 
This above code prints as (YYYY,MM,DD) i want in (dd/mm/yyyy) format .
In this case, you can use the substring() function to get the DDMM and YYYY parts from the date returned by ex:date-time() and then using the concat() function, concatenate them with /separator.
 
<xsl:template match="/">
    <xsl:variable name="currDt" select="ex:date-time()" />
    <currDate><xsl:value-of select="$currDt" /></currDate>
    <formattedDate>
        <xsl:value-of select="concat(substring($currDt, 9, 2), '/', substring($currDt, 6, 2), '/', substring($currDt, 1, 4))" />
    </formattedDate>
</xsl:template> 

Output

<currDate>2018-04-13T14:39:14+05:1800000</currDate>
<formattedDate>13/04/2018</formattedDate> 
<xsl:value-of select="format-date(., '[M01]/[D01]/[Y0001]')"/> 
<xsl:function name="ex:date-time">
    <xsl:param name="date"/>
    <xsl:variable name="yy" select="substring-before($date,'-')"/>
    <xsl:variable name="mm" select="substring-before(substring-after($date,'-'),'-')"/>
    <xsl:variable name="dd" select="substring-before(substring-after(substring-after($date,'-'),'-'),'Z')"/>
    <xsl:value-of select="concat($dd,'/',$mm,'/',$yy)"/>

</xsl:function> 

To convert format of datetime into date: with one day before. Todaydate - 1

<xsl:template name="XDaysMinus">
    <xsl:variable name="vToday" select="xp20:current-dateTime()"/>
    <xsl:variable name="vXday" select="xp20:subtract-dayTimeDuration-from-dateTime($vToday,'P1D')"/>
    <xsl:variable name="vXdayFormated" select="xp20:format-dateTime($vXday, '[M01]-[D01]-[Y0001]')"/>
    <xsl:value-of select="$vXdayFormated"/>
  </xsl:template>

Output:
<tns:from_update_date>01-14-2019</tns:from_update_date> 


Q) xslt-subtracting days

<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="/">
  <xsl:variable name="vToday" select="current-date()"/> 
  Today is: <xsl:sequence select="$vToday"/>
  30 days ago it was: <xsl:sequence select=
    "$vToday -30*xs:dayTimeDuration('P1D')"/>
  365 days ago it was: <xsl:sequence select=
    "$vToday -365*xs:dayTimeDuration('P1D')"/>
 </xsl:template>
</xsl:stylesheet>

 
Output:
  Today is: 2010-10-07-07:00
  30 days ago it was: 2010-09-07-07:00
  365 days ago it was: 2009-10-07-07:00

 

Q) subtracts 1 day from the date 2010-01-01 to produce 2009-12-31


<?xml version="1.0"?>
<xsl:stylesheet version="2.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xsl:template match="/">
  <xsl:value-of select="xs:date('2010-01-01') - xs:dayTimeDuration('P1D')" />
</xsl:template>
</xsl:stylesheet> 

Q) Example: Consider that the number of days to be subtracted is 365 and we need it as the default start date. In this case, we have to provide the duration 365 days in xs:dayTimeDuration format i.e. '-P365D'.

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:date="http://exslt.org/dates-and-times"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
extension-element-prefixes="date xs"
exclude-result-prefixes="date xs" version="1.0">
<xsl:output method="xml" version="1.0" encoding="UTF-8" />


    <xsl:template match="/">
      <xsl:variable name="vCurrDate" select="date:date-time()"/>
      <xsl:variable name="vDefaultStDate" select="(date:add($vCurrDate, '-P365D'))"/>
    </xsl:template>
</xsl:stylesheet>

 

Q) Finding the difference between two dateTimes in XSLT



<xsl:variable name="to" select="...to node value"/>
<xsl:variable name="from" select"...from node value"/>
<xsl:value-of select="days-from-duration(xs:dayTimeDuration(xs:date($to) - xs:date($from)))"/> 

Output:

<tns:from_update_date>01-14-2019</tns:from_update_date> 

XSD Date and Time Data Types

Date and time data types are used for values that contain date and time.

The date data type is used to specify a date.

The date is specified in the following form "YYYY-MM-DD" where:

YYYY indicates the year

MM indicates the month

DD indicates the day

Note: All components are required!

<xs:element name=”start” type=”xs:date”/>

<start>2020-08-19</start>

Time Zones

To specify a time zone, you can either enter a date in UTC time by adding a "Z" behind the date

<start>2020-08-19Z</start>

Time Data Type

The time data type is used to specify a time.

The time is specified in the following form "hh:mm:ss" where:

hh indicates the hour

mm indicates the minute

ss indicates the second

Note: All components are required!

<xs:element name=”start” type=”xs:time”/>

<start>09-00-00</start>

DateTime Data Type

The dateTime data type is used to specify a date and a time.

The dateTime is specified in the following form "YYYY-MM-DDThh:mm:ss" where:

YYYY indicates the year

MM indicates the month

DD indicates the day

T indicates the start of the required time section

hh indicates the hour

mm indicates the minute

ss indicates the second

Note: All components are required!

<xs:element name=”startdate” type=”xs:dateTime”/>

<startdate>2020-08-19T09:00:00</startdate>

Duration Data Type

The duration data type is used to specify a time interval.

The time interval is specified in the following form "PnYnMnDTnHnMnS" where:

P indicates the period (required)

nY indicates the number of years

nM indicates the number of months

nD indicates the number of days

T indicates the start of a time section (required if you are going to specify hours, minutes, or seconds)

nH indicates the number of hours

nM indicates the number of minutes

nS indicates the number of seconds

<xs:element name=”period” type=”xs:duration”/>

<period>P5Y</period> //5years

<period>P5Y2M10D</period>  // 5Years,two month,10days

<period> P5Y2M10DT15H</period> //5Years,two month,10days,15hours

<period> P5Y2M10DT15H</period>  //Period of 15 hours


Decimal Data Type

<xs:element name="prize" type="xs:decimal"/>

<prize>999.50</prize>

<prize>+999.5450</prize>

<prize>-999.5230</prize>

<prize>0</prize>

<prize>14</prize

Integer Data Type

<xs:element name="prize" type="xs:integer"/>

<prize>999</prize>

<prize>+999</prize>

<prize>-999</prize>

<prize>0</prize

Boolean Data Type

The Boolean data type is used to specify a true or false value.

Note: Legal values for boolean are true, false, 1 (which indicates true), and 0 (which indicates false).

<xs:attribute name=”desabled” type=”xs:boolean”>

<prize disabled=”true”>999</prize>

 

 


No comments:

Post a Comment

SOA Overview Part-1

  Middleware It provides a mechanism for the process to interact with other processes running on multiple network machines. Advantages...