πŸ“œ ⬆️ ⬇️

Date conversion to international format (UTC). Template for XSLT versions from 1.0

It was necessary to translate the date in xml files from Moscow time to international time. Initially, the problem was solved by inserting Java squeak, but it took to use only the built-in features of XSLT 1.0.
Immediately I warn commenters that the XSLT 2.0 version, where there is a Date data type, is no good, it needs to be implemented exactly in 1.0.

Download an example, template, result and parser here.

So, the steps to solve the problem:

')
Subtasks:


Original Date Pattern:
DD.MM.YYYY hh: mm: ss
You can easily correct the XSL for your format, just change the cutting sequence and specify the delimiters.

UTC date format:
YYYY-MM-DD hh: mm: ss
Corrected even easier when collecting the final line.

If other time zone offset values ​​are required, it is sufficient to correct them in the MoscowOffsetTime function.

Template use:
<xsl:call-template name= "GetTime" >
<xsl:with-param name= "time" select = "10.15.2010 14:10:17" ></xsl:with-param>
</xsl:call-template>


* This source code was highlighted with Source Code Highlighter .



Actually the template code itself:
<xsl:template name= "GetTime" >
<xsl:param name= "time" ></xsl:param>
<xsl:call-template name= "MoscowDataToUTC" >
<xsl:with-param name= "data" select = "$time" ></xsl:with-param>
</xsl:call-template>
</xsl:template>

<xsl:template name= "MoscowDataToUTC" >
<xsl:param name= "data" />
<xsl:variable name= "vData" >
<xsl:call-template name= "splitEqFirst" >
<xsl:with-param name= "str" select = "$data" ></xsl:with-param>
<xsl:with-param name= "worddiv" select = "' '" />
</xsl:call-template>
</xsl:variable>
<xsl:variable name= "vDataDD" >
<xsl:call-template name= "splitEqFirst" >
<xsl:with-param name= "str" select = "$vData" ></xsl:with-param>
<xsl:with-param name= "worddiv" select = "'.'" />
</xsl:call-template>
</xsl:variable>
<xsl:variable name= "vDataBuf" >
<xsl:call-template name= "splitEqSecond" >
<xsl:with-param name= "str" select = "$vData" ></xsl:with-param>
<xsl:with-param name= "worddiv" select = "'.'" />
</xsl:call-template>
</xsl:variable>
<xsl:variable name= "vDataMM" >
<xsl:call-template name= "splitEqFirst" >
<xsl:with-param name= "str" select = "$vDataBuf" ></xsl:with-param>
<xsl:with-param name= "worddiv" select = "'.'" />
</xsl:call-template>
</xsl:variable>
<xsl:variable name= "vDataYYYY" >
<xsl:call-template name= "splitEqSecond" >
<xsl:with-param name= "str" select = "$vDataBuf" ></xsl:with-param>
<xsl:with-param name= "worddiv" select = "'.'" />
</xsl:call-template>
</xsl:variable>
<xsl:variable name= "vTime" >
<xsl:call-template name= "splitEqSecond" >
<xsl:with-param name= "str" select = "$data" ></xsl:with-param>
<xsl:with-param name= "worddiv" select = "' '" />
</xsl:call-template>
</xsl:variable>
<xsl:variable name= "vTimeHH" >
<xsl:call-template name= "splitEqFirst" >
<xsl:with-param name= "str" select = "$vTime" ></xsl:with-param>
<xsl:with-param name= "worddiv" select = "':'" />
</xsl:call-template>
</xsl:variable>
<xsl:variable name= "vTimeBuf" >
<xsl:call-template name= "splitEqSecond" >
<xsl:with-param name= "str" select = "$vTime" ></xsl:with-param>
<xsl:with-param name= "worddiv" select = "':'" />
</xsl:call-template>
</xsl:variable>
<xsl:variable name= "vTimeMM" >
<xsl:call-template name= "splitEqFirst" >
<xsl:with-param name= "str" select = "$vTimeBuf" ></xsl:with-param>
<xsl:with-param name= "worddiv" select = "':'" />
</xsl:call-template>
</xsl:variable>
<xsl:variable name= "vTimeSS" >
<xsl:call-template name= "splitEqSecond" >
<xsl:with-param name= "str" select = "$vTimeBuf" ></xsl:with-param>
<xsl:with-param name= "worddiv" select = "':'" />
</xsl:call-template>
</xsl:variable>
<!-- -->
<xsl:variable name= "deltaTime" >
<xsl:call-template name= "MoscowOffsetTime" >
<xsl:with-param name= "day" select = "$vDataDD" ></xsl:with-param>
<xsl:with-param name= "hh" select = "$vTimeHH" ></xsl:with-param>
<xsl:with-param name= "month" select = "$vDataMM" ></xsl:with-param>
<xsl:with-param name= "year" select = "$vDataYYYY" ></xsl:with-param>
</xsl:call-template>
</xsl:variable>
<!-- UTC -->
<!-- , , 1-->
<xsl:variable name= "vDataYYYYUTC" >
<xsl:call-template name= "MoscowYearToUTCYear" >
<xsl:with-param name= "hh" select = "$vTimeHH" ></xsl:with-param>
<xsl:with-param name= "day" select = "$vDataDD" ></xsl:with-param>
<xsl:with-param name= "month" select = "$vDataMM" ></xsl:with-param>
<xsl:with-param name= "year" select = "$vDataYYYY" ></xsl:with-param>
<xsl:with-param name= "delta" select = "$deltaTime" ></xsl:with-param>
</xsl:call-template>
</xsl:variable>
<!-- , , -->
<xsl:variable name= "vDataMMUTC" >
<xsl:call-template name= "MoscowMonthToUTCMonth" >
<xsl:with-param name= "hh" select = "$vTimeHH" ></xsl:with-param>
<xsl:with-param name= "day" select = "$vDataDD" ></xsl:with-param>
<xsl:with-param name= "month" select = "$vDataMM" ></xsl:with-param>
<xsl:with-param name= "delta" select = "$deltaTime" ></xsl:with-param>
</xsl:call-template>
</xsl:variable>
<!-- , , -->
<xsl:variable name= "vDataDDUTC" >
<xsl:call-template name= "MoscowDayToUTCDay" >
<xsl:with-param name= "hh" select = "$vTimeHH" ></xsl:with-param>
<xsl:with-param name= "day" select = "$vDataDD" ></xsl:with-param>
<xsl:with-param name= "month" select = "$vDataMM" ></xsl:with-param>
<xsl:with-param name= "year" select = "$vDataYYYY" ></xsl:with-param>
<xsl:with-param name= "delta" select = "$deltaTime" ></xsl:with-param>
</xsl:call-template>
</xsl:variable>
<!-- , delta, , 20-->
<xsl:variable name= "vTimeHHUTC" >
<xsl:call-template name= "MoscowHoutToUTCHour" >
<xsl:with-param name= "hh" select = "$vTimeHH" ></xsl:with-param>
<xsl:with-param name= "hl" select = "$deltaTime" ></xsl:with-param>
</xsl:call-template>
</xsl:variable>
<!-- , 0 -->
<xsl:variable name= "vTimeHHOUT" >
<xsl:call-template name= "ZeroBeforeOneNumber" >
<xsl:with-param name= "num" select = "$vTimeHHUTC" ></xsl:with-param>
</xsl:call-template>
</xsl:variable>
<xsl:variable name= "vDateDDOUT" >
<xsl:call-template name= "ZeroBeforeOneNumber" >
<xsl:with-param name= "num" select = "$vDataDDUTC" ></xsl:with-param>
</xsl:call-template>
</xsl:variable>
<xsl:variable name= "vDataMMOUT" >
<xsl:call-template name= "ZeroBeforeOneNumber" >
<xsl:with-param name= "num" select = "$vDataMMUTC" ></xsl:with-param>
</xsl:call-template>
</xsl:variable>
<!-- UTC -->
<xsl: value -of select = "$vDataYYYYUTC" />-<xsl: value -of select = "$vDataMMOUT" />-<xsl: value -of select = "$vDateDDOUT" /><xsl: value -of select = "' '" /><xsl: value -of select = "$vTimeHHOUT" />:<xsl: value -of select = "$vTimeMM" />:<xsl: value -of select = "$vTimeSS" />
</xsl:template>
<!-- -->
<xsl:template name= "ZeroBeforeOneNumber" >
<xsl:param name= "num" ></xsl:param>
<xsl:choose>
<xsl:when test= "number($num) < 10" >0<xsl: value -of select = "$num" /></xsl:when>
<xsl:otherwise><xsl: value -of select = "$num" /></xsl:otherwise>
</xsl:choose>
</xsl:template>
<!-- -->
<xsl:template name= "MoscowYearToUTCYear" >
<xsl:param name= "hh" ></xsl:param>
<xsl:param name= "day" ></xsl:param>
<xsl:param name= "month" ></xsl:param>
<xsl:param name= "year" ></xsl:param>
<xsl:param name= "delta" ></xsl:param>
<xsl:choose>
<xsl:when test= "(number($hh) + $delta) < 0 and ($day = '01') and ($month='01')" >
<xsl: value -of select = "number($year)-number(1)" />
</xsl:when>
<xsl:otherwise>
<xsl: value -of select = "number($year)" />
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<!-- -->
<xsl:template name= "MoscowMonthToUTCMonth" >
<xsl:param name= "hh" ></xsl:param>
<xsl:param name= "day" ></xsl:param>
<xsl:param name= "month" ></xsl:param>
<xsl:param name= "delta" ></xsl:param>
<xsl:choose>
<xsl:when test= "(number($hh) + $delta) < 0 and ($day = '01')" >
<xsl:choose>
<xsl:when test= "number($month) = 1" >12</xsl:when>
<xsl:otherwise><xsl: value -of select = "number($month)-number(1)" /></xsl:otherwise>
</xsl:choose>
</xsl:when>
<xsl:otherwise>
<xsl: value -of select = "number($month)" />
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<!-- -->
<xsl:template name= "MoscowDayToUTCDay" >
<xsl:param name= "hh" ></xsl:param>
<xsl:param name= "day" ></xsl:param>
<xsl:param name= "month" ></xsl:param>
<xsl:param name= "year" ></xsl:param>
<xsl:param name= "delta" ></xsl:param>
<xsl:choose>
<xsl:when test= "(number($hh) + $delta) < 0" >
<xsl:choose>
<xsl:when test= "number($day) = 1" >
<xsl:call-template name= "CountDaysInMonth" >
<xsl:with-param name= "month" select = "number($month)-1" ></xsl:with-param>
<xsl:with-param name= "year" select = "$year" ></xsl:with-param>
</xsl:call-template>
</xsl:when>
<xsl:otherwise><xsl: value -of select = "number($day)-number(1)" /></xsl:otherwise>
</xsl:choose>
</xsl:when>
<xsl:otherwise><xsl: value -of select = "$day" /></xsl:otherwise>
</xsl:choose>
</xsl:template>
<!-- -->
<xsl:template name= "CountDaysInMonth" >
<xsl:param name= "month" ></xsl:param>
<xsl:param name= "year" ></xsl:param>
<xsl:choose>
<xsl:when test= "($month = 1) or ($month = 3) or ($month = 5) or ($month = 7) or ($month = 8) or ($month = 10) or ($month = 12) or ($month = 0)" >31</xsl:when>
<xsl:when test= "($month = 4) or ($month = 6) or ($month = 9) or ($month = 11)" >30</xsl:when>
<xsl:when test= "($month = 2)" >
<!--. -->
<xsl:choose>
<xsl:when test= "(number($year) mod 4 = 0) and (number($year) mod 100 != 0 or number($year) mod 400 = 0)" >29</xsl:when>
<xsl:otherwise>28</xsl:otherwise>
</xsl:choose>
</xsl:when>
<xsl:otherwise>30</xsl:otherwise>
</xsl:choose>
</xsl:template>
<!-- -->
<xsl:template name= "MoscowHoutToUTCHour" >
<xsl:param name= "hh" />
<xsl:param name= "hl" />
<xsl:variable name= "t" select = "(number($hh)+number($hl))" ></xsl:variable>
<xsl:choose>
<xsl:when test= "number($t) < 0" >
<xsl: value -of select = "number($t)+24" />
</xsl:when>
<xsl:when test= "number($t) > 23" >
<xsl: value -of select = "number($t)-24" />
</xsl:when>
<xsl:otherwise>
<xsl: value -of select = "number($t)" />
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<!-- / -->
<xsl:template name= "MoscowOffsetTime" >
<xsl:param name= "hh" ></xsl:param>
<xsl:param name= "day" ></xsl:param>
<xsl:param name= "month" ></xsl:param>
<xsl:param name= "year" ></xsl:param>
<!-- -->
<xsl:variable name= "dayOfWeek" >
<xsl:call-template name= "DayOfWeek" >
<xsl:with-param name= "day" select = "$day" ></xsl:with-param>
<xsl:with-param name= "month" select = "$month" ></xsl:with-param>
<xsl:with-param name= "year" select = "$year" ></xsl:with-param>
</xsl:call-template>
</xsl:variable>
<!-- -->
<xsl:variable name= "countDayOfMonth" >
<xsl:call-template name= "CountDaysInMonth" >
<xsl:with-param name= "month" select = "$month" ></xsl:with-param>
<xsl:with-param name= "year" select = "$year" ></xsl:with-param>
</xsl:call-template>
</xsl:variable>
<!-- -->
<xsl:variable name= "diffDay" select = "number($countDayOfMonth)-number($day)" />
<!-- -->
<xsl:variable name= "offsetToSun" select = "6-number($dayOfWeek)" />
<!-- -->
<xsl:choose>
<xsl:when test= "number($month) > 3 and number($month) < 10" >-4</xsl:when>
<!-- 7 -->
<xsl:when test= "number($month) = 3 and $diffDay > 7" >
-3
</xsl:when>
<xsl:when test= "number($month) = 10 and $diffDay > 7" >
-4
</xsl:when>
<!-- 7 -->
<xsl:when test= "number($month) = 3 and $offsetToSun > $diffDay " >
-4
</xsl:when>
<xsl:when test= "number($month) = 10 and $offsetToSun > $diffDay " >
-3
</xsl:when>
<!-- -->
<xsl:when test= "number($month) = 3 and ($offsetToSun = 0) and ($diffDay < 7)" >
<xsl:choose>
<xsl:when test= "$hh >= 2" >-4</xsl:when>
<xsl:otherwise>-3</xsl:otherwise>
</xsl:choose>
</xsl:when>
<xsl:when test= "number($month) = 10 and ($offsetToSun = 0) and ($diffDay < 7)" >
<xsl:choose>
<xsl:when test= "$hh >= 3" >-3</xsl:when>
<xsl:otherwise>-4</xsl:otherwise>
</xsl:choose>
</xsl:when>
<xsl:otherwise>-3</xsl:otherwise>
</xsl:choose>
</xsl:template>
<!-- ( )-->
<xsl:template name= "DayOfWeek" >
<xsl:param name= "day" ></xsl:param>
<xsl:param name= "month" ></xsl:param>
<xsl:param name= "year" ></xsl:param>
<xsl:variable name= "gMonth" >
<xsl:choose>
<xsl:when test= "number($month) = 1" >
<xsl: value -of select = "number(13)" />
</xsl:when>
<xsl:when test= "number($month) = 2" >
<xsl: value -of select = "number(14)" />
</xsl:when>
<xsl:otherwise>
<xsl: value -of select = "number($month)" />
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:variable name= "Y" select = "number($year) mod 100" ></xsl:variable>
<xsl:variable name= "Ydiv4" select = "floor($Y div 4)" />
<xsl:variable name= "M26div10" select = "floor(((number($gMonth)+1)*26) div 10)" />
<xsl:variable name= "C" select = "floor($year div 100)" />
<xsl:variable name= "Cdiv4" select = "floor($C div 4)" />
<xsl:variable name= "F" >
<xsl: value -of select = "(number($day)+number($M26div10)+$Y+number($Ydiv4)+number($Cdiv4)+5*$C) mod 7" ></xsl: value -of>
</xsl:variable>
<!-- , =0, ..., =5, =6-->
<xsl:choose>
<xsl:when test= "$F=0" >5</xsl:when>
<xsl:when test= "$F=1" >6</xsl:when>
<xsl:otherwise>
<xsl: value -of select = "number($F)-2" />
</xsl:otherwise>
</xsl:choose>
</xsl:template>

<!-- -->
<xsl:template name= "tokenEq" >
<xsl:param name= "token" />
<xsl: value -of select = "$token" />
</xsl:template>

<xsl:template name= "splitEqFirst" match= "text()" mode= "splitEqFirst" >
<xsl:param name= "str" select = "." />
<xsl:param name= "worddiv" select = "' '" />
<xsl: if test= "contains($str,$worddiv)" >
<xsl:call-template name= "tokenEq" >
<xsl:with-param name= "token" select = "substring-before($str, $worddiv)" />
</xsl:call-template>
</xsl: if >
</xsl:template>

<xsl:template name= "splitEqSecond" match= "text()" mode= "splitEqSecond" >
<xsl:param name= "str" select = "." />
<xsl:param name= "worddiv" select = "' '" />
<xsl: if test= "contains($str,$worddiv)" >
<xsl:call-template name= "tokenEq" >
<xsl:with-param name= "token" select = "substring-after($str, $worddiv)" />
</xsl:call-template>
</xsl: if >
</xsl:template>
<!--β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”-->


* This source code was highlighted with Source Code Highlighter .

Source: https://habr.com/ru/post/106216/


All Articles