Date conversion YYYYMMDD to YYYY-MM-DD - xslt

I have a date string in format YYYYMMDD for example 20140330
In xsl 1.0 I want to convert the date string to format YYYY-MM-DD for example 2014-03-30
I tried using several date functions but it did not work.
Can anyone help me to convert the date ?

You can use the substring function. Given the following input XML:
<root>20140330</root>
and the following stylesheet:
<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>
it outputs:
2014-03-30

Related

Convert week number date YY-WW-DW into standard xslt date format YYYY-MM-DD

How can be converted week date YYWWWD, where YY - year, WW - week number and WD - week day 1-7 to a standard format YYYY-MM-DD for ISO 8601 using xslt 3.
Example: 21133
Year: 21
Week: 13
Week Day: 3 (Wednesday)
converted to 2021-03-31
Input:
<Line>
<week>2113</week>
<day>3</day>
</Line>
Output:
<Line>
<Date>2021-03-31</Date>
</Line>
I tried calculation rules, but struggling with the logic for the dates around New Year like the case 20537 to be converted to 2021-01-03.
Here is an example you could use as your starting point. It converts dates in ISO week date format to standard YYYY-MM-DD date format:
XML
<input>
<ISO-week-date>2006-W02-7</ISO-week-date>
<ISO-week-date>2021-W13-3</ISO-week-date>
<ISO-week-date>2020-W53-7</ISO-week-date>
</input>
XSLT 2.0
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xs">
<xsl:output method="xml" version="1.0" encoding="utf-8" indent="yes"/>
<xsl:template match="/input">
<output>
<xsl:for-each select="ISO-week-date">
<!-- extract ISO-week-date components -->
<xsl:variable name="year" select="substring(., 1, 4)"/>
<xsl:variable name="week" select="xs:integer(substring(., 7, 2))"/>
<xsl:variable name="weekday" select="xs:integer(substring(., 10, 1))"/>
<!-- calculate base Sunday -->
<xsl:variable name="base" select="xs:date(concat($year, '-01-04'))"/>
<xsl:variable name="base-weekday" select="xs:integer(format-date($base, '[F1]'))"/>
<xsl:variable name="base-sunday" select="$base - $base-weekday * xs:dayTimeDuration('P1D')"/>
<!-- calculate standard date -->
<xsl:variable name="target-date" select="$base-sunday + ($week - 1) * xs:dayTimeDuration('P7D') + $weekday * xs:dayTimeDuration('P1D')"/>
<date>
<xsl:value-of select="$target-date"/>
</date>
</xsl:for-each>
</output>
</xsl:template>
</xsl:stylesheet>
Result
<?xml version="1.0" encoding="utf-8"?>
<output>
<date>2006-01-15</date>
<date>2021-03-31</date>
<date>2021-01-03</date>
</output>
If your week numbers follow the same convention as the ISO 8601 date and time standard, then you only need to adjust the parts that extract the input components.
Of course, if you need this in more than one place, you can turn this into a function.

How to change all decimal to Zeroes using XSL

How to change all decimal value to zeroes in XSL
Example value:
from : 9876.123
to : 9876.000
Well,
floor(9876.123)
returns:
9876
and:
format-number(floor(9876.123), '#.000')
returns:
9876.000
I don't see why this would be useful, but in case you do want to preserve the number of decimal places, I would use:
format-number(floor($amount), translate($amount, '123456789', '000000000'))
In case the number of digits after the decimal point is unknown in advance, use:
concat(substring-before(., '.'),
'.',
translate(substring-after(., '.'), '123456789', '000000000'))
Here is a complete XSLT transformation example:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="d">
<xsl:value-of select=
"concat(substring-before(., '.'),
'.',
translate(substring-after(.,'.'), '123456789','000000000'))"/>
</xsl:template>
</xsl:stylesheet>
When this transformation is applied on the following XML document:
<t>
<d>9876.1</d>
<d>9876.12</d>
<d>9876.123</d>
<d>9876.1234</d>
<d>9876.12345</d>
<d>9876.123456</d>
<d>9876.1234567</d>
<d>9876.12345678</d>
<d>9876.123456789</d>
</t>
the wanted, correct result is produced:
9876.0
9876.00
9876.000
9876.0000
9876.00000
9876.000000
9876.0000000
9876.00000000
9876.000000000
Update
Someone requested that integer values (not containing decimal point) are also processed correctly (copied intact).
I also added to this that negative values and / or currency denominations should also be processed correctly.
Although this falls outside the scope of the current problem, here is again a single XPath 1.0 expression that produces the wanted result:
concat(substring-before(concat(., '.'), '.'),
translate(., '+-$0123456789', ''),
translate(substring-after(.,'.'), '123456789','000000000'))
And here again is the complete transformation:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="d">
<xsl:value-of select=
"concat(substring-before(concat(., '.'), '.'),
translate(., '+-$0123456789', ''),
translate(substring-after(.,'.'), '123456789','000000000'))"/>
</xsl:template>
</xsl:stylesheet>
When this transformation is applied on the following XML document:
<t>
<d>-$1.234</d>
<d>-1.234</d>
<d>-.234</d>
<d>9876</d>
<d>9876.1</d>
<d>9876.12</d>
<d>9876.123</d>
<d>9876.1234</d>
<d>9876.12345</d>
<d>9876.123456</d>
<d>9876.1234567</d>
<d>9876.12345678</d>
<d>9876.123456789</d>
</t>
the wanted, correct result is produced:
-$1.000
-1.000
-.000
9876
9876.0
9876.00
9876.000
9876.0000
9876.00000
9876.000000
9876.0000000
9876.00000000
9876.000000000

dateTime to Epoch and vice versa xslt

I have been trying to convert a given dateTime to epoch time and also a given epoch time to dateTime. I am quite new to xslt and have been struggling with this quite for some time, it is not giving me back any results. Here is my xslt so far
<xsl:stylesheet version="1.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:ns0="http://www.NoPreAuth.org"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
exclude-result-prefixes="xsi xsl ns0 xsd">
<xsl:template match="/">
<xsl:variable name="date1">
<xsl:value-of select="/ns0:NoAuthInput/ns0:StartDate"/>
</xsl:variable>
<xsl:variable name="date2">
<xsl:value-of select="/ns0:NoAuthInput/ns0:EndDate"/>
</xsl:variable>
<ns0:NoPreAuthInput>
<ns0:Product>
<xsl:value-of select="/ns0:NoAuthInput/ns0:Product"/>
</ns0:Product>
<!-- datTime to epoch -->
<ns0:END_T>
<xsl:value-of select= "(('$date1') - xsd:dateTime('1970-01-01T00:00:00') ) div xsd:dayTimeDuration('PT1S') "/>
</ns0:END_T>
<!-- epoch To datTime -->
<ns0:Closed_T>
<xsl:value-of select= "(('$date2') + xsd:dateTime('1970-01-01T00:00:00') ) * xsd:dayTimeDuration('PT1S') "/>
</ns0:Closed_T>
</ns0:NoPreAuthInput>
</xsl:template>
</xsl:stylesheet>
and the xml which I am trying to convert is:
<?xml version="1.0" encoding="UTF-8" ?>
<NoAuthInput xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.NoAuth.org
xmlns="http://www.NoAuth.org">
<Product>ABC</Product>
<StartDate>2015-10-05T15:52:40.782</StartDate>
<EndDate>1444150760</EndDate>
</NoAuthInput>
any help on this much appreciated. Thanks
To convert Unix time to ISO 8601 date-time:
<xsl:value-of select="xs:dateTime('1970-01-01T00:00:00') + xs:dayTimeDuration(concat('PT', UnixTime, 'S'))"/>
To convert ISO 8601 date-time to Unix time;
<xsl:value-of select="floor((xs:dateTime(ISODateTime) - xs:dateTime('1970-01-01T00:00:00')) div xs:dayTimeDuration('PT1S')) "/>
Requires XSLT 2.0.
Working demo: http://xsltransform.net/94rmq5L
If you are trying to do this in XSLT 1.0 on MSXML (I know the original asker is not):
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0" xmlns:ms="urn:schemas-microsoft-com:xslt" xmlns:msxsl="urn:schemas-microsoft-com:xslt" xmlns:userCSharp="http://stackoverflow.com/xsltexample">
<xsl:output method="xml" omit-xml-declaration="yes" indent="yes" />
<xsl:template match="/">
<xsl:value-of select="userCSharp:DateToEpoch('1970-01-02')" />
</xsl:template>
<msxsl:script language="CSharp" implements-prefix="userCSharp"><![CDATA[
public string DateToEpoch(string s)
{
DateTime dt = DateTime.Parse(s);
DateTime epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
return (dt - epoch).TotalSeconds.ToString();
}
]]></msxsl:script>
</xsl:stylesheet>
Replace the '1970-01-02' with whatever text node you want and this should work, as long as that node was a valid date time. If not, it's easy enough to write up another simple method to do that using DateTime.Parse/TryParse. The output of this template (against any valid XML) would be 86400. Note that it's best to define methods in a CDATA node to avoid needing to escape quotes or angle brackets (this code doesn't happen to use any but might be extended to for some reason).

XSLT - format Date - remove milliseconds

I am using XSLT to create XML file. A Date-time has milliseconds. I need to have the output XML without milliseconds.
Format needs to be YYYY-MM-DDTHH:MM:SS
For example:
XML shows date as: 2012-12-341T09:26:53.132-0500
But this needs to be: 2012-12-341T09:26:53
If all of the values are dateTime and have a ., you could use substring-before():
substring-before('2012-12-341T09:26:53.132-0500', '.')
Of you could use substring() to select the first 20 characters:
substring('2012-12-341T09:26:53.132-0500', 0, 21)
If you are using XSLT2, see this function: http://www.w3.org/TR/xslt20/#function-format-dateTime. This picture string should give you what you want:
format-dateTime($dateTime,'[Y0001]-[M01]-[D01]T[H01]:[m01]:[s01]')
This XPath expression produces the wanted result regardless whether the string contains a dot or a hyphen or both dot and hyphen, or none, and doesn't rely on the number of digits used for year, month, day:
substring-before(concat(substring-before(concat(substring-after(.,'T'),
'.'),
'.'),
'-'),
'-')
Here is a simple XSLT transformation that uses this XPath expression:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="node()|#*">
<xsl:copy>
<xsl:apply-templates select="node()|#*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="dt/text()">
<xsl:value-of select="substring-before(., 'T')"/>
<xsl:text>T</xsl:text>
<xsl:value-of select=
"substring-before(concat(substring-before(concat(substring-after(.,'T'),
'.'),
'.'),
'-'),
'-')
"/>
</xsl:template>
</xsl:stylesheet>
When this transformation is applied on this test XML document:
<t>
<dt>2012-12-341T09:26:53.132-0500</dt>
<dt>2012-12-355T09:34:56</dt>
<dt>2012-12-355T09:34:56-0500</dt>
<dt>2012-12-13T9:34:5-0500</dt>
<dt>2012-12-344T09:12:34.378-0500</dt>
</t>
the wanted, correct result is produced:
<t>
<dt>2012-12-341T09:26:53</dt>
<dt>2012-12-355T09:34:56</dt>
<dt>2012-12-355T09:34:56</dt>
<dt>2012-12-13T9:34:5</dt>
<dt>2012-12-344T09:12:34</dt>
</t>
Explanation:
Proper application of sentinels.

XSLT date conversion - data format change

What's the options to show/output date in HTML in some sort of readable format. I mean if I simply show value of date_last_activity it looks wierd :S
So my question IS does XSLT offers any date format conversions at all?
XML:
<date_last_activity format="MMDDCCYY">04132012</date_last_activity>
XLS template:
<xsl:value-of select="date_last_activity"/>
HTML:
04132012
Would rather like it to look like 04/13/2012...
I readed a lot on XSLT one, I guess it's possible to make "template" => formatDate... but no idea where to start :S
This transformation:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="date_last_activity">
<xsl:value-of select=
"concat(
substring(.,
string-length(substring-before(#format, 'MM'))+1,
2
),
'/',
substring(.,
string-length(substring-before(#format, 'DD'))+1,
2
),
'/',
substring(.,
string-length(substring-before(#format, 'CCYY'))+1,
4
)
)"/>
</xsl:template>
</xsl:stylesheet>
when applied to the provided XML document:
<date_last_activity format="MMDDCCYY">04132012</date_last_activity>
produces the wanted, correct result:
04/13/2012
When the same transformation is applied to the following XML document:
<date_last_activity format="CCYYDDMM">20121304</date_last_activity>
the same correct result is produced:
04/13/2012
XSLT 2.0 offers the function format-date(). However, before using it you will need to convert your date to ISO format, YYYY-MM-DD, which can be done using concat and substring.
If you're still stuck with XSLT 1.0, there's a library of date-handling functions and templates available at www.exslt.org.
If you need to do it n more than one place, create a named template somewhere in your xsl
EDIT: template didn't appear because of wrong formatting...
<xsl:template name="formats_date">
<xsl:param name="raw_date" />
<xsl:value-of select="concat( substring( $raw_date, 0, 2 ), '/', substring( $raw_date, 2, 2 ), '/', substring( $raw_date, 4 ) )" />
</xsl:template>
Then apply it as
<xsl:call-template name="formats_date">
<xsl:with-param name="raw_date" select="date_last_activity" />
</xsl:call-template/>
Otherwise you can just do the xsl:value-of concat... stuff directly where you need it