source: DCWoRMS/trunk/simulator/xslt/date.add.template.xsl @ 477

Revision 477, 22.0 KB checked in by wojtekp, 13 years ago (diff)
  • Property svn:mime-type set to text/plain
Line 
1<?xml version="1.0"?>
2<xsl:stylesheet version="1.0"
3                xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
4                xmlns:date="http://exslt.org/dates-and-times"
5                extension-element-prefixes="date">
6 
7<date:month-lengths>
8   <date:month>31</date:month>
9   <date:month>28</date:month>
10   <date:month>31</date:month>
11   <date:month>30</date:month>
12   <date:month>31</date:month>
13   <date:month>30</date:month>
14   <date:month>31</date:month>
15   <date:month>31</date:month>
16   <date:month>30</date:month>
17   <date:month>31</date:month>
18   <date:month>30</date:month>
19   <date:month>31</date:month>
20</date:month-lengths>
21
22<xsl:template name="date:add">
23        <xsl:param name="date-time" />
24   <xsl:param name="duration" />
25   <xsl:variable name="dt-neg" select="starts-with($date-time, '-')" />
26   <xsl:variable name="dt-no-neg">
27      <xsl:choose>
28         <xsl:when test="$dt-neg or starts-with($date-time, '+')">
29            <xsl:value-of select="substring($date-time, 2)" />
30         </xsl:when>
31         <xsl:otherwise>
32            <xsl:value-of select="$date-time" />
33         </xsl:otherwise>
34      </xsl:choose>
35   </xsl:variable>
36   <xsl:variable name="dt-no-neg-length" select="string-length($dt-no-neg)" />
37   <xsl:variable name="timezone">
38      <xsl:choose>
39         <xsl:when test="substring($dt-no-neg, $dt-no-neg-length) = 'Z'">Z</xsl:when>
40         <xsl:otherwise>
41            <xsl:variable name="tz" select="substring($dt-no-neg, $dt-no-neg-length - 5)" />
42            <xsl:if test="(substring($tz, 1, 1) = '-' or
43                           substring($tz, 1, 1) = '+') and
44                          substring($tz, 4, 1) = ':'">
45               <xsl:value-of select="$tz" />
46            </xsl:if>
47         </xsl:otherwise>
48      </xsl:choose>
49   </xsl:variable>
50   <xsl:variable name="new-dt">
51      <xsl:if test="not(string($timezone)) or
52                    $timezone = 'Z' or
53                    (substring($timezone, 2, 2) &lt;= 23 and
54                     substring($timezone, 5, 2) &lt;= 59)">
55         <xsl:variable name="dt" select="substring($dt-no-neg, 1, $dt-no-neg-length - string-length($timezone))" />
56         <xsl:variable name="dt-length" select="string-length($dt)" />
57         <xsl:variable name="du-neg" select="starts-with($duration, '-')" />
58         <xsl:variable name="du">
59            <xsl:choose>
60               <xsl:when test="$du-neg"><xsl:value-of select="substring($duration, 2)" /></xsl:when>
61               <xsl:otherwise><xsl:value-of select="$duration" /></xsl:otherwise>
62            </xsl:choose>
63         </xsl:variable>
64         <xsl:if test="starts-with($du, 'P') and
65                       not(translate($du, '0123456789PYMDTHS.', ''))">
66            <xsl:variable name="du-date">
67               <xsl:choose>
68                  <xsl:when test="contains($du, 'T')"><xsl:value-of select="substring-before(substring($du, 2), 'T')" /></xsl:when>
69                  <xsl:otherwise><xsl:value-of select="substring($du, 2)" /></xsl:otherwise>
70               </xsl:choose>
71            </xsl:variable>
72            <xsl:variable name="du-time">
73               <xsl:if test="contains($du, 'T')"><xsl:value-of select="substring-after($du, 'T')" /></xsl:if>
74            </xsl:variable>
75            <xsl:if test="(not($du-date) or
76                           (not(translate($du-date, '0123456789YMD', '')) and
77                            not(substring-after($du-date, 'D')) and
78                            (contains($du-date, 'D') or
79                             (not(substring-after($du-date, 'M')) and
80                              (contains($du-date, 'M') or
81                               not(substring-after($du-date, 'Y'))))))) and
82                          (not($du-time) or
83                           (not(translate($du-time, '0123456789HMS.', '')) and
84                            not(substring-after($du-time, 'S')) and
85                            (contains($du-time, 'S') or
86                             not(substring-after($du-time, 'M')) and
87                             (contains($du-time, 'M') or
88                              not(substring-after($du-time, 'Y'))))))">
89               <xsl:variable name="duy-str">
90                  <xsl:choose>
91                     <xsl:when test="contains($du-date, 'Y')"><xsl:value-of select="substring-before($du-date, 'Y')" /></xsl:when>
92                     <xsl:otherwise>0</xsl:otherwise>
93                  </xsl:choose>
94               </xsl:variable>
95               <xsl:variable name="dum-str">
96                  <xsl:choose>
97                     <xsl:when test="contains($du-date, 'M')">
98                        <xsl:choose>
99                           <xsl:when test="contains($du-date, 'Y')"><xsl:value-of select="substring-before(substring-after($du-date, 'Y'), 'M')" /></xsl:when>
100                           <xsl:otherwise><xsl:value-of select="substring-before($du-date, 'M')" /></xsl:otherwise>
101                        </xsl:choose>
102                     </xsl:when>
103                     <xsl:otherwise>0</xsl:otherwise>
104                  </xsl:choose>
105               </xsl:variable>
106               <xsl:variable name="dud-str">
107                  <xsl:choose>
108                     <xsl:when test="contains($du-date, 'D')">
109                        <xsl:choose>
110                           <xsl:when test="contains($du-date, 'M')"><xsl:value-of select="substring-before(substring-after($du-date, 'M'), 'D')" /></xsl:when>
111                           <xsl:when test="contains($du-date, 'Y')"><xsl:value-of select="substring-before(substring-after($du-date, 'Y'), 'D')" /></xsl:when>
112                           <xsl:otherwise><xsl:value-of select="substring-before($du-date, 'D')" /></xsl:otherwise>
113                        </xsl:choose>
114                     </xsl:when>
115                     <xsl:otherwise>0</xsl:otherwise>
116                  </xsl:choose>
117               </xsl:variable>
118               <xsl:variable name="duh-str">
119                  <xsl:choose>
120                     <xsl:when test="contains($du-time, 'H')"><xsl:value-of select="substring-before($du-time, 'H')" /></xsl:when>
121                     <xsl:otherwise>0</xsl:otherwise>
122                  </xsl:choose>
123               </xsl:variable>
124               <xsl:variable name="dumin-str">
125                  <xsl:choose>
126                     <xsl:when test="contains($du-time, 'M')">
127                        <xsl:choose>
128                           <xsl:when test="contains($du-time, 'H')"><xsl:value-of select="substring-before(substring-after($du-time, 'H'), 'M')" /></xsl:when>
129                           <xsl:otherwise><xsl:value-of select="substring-before($du-time, 'M')" /></xsl:otherwise>
130                        </xsl:choose>
131                     </xsl:when>
132                     <xsl:otherwise>0</xsl:otherwise>
133                  </xsl:choose>
134               </xsl:variable>
135               <xsl:variable name="dus-str">
136                  <xsl:choose>
137                     <xsl:when test="contains($du-time, 'S')">
138                        <xsl:choose>
139                           <xsl:when test="contains($du-time, 'M')"><xsl:value-of select="substring-before(substring-after($du-time, 'M'), 'S')" /></xsl:when>
140                           <xsl:when test="contains($du-time, 'H')"><xsl:value-of select="substring-before(substring-after($du-time, 'H'), 'S')" /></xsl:when>
141                           <xsl:otherwise><xsl:value-of select="substring-before($du-time, 'S')" /></xsl:otherwise>
142                        </xsl:choose>
143                     </xsl:when>
144                     <xsl:otherwise>0</xsl:otherwise>
145                  </xsl:choose>
146               </xsl:variable>
147               <xsl:variable name="mult" select="($du-neg * -2) + 1" />
148               <xsl:variable name="duy" select="$duy-str * $mult" />
149               <xsl:variable name="dum" select="$dum-str * $mult" />
150               <xsl:variable name="dud" select="$dud-str * $mult" />
151               <xsl:variable name="duh" select="$duh-str * $mult" />
152               <xsl:variable name="dumin" select="$dumin-str * $mult" />
153               <xsl:variable name="dus" select="$dus-str * $mult" />
154
155               <xsl:variable name="year" select="substring($dt, 1, 4) * (($dt-neg * -2) + 1)" />
156               <xsl:choose>
157                  <xsl:when test="$year and
158                                  string($duy) = 'NaN' or
159                                  string($dum) = 'NaN' or
160                                  string($dud) = 'NaN' or
161                                  string($duh) = 'NaN' or
162                                  string($dumin) = 'NaN' or
163                                  string($dus) = 'NaN'" />
164                  <xsl:when test="$dt-length > 4 or
165                                  $dum or $dud or $duh or $dumin or $dus">
166                     <xsl:variable name="month">
167                        <xsl:choose>
168                           <xsl:when test="$dt-length > 4">
169                              <xsl:if test="substring($dt, 5, 1) = '-'">
170                                 <xsl:value-of select="substring($dt, 6, 2)" />
171                              </xsl:if>
172                           </xsl:when>
173                           <xsl:otherwise>1</xsl:otherwise>
174                        </xsl:choose>
175                     </xsl:variable>
176                     <xsl:choose>
177                        <xsl:when test="not($month) or $month > 12" />
178                        <xsl:when test="$dt-length > 7 or
179                                        $dud or $duh or $dumin or $dus">
180                           <xsl:variable name="day">
181                              <xsl:choose>
182                                 <xsl:when test="$dt-length > 7">
183                                    <xsl:if test="substring($dt, 8, 1) = '-'">
184                                       <xsl:value-of select="substring($dt, 9, 2)" />
185                                    </xsl:if>
186                                 </xsl:when>
187                                 <xsl:otherwise>1</xsl:otherwise>
188                              </xsl:choose>
189                           </xsl:variable>
190                           <xsl:choose>
191                              <xsl:when test="not($day) or $day > 31" />
192                              <xsl:when test="$dt-length > 10 or
193                                              $duh or $dumin or $dus">
194                                 <xsl:if test="$dt-length = 10 or
195                                               (substring($dt, 11, 1) = 'T' and
196                                                substring($dt, 14, 1) = ':' and
197                                                substring($dt, 17, 1) = ':')">
198                                    <xsl:variable name="hour">
199                                       <xsl:choose>
200                                          <xsl:when test="$dt-length > 10"><xsl:value-of select="substring($dt, 12, 2)" /></xsl:when>
201                                          <xsl:otherwise>0</xsl:otherwise>
202                                       </xsl:choose>
203                                    </xsl:variable>
204                                    <xsl:variable name="minute">
205                                       <xsl:choose>
206                                          <xsl:when test="$dt-length > 10"><xsl:value-of select="substring($dt, 15, 2)" /></xsl:when>
207                                          <xsl:otherwise>0</xsl:otherwise>
208                                       </xsl:choose>
209                                    </xsl:variable>
210                                    <xsl:variable name="second">
211                                       <xsl:choose>
212                                          <xsl:when test="$dt-length > 10"><xsl:value-of select="substring($dt, 18)" /></xsl:when>
213                                          <xsl:otherwise>0</xsl:otherwise>
214                                       </xsl:choose>
215                                    </xsl:variable>
216                                    <xsl:if test="$hour &lt;= 23 and $minute &lt;= 59 and $second &lt;= 60">
217                                       <xsl:variable name="new-second" select="$second + $dus" />
218                                       <xsl:variable name="new-minute" select="$minute + $dumin + floor($new-second div 60)" />
219                                       <xsl:variable name="new-hour" select="$hour + $duh + floor($new-minute div 60)" />
220                                       <xsl:variable name="new-month" select="$month + $dum" />
221                                       <xsl:call-template name="date:_add-days">
222                                          <xsl:with-param name="year" select="$year + $duy + floor(($new-month - 1) div 12)" />
223                                          <xsl:with-param name="month">
224                                             <xsl:variable name="m">
225                                                <xsl:choose>
226                                                   <xsl:when test="$new-month &lt; 1"><xsl:value-of select="$new-month + 12" /></xsl:when>
227                                                   <xsl:otherwise><xsl:value-of select="$new-month" /></xsl:otherwise>
228                                                </xsl:choose>
229                                             </xsl:variable>
230                                             <xsl:choose>
231                                                <xsl:when test="$m mod 12">
232                                                   <xsl:value-of select="format-number($m mod 12, '00')" />
233                                                </xsl:when>
234                                                <xsl:otherwise>12</xsl:otherwise>
235                                             </xsl:choose>
236                                          </xsl:with-param>
237                                          <xsl:with-param name="day" select="$day" />
238                                          <xsl:with-param name="days" select="$dud + floor($new-hour div 24)" />
239                                       </xsl:call-template>
240                                       <xsl:text>T</xsl:text>
241                                       <xsl:value-of select="format-number(($new-hour + 24) mod 24, '00')" />
242                                       <xsl:text>:</xsl:text>
243                                       <xsl:value-of select="format-number($new-minute mod 60, '00')" />
244                                       <xsl:text>:</xsl:text>
245                                       <xsl:if test="$new-second mod 60 &lt; 10">0</xsl:if>
246                                       <xsl:value-of select="$new-second mod 60" />
247                                       <xsl:value-of select="$timezone" />
248                                    </xsl:if>
249                                 </xsl:if>
250                              </xsl:when>
251                              <xsl:otherwise>
252                                 <xsl:variable name="new-month" select="$month + $dum" />
253                                 <xsl:call-template name="date:_add-days">
254                                    <xsl:with-param name="year" select="$year + $duy + floor(($new-month - 1) div 12)" />
255                                    <xsl:with-param name="month">
256                                       <xsl:variable name="m">
257                                          <xsl:choose>
258                                             <xsl:when test="$new-month &lt; 1"><xsl:value-of select="$new-month + 12" /></xsl:when>
259                                             <xsl:otherwise><xsl:value-of select="$new-month" /></xsl:otherwise>
260                                          </xsl:choose>
261                                       </xsl:variable>
262                                       <xsl:choose>
263                                          <xsl:when test="$m mod 12">
264                                             <xsl:value-of select="format-number($m mod 12, '00')" />
265                                          </xsl:when>
266                                          <xsl:otherwise>12</xsl:otherwise>
267                                       </xsl:choose>
268                                    </xsl:with-param>
269                                    <xsl:with-param name="day" select="$day" />
270                                    <xsl:with-param name="days" select="$dud" />
271                                 </xsl:call-template>
272                                 <xsl:value-of select="$timezone" />
273                              </xsl:otherwise>
274                           </xsl:choose>
275                        </xsl:when>
276                        <xsl:otherwise>
277                           <xsl:variable name="new-month" select="$month + $dum" />
278                           <xsl:value-of select="format-number($year + $duy + floor(($new-month - 1) div 12), '0000')" />
279                           <xsl:text>-</xsl:text>
280                           <xsl:variable name="m">
281                              <xsl:choose>
282                                 <xsl:when test="$new-month &lt; 1"><xsl:value-of select="$new-month + 12" /></xsl:when>
283                                 <xsl:otherwise><xsl:value-of select="$new-month" /></xsl:otherwise>
284                              </xsl:choose>
285                           </xsl:variable>
286                           <xsl:choose>
287                              <xsl:when test="$m mod 12">
288                                 <xsl:value-of select="format-number($m mod 12, '00')" />
289                              </xsl:when>
290                              <xsl:otherwise>12</xsl:otherwise>
291                           </xsl:choose>
292                           <xsl:value-of select="$timezone" />
293                        </xsl:otherwise>
294                     </xsl:choose>
295                  </xsl:when>
296                  <xsl:otherwise>
297                     <xsl:value-of select="format-number($year + $duy, '0000')" />
298                     <xsl:value-of select="$timezone" />
299                  </xsl:otherwise>
300               </xsl:choose>
301            </xsl:if>
302         </xsl:if>
303      </xsl:if>
304   </xsl:variable>
305   <xsl:choose>
306     <xsl:when test="string-length($date-time) > 10">
307       <xsl:value-of select="$new-dt" />
308     </xsl:when>
309     <xsl:otherwise>
310       <xsl:value-of select="substring($new-dt, 1, string-length($date-time))" />
311     </xsl:otherwise>
312   </xsl:choose>
313</xsl:template>
314
315<xsl:template name="date:_add-days">
316   <xsl:param name="year" />
317   <xsl:param name="month" />
318   <xsl:param name="day" />
319   <xsl:param name="days" />
320   <xsl:param name="new-day" select="'NaN'" />
321   <xsl:variable name="leap" select="(not($year mod 4) and $year mod 100) or not($year mod 400)" />
322   <xsl:variable name="month-days" select="document('')/*/date:month-lengths/date:month" />
323   <xsl:variable name="days-in-month">
324      <xsl:choose>
325         <xsl:when test="$month = 2 and $leap">
326            <xsl:value-of select="$month-days[number($month)] + 1" />
327         </xsl:when>
328         <xsl:otherwise>
329            <xsl:value-of select="$month-days[number($month)]" />
330         </xsl:otherwise>
331      </xsl:choose>
332   </xsl:variable>
333   <xsl:choose>
334      <xsl:when test="$new-day = 'NaN'">
335         <xsl:call-template name="date:_add-days">
336            <xsl:with-param name="year" select="$year" />
337            <xsl:with-param name="month" select="$month" />
338            <xsl:with-param name="new-day">
339               <xsl:choose>
340                  <xsl:when test="$day > $days-in-month">
341                     <xsl:value-of select="$days-in-month + $days" />
342                  </xsl:when>
343                  <xsl:otherwise><xsl:value-of select="$day + $days" /></xsl:otherwise>
344               </xsl:choose>
345            </xsl:with-param>
346         </xsl:call-template>
347      </xsl:when>
348      <xsl:otherwise>
349         <xsl:choose>
350            <xsl:when test="$new-day &lt; 1">
351               <xsl:call-template name="date:_add-days">
352                  <xsl:with-param name="year" select="$year - ($month = 1)" />
353                  <xsl:with-param name="month">
354                     <xsl:choose>
355                        <xsl:when test="$month = 1">12</xsl:when>
356                        <xsl:otherwise><xsl:value-of select="$month - 1" /></xsl:otherwise>
357                     </xsl:choose>
358                  </xsl:with-param>
359                  <xsl:with-param name="new-day">
360                     <xsl:variable name="days-in-new-month">
361                        <xsl:choose>
362                           <xsl:when test="$leap and $month = 3">29</xsl:when>
363                           <xsl:when test="$month = 1">31</xsl:when>
364                           <xsl:otherwise>
365                              <xsl:value-of select="$month-days[$month - 1]" />
366                           </xsl:otherwise>
367                        </xsl:choose>
368                     </xsl:variable>                     
369                     <xsl:value-of select="$new-day + $days-in-new-month" />
370                  </xsl:with-param>
371               </xsl:call-template>
372            </xsl:when>
373            <xsl:when test="$new-day > $days-in-month">
374               <xsl:call-template name="date:_add-days">
375                  <xsl:with-param name="year" select="$year + ($month = 12)" />
376                  <xsl:with-param name="month">
377                     <xsl:choose>
378                        <xsl:when test="$month = 12">1</xsl:when>
379                        <xsl:otherwise><xsl:value-of select="$month + 1" /></xsl:otherwise>
380                     </xsl:choose>
381                  </xsl:with-param>
382                  <xsl:with-param name="new-day" select="$new-day - $days-in-month" />
383               </xsl:call-template>
384            </xsl:when>
385            <xsl:otherwise>
386               <xsl:value-of select="format-number($year, '0000')" />
387               <xsl:text>-</xsl:text>
388               <xsl:value-of select="format-number($month, '00')" />
389               <xsl:text>-</xsl:text>
390               <xsl:value-of select="format-number($new-day, '00')" />
391            </xsl:otherwise>
392         </xsl:choose>
393      </xsl:otherwise>
394   </xsl:choose>
395</xsl:template>
396
397</xsl:stylesheet>
Note: See TracBrowser for help on using the repository browser.