Please help me with the code of converting given calendar date to Julian date(YYYYMMM) 7 bytes format using xslt please...
Thanks in advance !
The JD Edwards date format (which is often referred to incorrectly as the JDE Julian Date format) is a CYYDDD format, where:
C is a number denoting the century: a value of 0 represents years between 1900 and 1999, a value of 1 years from 2000 to 2099, and so on;
YY denotes the year in the given century;
DDD is the day number in the given year.
Thus, for example, the date of 2019-07-02 would be represented as 119183.
To convert a date in YYYY-MM-DD format to JD Edwards date format using XSLT 1.0, you can use:
<xsl:template name="date-to-JDE">
<xsl:param name="date"/>
<xsl:variable name="year" select="substring($date, 1, 4)"/>
<xsl:variable name="month" select="substring($date, 6, 2)"/>
<xsl:variable name="day" select="substring($date, 9, 2)"/>
<xsl:variable name="C" select="floor($year div 100) - 19"/>
<xsl:variable name="YY" select="$year mod 100"/>
<xsl:variable name="leap" select="not($year mod 4) and $year mod 100 or not($year mod 400)" />
<xsl:variable name="elapsed-months" select="substring('000031059090120151181212243273304334', 3 * ($month - 1) + 1, 3)"/>
<xsl:variable name="DDD" select="$elapsed-months + ($month > 2 and $leap) + $day"/>
<xsl:value-of select="$C * 100000 + $YY * 1000 + $DDD"/>
</xsl:template>
Demo: https://xsltfiddle.liberty-development.net/jyRYYj8
Added:
If you actually need YYYYDDD, then you can simplify the above to:
<xsl:template name="date-to-YYYYDDD">
<xsl:param name="date"/>
<xsl:variable name="year" select="substring($date, 1, 4)"/>
<xsl:variable name="month" select="substring($date, 6, 2)"/>
<xsl:variable name="day" select="substring($date, 9, 2)"/>
<xsl:variable name="leap" select="not($year mod 4) and $year mod 100 or not($year mod 400)" />
<xsl:variable name="elapsed-months" select="substring('000031059090120151181212243273304334', 3 * ($month - 1) + 1, 3)"/>
<xsl:variable name="DDD" select="$elapsed-months + ($month > 2 and $leap) + $day"/>
<xsl:value-of select="$year * 1000 + $DDD"/>
</xsl:template>
In XSLT 2.0, format-date() with picture [Y0001][d001] should give you what you want.
If you can't use XSLT 2.0, see whether your XSLT processor supports the date/time extensions defined at www.exslt.org
Related
I am trying to create an XSLT mapping to get the last(max) day of the previous month.
Eg- If I pass a value of 2019-10-17 to the mapping it should return
2019-09-30. The date format that I am using here is YYYY-MM-DD.
tried to get the month from the current data and subtract it with 1 so that it would return the previous month. But I am not able to get the max date of the last month.
xp20:month-from-dateTime (/ns0:ddSelecCorpoMasterOutputCollection/ns0:ddSelecCorpoMasterOutput/ns0:FROM_DATE_FILTER ) - 1
input- sysdate
o/p- maxdate of previous month
eg- i/p-2019-10-18
o/p- 2019-09-30
Thanks in advance.
Finding the last day of previous month in pure XSLT 1.0:
<xsl:template name="end-of-last-month">
<xsl:param name="date"/>
<!-- extract date components -->
<xsl:variable name="year" select="substring($date, 1, 4)"/>
<xsl:variable name="month" select="substring($date, 6, 2)"/>
<!-- go one month back -->
<xsl:variable name="y" select="$year - ($month = 1)"/>
<xsl:variable name="m" select="($month + 10) mod 12 + 1"/>
<!-- get month length -->
<xsl:variable name="cal" select="'312831303130313130313031'"/>
<xsl:variable name="leap" select="not($y mod 4) and $y mod 100 or not($y mod 400)"/>
<xsl:variable name="month-length" select="substring($cal, 2*($m - 1) + 1, 2) + ($m=2 and $leap)" />
<!-- output -->
<xsl:value-of select="$y" />
<xsl:value-of select="format-number($m, '-00')" />
<xsl:text>-</xsl:text>
<xsl:value-of select="$month-length" />
</xsl:template>
Example:
XML
<input>
<date>2019-01-15</date>
<date>2019-02-15</date>
<date>2019-03-15</date>
<date>2019-04-15</date>
<date>2019-05-15</date>
<date>2019-06-15</date>
<date>2019-07-15</date>
<date>2019-08-15</date>
<date>2019-09-15</date>
<date>2019-10-15</date>
<date>2019-11-15</date>
<date>2019-12-15</date>
<date>2020-01-15</date>
<date>2020-02-15</date>
<date>2020-03-15</date>
</input>
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:template match="/input">
<output>
<xsl:for-each select="date">
<end-of-last-month date="{.}">
<xsl:call-template name="end-of-last-month">
<xsl:with-param name="date" select="."/>
</xsl:call-template>
</end-of-last-month>
</xsl:for-each>
</output>
</xsl:template>
<xsl:template name="end-of-last-month">
<xsl:param name="date"/>
<!-- extract date components -->
<xsl:variable name="year" select="substring($date, 1, 4)"/>
<xsl:variable name="month" select="substring($date, 6, 2)"/>
<!-- go one month back -->
<xsl:variable name="y" select="$year - ($month = 1)"/>
<xsl:variable name="m" select="($month + 10) mod 12 + 1"/>
<!-- get month length -->
<xsl:variable name="cal" select="'312831303130313130313031'"/>
<xsl:variable name="leap" select="not($y mod 4) and $y mod 100 or not($y mod 400)"/>
<xsl:variable name="month-length" select="substring($cal, 2*($m - 1) + 1, 2) + ($m=2 and $leap)" />
<!-- output -->
<xsl:value-of select="$y" />
<xsl:value-of select="format-number($m, '-00')" />
<xsl:text>-</xsl:text>
<xsl:value-of select="$month-length" />
</xsl:template>
</xsl:stylesheet>
Result
<?xml version="1.0" encoding="UTF-8"?>
<output>
<end-of-last-month date="2019-01-15">2018-12-31</end-of-last-month>
<end-of-last-month date="2019-02-15">2019-01-31</end-of-last-month>
<end-of-last-month date="2019-03-15">2019-02-28</end-of-last-month>
<end-of-last-month date="2019-04-15">2019-03-31</end-of-last-month>
<end-of-last-month date="2019-05-15">2019-04-30</end-of-last-month>
<end-of-last-month date="2019-06-15">2019-05-31</end-of-last-month>
<end-of-last-month date="2019-07-15">2019-06-30</end-of-last-month>
<end-of-last-month date="2019-08-15">2019-07-31</end-of-last-month>
<end-of-last-month date="2019-09-15">2019-08-31</end-of-last-month>
<end-of-last-month date="2019-10-15">2019-09-30</end-of-last-month>
<end-of-last-month date="2019-11-15">2019-10-31</end-of-last-month>
<end-of-last-month date="2019-12-15">2019-11-30</end-of-last-month>
<end-of-last-month date="2020-01-15">2019-12-31</end-of-last-month>
<end-of-last-month date="2020-02-15">2020-01-31</end-of-last-month>
<end-of-last-month date="2020-03-15">2020-02-29</end-of-last-month>
</output>
Demo: https://xsltfiddle.liberty-development.net/94AbWB5
If you have access to the XPath 2.0 date/time library,
(1) convert to an xs:date
<xsl:variable name="d" select="xs:date($in)"/>
(2) extract the day of the month:
<xsl:variable name="dom" select="day-from-date($d)"/>
(3) subtract this number of days from the date:
<xsl:variable name="result" select="$d - xs:dayTimeDuration('P1D') * $dom"/>
Is there an easy way to format an RSS pubDate
<pubDate>Thu, 28 May 2015 08:00:00 -0400</pubDate>
into:
8:00AM
I'm not all that familiar with date formatting, and I can't for the life of me recall what that time format is, so Google isn't helping me any.
Try it this way:
XSLT 1.0
<xsl:template match="pubDate">
<xsl:variable name="h" select="substring(., 18, 2)"/>
<xsl:variable name="m" select="substring(., 21, 2)"/>
<xsl:variable name="h12" select="($h + 11) mod 12 + 1"/>
<xsl:variable name="am.pm" select="substring('AMPM', 1 + 2*(number($h) > 11), 2)"/>
<xsl:value-of select="concat($h12, ':', $m, $am.pm)"/>
</xsl:template>
General date parsing is quite complex. There were some discussions to add the opposite of fn:format-date() to the standard XPath library 3.0, but did not succeed because of the complexity of the task in the generic case.
I am afraid you are limited to string manipulation here, which in your case is not too bad. For instance:
<xsl:variable name="hours" select="xs:integer(substring($input, 18, 2))"/>
<xsl:variable name="minutes" select="substring($input, 21, 2)"/>
<xsl:sequence select="
if ( $hours ge 12 ) then
concat($hours - 12, ':', $minutes, 'PM')
else
concat($hours, ':', $minutes, 'AM')"/>
Error management has not been added, up to you to add some, depending on how good and homogeneous is your input.
I've got a date format template that I'm passing a date value to in the format YYYYMMDD
The template is the following:
<xsl:template name="formatDate">
<xsl:param name="date" />
<xsl:variable name="year" select="substring($date, 1, 4)" />
<xsl:variable name="month" select="substring($date, 5, 2)" />
<xsl:variable name="day" select="substring($date, 7, 2)" />
<xsl:value-of select="concat($month, '/', $day, '/', $year)" />
</xsl:template>
This would return the string 20131004 as 10/04/2013 which is correct.
What I need to do though is if the $month has a leading zero, to remove it. For example, 20130930 would be 09/30/2013 when I would prefer 9/30/2013.
What's the most efficient way to do that? I could do a choose/when before I set the value of the variable but I'm trying to do it in the proper manner with xslt (I'm still trying to get into it, it's coming along).
Thanks
You could utilize number() function
<xsl:variable name="month" select="number(substring($date, 5, 2))" />
<xsl:variable name="day" select="number(substring($date, 7, 2))" />
It should remove leading zero.
Suppose I have a key defined in an xslt file in SharePoint Designer 2010 as:
<xsl:key name="Years" match="/dsQueryResponse/Rows/Row" use="#Date" />
Where #Date is the column, however instead of #Date, I want to use the value of the following variable:
<xsl:variable name="VarNAme">
<xsl:choose>
<xsl:when test="string-length(#Date) = 8">
<xsl:value-of select="substring(#Date, 5, 4)"></xsl:value-of>
</xsl:when>
<xsl:when test="string-length(#Date) = 9">
<xsl:value-of select="substring(#Date, 6, 4)"></xsl:value-of>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="substring(#Date, 7, 4)"></xsl:value-of>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
If there is a better way (one-liner) to get just the year from a date, I'd welcome that as well. I want to use generate-id to get distinct years (not dates, years).
<xsl:key
name="Years"
match="/dsQueryResponse/Rows/Row"
use="substring(#Date, string-length(#Date) - 3, 4)"
/>
Hint
8 - 3 = 5
9 - 3 = 6
10 - 3 = 7
;-)
Is there a less then kludgey way of finding the difference in days between 2 dates in xslt? If so can you point me in the right direction. I am receiving dates in the format of mm/dd/yyyy.
A nicer (and shorter) alternative for XSLT 1.0 is to compute the equivalent Julian dates and subtract them.
Template:
<xsl:template name="calculate-julian-day">
<xsl:param name="year"/>
<xsl:param name="month"/>
<xsl:param name="day"/>
<xsl:variable name="a" select="floor((14 - $month) div 12)"/>
<xsl:variable name="y" select="$year + 4800 - $a"/>
<xsl:variable name="m" select="$month + 12 * $a - 3"/>
<xsl:value-of select="$day + floor((153 * $m + 2) div 5) + $y * 365 + floor($y div 4) - floor($y div 100) + floor($y div 400) - 32045"/>
Usage:
<xsl:variable name="dateInv" select="'20120406'" />
<xsl:call-template name="calculate-julian-day">
<xsl:with-param name="year" select="substring($date,1,4)"/>
<xsl:with-param name="month" select="substring($date,5,2)"/>
<xsl:with-param name="day" select="substring($date,7,2)"/>
</xsl:call-template>
Repeat for the second date and you'll have two integers. Then, simply subtract them.
This could be easily done using the following expression:
days-from-duration(xs:date('yyyy-MM-dd')-xs:date('yyyy-MM-dd'))
For example:
days-from-duration(xs:date('2012-06-30')-xs:date('2012-06-18'))
will give result of 12
Use XSLT 2.0 (XPath 2.0) for this:
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:my="my:my">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="/">
<xsl:variable name="vDate1"
select="my:dateFromUsDate(/*/d1)"/>
<xsl:variable name="vDate2"
select="my:dateFromUsDate(/*/d2)"/>
<xsl:sequence select=
"($vDate1 - $vDate2) div xs:dayTimeDuration('P1D')"/>
</xsl:template>
<xsl:function name="my:dateFromUsDate" as="xs:date">
<xsl:param name="pUsDate" as="xs:string"/>
<xsl:sequence select=
"xs:date(concat(substring($pUsDate,7,4),
'-',
substring($pUsDate,1,2),
'-',
substring($pUsDate,4,2)
)
)
"/>
</xsl:function>
</xsl:stylesheet>
when this transformation is applied on the following XML document:
<t>
<d1>04/06/2011</d1>
<d2>01/11/2010</d2>
</t>
the wanted, correct result (the difference is 450 days) is produced:
450