Update with various changes submitted by Simon
[project-aon.git] / common / xsl / org.projectaon.format-date-localized.template.xsl
1 <?xml version="1.0" encoding="UTF-8"?>\r
2 <xsl:stylesheet version="1.0"\r
3                 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"\r
4                 xmlns:date="http://exslt.org/dates-and-times"\r
5                 xmlns:str="http://exslt.org/strings"\r
6                 extension-element-prefixes="date str">\r
7 \r
8 <!--\r
9   Derived from date.format-date.template.xsl by Jeni Tennison.\r
10   http://exslt.org/date/functions/format-date/date.format-date.template.xsl\r
11   See also http://exslt.org/date/functions/format-date/index.html.\r
12 \r
13   Change log\r
14 \r
15   2010-23-11  Ingo Kloecker\r
16     * Commented out import of str.padding.template.xsl since xsltproc supports\r
17       str:padding out-of-the-box.\r
18     * Fixed a bug in date:_format-date with the handling of quoted text in the\r
19       pattern string.\r
20     * Renamed template date:format-date to date:format-date-localized.\r
21     * Added localization support (English and Spanish).\r
22 -->\r
23 \r
24 <!--\r
25 <xsl:import href="../../../str/functions/padding/str.padding.template.xsl" />\r
26 -->\r
27 \r
28 <date:months lang="en">\r
29    <date:month length="31" abbr="Jan">January</date:month>\r
30    <date:month length="28" abbr="Feb">February</date:month>\r
31    <date:month length="31" abbr="Mar">March</date:month>\r
32    <date:month length="30" abbr="Apr">April</date:month>\r
33    <date:month length="31" abbr="May">May</date:month>\r
34    <date:month length="30" abbr="Jun">June</date:month>\r
35    <date:month length="31" abbr="Jul">July</date:month>\r
36    <date:month length="31" abbr="Aug">August</date:month>\r
37    <date:month length="30" abbr="Sep">September</date:month>\r
38    <date:month length="31" abbr="Oct">October</date:month>\r
39    <date:month length="30" abbr="Nov">November</date:month>\r
40    <date:month length="31" abbr="Dec">December</date:month>\r
41 </date:months>\r
42 \r
43 <date:months lang="es">\r
44    <date:month length="31" abbr="ene.">enero</date:month>\r
45    <date:month length="28" abbr="feb.">febrero</date:month>\r
46    <date:month length="31" abbr="mar.">marzo</date:month>\r
47    <date:month length="30" abbr="abr.">abril</date:month>\r
48    <date:month length="31" abbr="may.">mayo</date:month>\r
49    <date:month length="30" abbr="jun.">junio</date:month>\r
50    <date:month length="31" abbr="jul.">julio</date:month>\r
51    <date:month length="31" abbr="ago.">agosto</date:month>\r
52    <date:month length="30" abbr="sep.">septiembre</date:month>\r
53    <date:month length="31" abbr="oct.">octubre</date:month>\r
54    <date:month length="30" abbr="nov.">noviembre</date:month>\r
55    <date:month length="31" abbr="dic.">diciembre</date:month>\r
56 </date:months>\r
57 \r
58 <date:days lang="en">\r
59    <date:day abbr="Sun">Sunday</date:day>\r
60    <date:day abbr="Mon">Monday</date:day>\r
61    <date:day abbr="Tue">Tuesday</date:day>\r
62    <date:day abbr="Wed">Wednesday</date:day>\r
63    <date:day abbr="Thu">Thursday</date:day>\r
64    <date:day abbr="Fri">Friday</date:day>\r
65    <date:day abbr="Sat">Saturday</date:day>\r
66 </date:days>\r
67 \r
68 <date:days lang="es">\r
69    <date:day abbr="D">domingo</date:day>\r
70    <date:day abbr="L">lunes</date:day>\r
71    <date:day abbr="M">martes</date:day>\r
72    <date:day abbr="X">miércoles</date:day>\r
73    <date:day abbr="J">jueves</date:day>\r
74    <date:day abbr="V">viernes</date:day>\r
75    <date:day abbr="S">sábado</date:day>\r
76 </date:days>\r
77 \r
78 <xsl:template name="date:format-date-localized">\r
79    <xsl:param name="date-time" />\r
80    <xsl:param name="pattern" />\r
81    <xsl:variable name="formatted">\r
82       <xsl:choose>\r
83          <xsl:when test="starts-with($date-time, '---')">\r
84             <xsl:call-template name="date:_format-date">\r
85                <xsl:with-param name="year" select="'NaN'" />\r
86                <xsl:with-param name="month" select="'NaN'" />\r
87                <xsl:with-param name="day" select="number(substring($date-time, 4, 2))" />\r
88                <xsl:with-param name="pattern" select="$pattern" />\r
89             </xsl:call-template>\r
90          </xsl:when>\r
91          <xsl:when test="starts-with($date-time, '--')">\r
92             <xsl:call-template name="date:_format-date">\r
93                <xsl:with-param name="year" select="'NaN'" />\r
94                <xsl:with-param name="month" select="number(substring($date-time, 3, 2))" />\r
95                <xsl:with-param name="day" select="number(substring($date-time, 6, 2))" />\r
96                <xsl:with-param name="pattern" select="$pattern" />\r
97             </xsl:call-template>\r
98          </xsl:when>\r
99          <xsl:otherwise>\r
100             <xsl:variable name="neg" select="starts-with($date-time, '-')" />\r
101             <xsl:variable name="no-neg">\r
102                <xsl:choose>\r
103                   <xsl:when test="$neg or starts-with($date-time, '+')">\r
104                      <xsl:value-of select="substring($date-time, 2)" />\r
105                   </xsl:when>\r
106                   <xsl:otherwise>\r
107                      <xsl:value-of select="$date-time" />\r
108                   </xsl:otherwise>\r
109                </xsl:choose>\r
110             </xsl:variable>\r
111             <xsl:variable name="no-neg-length" select="string-length($no-neg)" />\r
112             <xsl:variable name="timezone">\r
113                <xsl:choose>\r
114                   <xsl:when test="substring($no-neg, $no-neg-length) = 'Z'">Z</xsl:when>\r
115                   <xsl:otherwise>\r
116                      <xsl:variable name="tz" select="substring($no-neg, $no-neg-length - 5)" />\r
117                      <xsl:if test="(substring($tz, 1, 1) = '-' or \r
118                                     substring($tz, 1, 1) = '+') and\r
119                                    substring($tz, 4, 1) = ':'">\r
120                         <xsl:value-of select="$tz" />\r
121                      </xsl:if>\r
122                   </xsl:otherwise>\r
123                </xsl:choose>\r
124             </xsl:variable>\r
125             <xsl:if test="not(string($timezone)) or\r
126                           $timezone = 'Z' or \r
127                           (substring($timezone, 2, 2) &lt;= 23 and\r
128                            substring($timezone, 5, 2) &lt;= 59)">\r
129                <xsl:variable name="dt" select="substring($no-neg, 1, $no-neg-length - string-length($timezone))" />\r
130                <xsl:variable name="dt-length" select="string-length($dt)" />\r
131                <xsl:choose>\r
132                   <xsl:when test="substring($dt, 3, 1) = ':' and\r
133                                   substring($dt, 6, 1) = ':'">\r
134                      <xsl:variable name="hour" select="substring($dt, 1, 2)" />\r
135                      <xsl:variable name="min" select="substring($dt, 4, 2)" />\r
136                      <xsl:variable name="sec" select="substring($dt, 7)" />\r
137                      <xsl:if test="$hour &lt;= 23 and\r
138                                    $min &lt;= 59 and\r
139                                    $sec &lt;= 60">\r
140                         <xsl:call-template name="date:_format-date">\r
141                            <xsl:with-param name="year" select="'NaN'" />\r
142                            <xsl:with-param name="month" select="'NaN'" />\r
143                            <xsl:with-param name="day" select="'NaN'" />\r
144                            <xsl:with-param name="hour" select="$hour" />\r
145                            <xsl:with-param name="minute" select="$min" />\r
146                            <xsl:with-param name="second" select="$sec" />\r
147                            <xsl:with-param name="timezone" select="$timezone" />\r
148                            <xsl:with-param name="pattern" select="$pattern" />\r
149                         </xsl:call-template>\r
150                      </xsl:if>\r
151                   </xsl:when>\r
152                   <xsl:otherwise>\r
153                      <xsl:variable name="year" select="substring($dt, 1, 4) * (($neg * -2) + 1)" />\r
154                      <xsl:choose>\r
155                         <xsl:when test="not(number($year))" />\r
156                         <xsl:when test="$dt-length = 4">\r
157                            <xsl:call-template name="date:_format-date">\r
158                               <xsl:with-param name="year" select="$year" />\r
159                               <xsl:with-param name="timezone" select="$timezone" />\r
160                               <xsl:with-param name="pattern" select="$pattern" />\r
161                            </xsl:call-template>\r
162                         </xsl:when>\r
163                         <xsl:when test="substring($dt, 5, 1) = '-'">\r
164                            <xsl:variable name="month" select="substring($dt, 6, 2)" />\r
165                            <xsl:choose>\r
166                               <xsl:when test="not($month &lt;= 12)" />\r
167                               <xsl:when test="$dt-length = 7">\r
168                                  <xsl:call-template name="date:_format-date">\r
169                                     <xsl:with-param name="year" select="$year" />\r
170                                     <xsl:with-param name="month" select="$month" />\r
171                                     <xsl:with-param name="timezone" select="$timezone" />\r
172                                     <xsl:with-param name="pattern" select="$pattern" />\r
173                                  </xsl:call-template>\r
174                               </xsl:when>\r
175                               <xsl:when test="substring($dt, 8, 1) = '-'">\r
176                                  <xsl:variable name="day" select="substring($dt, 9, 2)" />\r
177                                  <xsl:if test="$day &lt;= 31">\r
178                                     <xsl:choose>\r
179                                        <xsl:when test="$dt-length = 10">\r
180                                           <xsl:call-template name="date:_format-date">\r
181                                              <xsl:with-param name="year" select="$year" />\r
182                                              <xsl:with-param name="month" select="$month" />\r
183                                              <xsl:with-param name="day" select="$day" />\r
184                                              <xsl:with-param name="timezone" select="$timezone" />\r
185                                              <xsl:with-param name="pattern" select="$pattern" />\r
186                                           </xsl:call-template>\r
187                                        </xsl:when>\r
188                                        <xsl:when test="substring($dt, 11, 1) = 'T' and\r
189                                                        substring($dt, 14, 1) = ':' and\r
190                                                        substring($dt, 17, 1) = ':'">\r
191                                           <xsl:variable name="hour" select="substring($dt, 12, 2)" />\r
192                                           <xsl:variable name="min" select="substring($dt, 15, 2)" />\r
193                                           <xsl:variable name="sec" select="substring($dt, 18)" />\r
194                                           <xsl:if test="$hour &lt;= 23 and\r
195                                                         $min &lt;= 59 and\r
196                                                         $sec &lt;= 60">\r
197                                              <xsl:call-template name="date:_format-date">\r
198                                                 <xsl:with-param name="year" select="$year" />\r
199                                                 <xsl:with-param name="month" select="$month" />\r
200                                                 <xsl:with-param name="day" select="$day" />\r
201                                                 <xsl:with-param name="hour" select="$hour" />\r
202                                                 <xsl:with-param name="minute" select="$min" />\r
203                                                 <xsl:with-param name="second" select="$sec" />\r
204                                                 <xsl:with-param name="timezone" select="$timezone" />\r
205                                                 <xsl:with-param name="pattern" select="$pattern" />\r
206                                              </xsl:call-template>\r
207                                           </xsl:if>\r
208                                        </xsl:when>\r
209                                     </xsl:choose>\r
210                                  </xsl:if>\r
211                               </xsl:when>\r
212                            </xsl:choose>\r
213                         </xsl:when>\r
214                      </xsl:choose>\r
215                   </xsl:otherwise>\r
216                </xsl:choose>\r
217             </xsl:if>\r
218          </xsl:otherwise>\r
219       </xsl:choose>\r
220    </xsl:variable>\r
221    <xsl:value-of select="$formatted" />   \r
222 </xsl:template>\r
223 \r
224 <xsl:template name="date:_format-date">\r
225    <xsl:param name="year" />\r
226    <xsl:param name="month" select="1" />\r
227    <xsl:param name="day" select="1" />\r
228    <xsl:param name="hour" select="0" />\r
229    <xsl:param name="minute" select="0" />\r
230    <xsl:param name="second" select="0" />\r
231    <xsl:param name="timezone" select="'Z'" />\r
232    <xsl:param name="pattern" select="''" />\r
233    <xsl:variable name="char" select="substring($pattern, 1, 1)" />\r
234    <xsl:choose>\r
235       <xsl:when test="not($pattern)" />\r
236       <xsl:when test='$char = "&apos;"'>\r
237          <xsl:choose>\r
238             <xsl:when test='substring($pattern, 2, 1) = "&apos;"'>\r
239                <xsl:text>&apos;</xsl:text>\r
240                <xsl:call-template name="date:_format-date">\r
241                   <xsl:with-param name="year" select="$year" />\r
242                   <xsl:with-param name="month" select="$month" />\r
243                   <xsl:with-param name="day" select="$day" />\r
244                   <xsl:with-param name="hour" select="$hour" />\r
245                   <xsl:with-param name="minute" select="$minute" />\r
246                   <xsl:with-param name="second" select="$second" />\r
247                   <xsl:with-param name="timezone" select="$timezone" />\r
248                   <xsl:with-param name="pattern" select="substring($pattern, 3)" />\r
249                </xsl:call-template>\r
250             </xsl:when>\r
251             <xsl:otherwise>\r
252                <xsl:variable name="literal-value" select='substring-before(substring($pattern, 2), "&apos;")' />\r
253                <xsl:value-of select="$literal-value" />\r
254                <xsl:call-template name="date:_format-date">\r
255                   <xsl:with-param name="year" select="$year" />\r
256                   <xsl:with-param name="month" select="$month" />\r
257                   <xsl:with-param name="day" select="$day" />\r
258                   <xsl:with-param name="hour" select="$hour" />\r
259                   <xsl:with-param name="minute" select="$minute" />\r
260                   <xsl:with-param name="second" select="$second" />\r
261                   <xsl:with-param name="timezone" select="$timezone" />\r
262                   <xsl:with-param name="pattern" select="substring($pattern, string-length($literal-value) + 3)" />\r
263                   <!-- In the original file this was\r
264                   <xsl:with-param name="pattern" select="substring($pattern, string-length($literal-value) + 2)" />\r
265                   -->\r
266                </xsl:call-template>\r
267             </xsl:otherwise>\r
268          </xsl:choose>\r
269       </xsl:when>\r
270       <xsl:when test="not(contains('abcdefghjiklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ', $char))">\r
271          <xsl:value-of select="$char" />\r
272          <xsl:call-template name="date:_format-date">\r
273             <xsl:with-param name="year" select="$year" />\r
274             <xsl:with-param name="month" select="$month" />\r
275             <xsl:with-param name="day" select="$day" />\r
276             <xsl:with-param name="hour" select="$hour" />\r
277             <xsl:with-param name="minute" select="$minute" />\r
278             <xsl:with-param name="second" select="$second" />\r
279             <xsl:with-param name="timezone" select="$timezone" />\r
280             <xsl:with-param name="pattern" select="substring($pattern, 2)" />\r
281          </xsl:call-template>\r
282       </xsl:when>\r
283       <xsl:when test="not(contains('GyMdhHmsSEDFwWakKz', $char))">\r
284          <xsl:message>\r
285             Invalid token in format string: <xsl:value-of select="$char" />\r
286          </xsl:message>\r
287          <xsl:call-template name="date:_format-date">\r
288             <xsl:with-param name="year" select="$year" />\r
289             <xsl:with-param name="month" select="$month" />\r
290             <xsl:with-param name="day" select="$day" />\r
291             <xsl:with-param name="hour" select="$hour" />\r
292             <xsl:with-param name="minute" select="$minute" />\r
293             <xsl:with-param name="second" select="$second" />\r
294             <xsl:with-param name="timezone" select="$timezone" />\r
295             <xsl:with-param name="pattern" select="substring($pattern, 2)" />\r
296          </xsl:call-template>\r
297       </xsl:when>\r
298       <xsl:otherwise>\r
299          <xsl:variable name="next-different-char" select="substring(translate($pattern, $char, ''), 1, 1)" />\r
300          <xsl:variable name="pattern-length">\r
301             <xsl:choose>\r
302                <xsl:when test="$next-different-char">\r
303                   <xsl:value-of select="string-length(substring-before($pattern, $next-different-char))" />\r
304                </xsl:when>\r
305                <xsl:otherwise>\r
306                   <xsl:value-of select="string-length($pattern)" />\r
307                </xsl:otherwise>\r
308             </xsl:choose>\r
309          </xsl:variable>\r
310          <xsl:choose>\r
311             <xsl:when test="$char = 'G'">\r
312                <xsl:choose>\r
313                   <xsl:when test="string($year) = 'NaN'" />\r
314                   <xsl:when test="$year > 0">AD</xsl:when>\r
315                   <xsl:otherwise>BC</xsl:otherwise>\r
316                </xsl:choose>\r
317             </xsl:when>\r
318             <xsl:when test="$char = 'M'">\r
319                <xsl:choose>\r
320                   <xsl:when test="string($month) = 'NaN'" />\r
321                   <xsl:when test="$pattern-length >= 3">\r
322                      <xsl:variable name="month-node" select="document('')/*/date:months[@lang=$language]/date:month[number($month)]" />\r
323                      <xsl:choose>\r
324                         <xsl:when test="$pattern-length >= 4">\r
325                            <xsl:value-of select="$month-node" />\r
326                         </xsl:when>\r
327                         <xsl:otherwise>\r
328                            <xsl:value-of select="$month-node/@abbr" />\r
329                         </xsl:otherwise>\r
330                      </xsl:choose>\r
331                   </xsl:when>\r
332                   <xsl:when test="$pattern-length = 2">\r
333                      <xsl:value-of select="format-number($month, '00')" />\r
334                   </xsl:when>\r
335                   <xsl:otherwise>\r
336                      <xsl:value-of select="$month" />\r
337                   </xsl:otherwise>\r
338                </xsl:choose>\r
339             </xsl:when>\r
340             <xsl:when test="$char = 'E'">\r
341                <xsl:choose>\r
342                   <xsl:when test="string($year) = 'NaN' or string($month) = 'NaN' or string($day) = 'NaN'" />\r
343                   <xsl:otherwise>\r
344                      <xsl:variable name="month-days" select="sum(document('')/*/date:months[@lang=$language]/date:month[position() &lt; $month]/@length)" />\r
345                      <xsl:variable name="days" select="$month-days + $day + boolean(((not($year mod 4) and $year mod 100) or not($year mod 400)) and $month > 2)" />\r
346                      <xsl:variable name="y-1" select="$year - 1" />\r
347                      <xsl:variable name="dow"\r
348                                    select="(($y-1 + floor($y-1 div 4) -\r
349                                              floor($y-1 div 100) + floor($y-1 div 400) +\r
350                                              $days) \r
351                                             mod 7) + 1" />\r
352                      <xsl:variable name="day-node" select="document('')/*/date:days[@lang=$language]/date:day[number($dow)]" />\r
353                      <xsl:choose>\r
354                         <xsl:when test="$pattern-length >= 4">\r
355                            <xsl:value-of select="$day-node" />\r
356                         </xsl:when>\r
357                         <xsl:otherwise>\r
358                            <xsl:value-of select="$day-node/@abbr" />\r
359                         </xsl:otherwise>\r
360                      </xsl:choose>\r
361                   </xsl:otherwise>\r
362                </xsl:choose>\r
363             </xsl:when>\r
364             <xsl:when test="$char = 'a'">\r
365                <xsl:choose>\r
366                   <xsl:when test="string($hour) = 'NaN'" />\r
367                   <xsl:when test="$hour >= 12">PM</xsl:when>\r
368                   <xsl:otherwise>AM</xsl:otherwise>\r
369                </xsl:choose>\r
370             </xsl:when>\r
371             <xsl:when test="$char = 'z'">\r
372                <xsl:choose>\r
373                   <xsl:when test="$timezone = 'Z'">UTC</xsl:when>\r
374                   <xsl:otherwise>UTC<xsl:value-of select="$timezone" /></xsl:otherwise>\r
375                </xsl:choose>\r
376             </xsl:when>\r
377             <xsl:otherwise>\r
378                <xsl:variable name="padding">\r
379                   <xsl:choose>\r
380                      <xsl:when test="$pattern-length > 10">\r
381                         <xsl:call-template name="str:padding">\r
382                            <xsl:with-param name="length" select="$pattern-length" />\r
383                            <xsl:with-param name="chars" select="'0'" />\r
384                         </xsl:call-template>\r
385                      </xsl:when>\r
386                      <xsl:otherwise>\r
387                         <xsl:value-of select="substring('0000000000', 1, $pattern-length)" />\r
388                      </xsl:otherwise>\r
389                   </xsl:choose>\r
390                </xsl:variable>\r
391                <xsl:choose>\r
392                   <xsl:when test="$char = 'y'">\r
393                      <xsl:choose>\r
394                         <xsl:when test="string($year) = 'NaN'" />\r
395                         <xsl:when test="$pattern-length > 2"><xsl:value-of select="format-number($year, $padding)" /></xsl:when>\r
396                         <xsl:otherwise><xsl:value-of select="format-number(substring($year, string-length($year) - 1), $padding)" /></xsl:otherwise>\r
397                      </xsl:choose>\r
398                   </xsl:when>\r
399                   <xsl:when test="$char = 'd'">\r
400                      <xsl:choose>\r
401                         <xsl:when test="string($day) = 'NaN'" />\r
402                         <xsl:otherwise><xsl:value-of select="format-number($day, $padding)" /></xsl:otherwise>\r
403                      </xsl:choose>\r
404                   </xsl:when>\r
405                   <xsl:when test="$char = 'h'">\r
406                      <xsl:variable name="h" select="$hour mod 12" />\r
407                      <xsl:choose>\r
408                         <xsl:when test="string($hour) = 'NaN'"></xsl:when>\r
409                         <xsl:when test="$h"><xsl:value-of select="format-number($h, $padding)" /></xsl:when>\r
410                         <xsl:otherwise><xsl:value-of select="format-number(12, $padding)" /></xsl:otherwise>\r
411                      </xsl:choose>\r
412                   </xsl:when>\r
413                   <xsl:when test="$char = 'H'">\r
414                      <xsl:choose>\r
415                         <xsl:when test="string($hour) = 'NaN'" />\r
416                         <xsl:otherwise>\r
417                            <xsl:value-of select="format-number($hour, $padding)" />\r
418                         </xsl:otherwise>\r
419                      </xsl:choose>\r
420                   </xsl:when>\r
421                   <xsl:when test="$char = 'k'">\r
422                      <xsl:choose>\r
423                         <xsl:when test="string($hour) = 'NaN'" />\r
424                         <xsl:when test="$hour"><xsl:value-of select="format-number($hour, $padding)" /></xsl:when>\r
425                         <xsl:otherwise><xsl:value-of select="format-number(24, $padding)" /></xsl:otherwise>\r
426                      </xsl:choose>\r
427                   </xsl:when>\r
428                   <xsl:when test="$char = 'K'">\r
429                      <xsl:choose>\r
430                         <xsl:when test="string($hour) = 'NaN'" />\r
431                         <xsl:otherwise><xsl:value-of select="format-number($hour mod 12, $padding)" /></xsl:otherwise>\r
432                      </xsl:choose>\r
433                   </xsl:when>\r
434                   <xsl:when test="$char = 'm'">\r
435                      <xsl:choose>\r
436                         <xsl:when test="string($minute) = 'NaN'" />\r
437                         <xsl:otherwise>\r
438                            <xsl:value-of select="format-number($minute, $padding)" />\r
439                         </xsl:otherwise>\r
440                      </xsl:choose>\r
441                   </xsl:when>\r
442                   <xsl:when test="$char = 's'">\r
443                      <xsl:choose>\r
444                         <xsl:when test="string($second) = 'NaN'" />\r
445                         <xsl:otherwise>\r
446                            <xsl:value-of select="format-number($second, $padding)" />\r
447                         </xsl:otherwise>\r
448                      </xsl:choose>\r
449                   </xsl:when>\r
450                   <xsl:when test="$char = 'S'">\r
451                      <xsl:choose>\r
452                         <xsl:when test="string($second) = 'NaN'" />\r
453                         <xsl:otherwise>\r
454                            <xsl:value-of select="format-number(substring-after($second, '.'), $padding)" />\r
455                         </xsl:otherwise>\r
456                      </xsl:choose>\r
457                   </xsl:when>\r
458                   <xsl:when test="$char = 'F'">\r
459                      <xsl:choose>\r
460                         <xsl:when test="string($day) = 'NaN'" />\r
461                         <xsl:otherwise>\r
462                            <xsl:value-of select="floor($day div 7) + 1" />\r
463                         </xsl:otherwise>\r
464                      </xsl:choose>\r
465                   </xsl:when>\r
466                   <xsl:when test="string($year) = 'NaN' or string($month) = 'NaN' or string($day) = 'NaN'" />\r
467                   <xsl:otherwise>\r
468                      <xsl:variable name="month-days" select="sum(document('')/*/date:months[@lang=$language]/date:month[position() &lt; $month]/@length)" />\r
469                      <xsl:variable name="days" select="$month-days + $day + boolean(((not($year mod 4) and $year mod 100) or not($year mod 400)) and $month > 2)" />\r
470                      <xsl:choose>\r
471                         <xsl:when test="$char = 'D'">\r
472                            <xsl:value-of select="format-number($days, $padding)" />\r
473                         </xsl:when>\r
474                         <xsl:when test="$char = 'w'">\r
475                            <xsl:call-template name="date:_week-in-year">\r
476                               <xsl:with-param name="days" select="$days" />\r
477                               <xsl:with-param name="year" select="$year" />\r
478                            </xsl:call-template>\r
479                         </xsl:when>\r
480                         <xsl:when test="$char = 'W'">\r
481                            <xsl:variable name="y-1" select="$year - 1" />\r
482                            <xsl:variable name="day-of-week" \r
483                                          select="(($y-1 + floor($y-1 div 4) -\r
484                                                   floor($y-1 div 100) + floor($y-1 div 400) +\r
485                                                   $days) \r
486                                                   mod 7) + 1" />\r
487                            <xsl:choose>\r
488                               <xsl:when test="($day - $day-of-week) mod 7">\r
489                                  <xsl:value-of select="floor(($day - $day-of-week) div 7) + 2" />\r
490                               </xsl:when>\r
491                               <xsl:otherwise>\r
492                                  <xsl:value-of select="floor(($day - $day-of-week) div 7) + 1" />\r
493                               </xsl:otherwise>\r
494                            </xsl:choose>\r
495                         </xsl:when>\r
496                      </xsl:choose>\r
497                   </xsl:otherwise>\r
498                </xsl:choose>\r
499             </xsl:otherwise>\r
500          </xsl:choose>\r
501          <xsl:call-template name="date:_format-date">\r
502             <xsl:with-param name="year" select="$year" />\r
503             <xsl:with-param name="month" select="$month" />\r
504             <xsl:with-param name="day" select="$day" />\r
505             <xsl:with-param name="hour" select="$hour" />\r
506             <xsl:with-param name="minute" select="$minute" />\r
507             <xsl:with-param name="second" select="$second" />\r
508             <xsl:with-param name="timezone" select="$timezone" />\r
509             <xsl:with-param name="pattern" select="substring($pattern, $pattern-length + 1)" />\r
510          </xsl:call-template>\r
511       </xsl:otherwise>\r
512    </xsl:choose>\r
513 </xsl:template>\r
514 \r
515 <xsl:template name="date:_week-in-year">\r
516    <xsl:param name="days" />\r
517    <xsl:param name="year" />\r
518    <xsl:variable name="y-1" select="$year - 1" />\r
519    <!-- this gives the day of the week, counting from Sunday = 0 -->\r
520    <xsl:variable name="day-of-week" \r
521                  select="($y-1 + floor($y-1 div 4) -\r
522                           floor($y-1 div 100) + floor($y-1 div 400) +\r
523                           $days) \r
524                          mod 7" />\r
525    <!-- this gives the day of the week, counting from Monday = 1 -->\r
526    <xsl:variable name="dow">\r
527       <xsl:choose>\r
528          <xsl:when test="$day-of-week"><xsl:value-of select="$day-of-week" /></xsl:when>\r
529          <xsl:otherwise>7</xsl:otherwise>\r
530       </xsl:choose>\r
531    </xsl:variable>\r
532    <xsl:variable name="start-day" select="($days - $dow + 7) mod 7" />\r
533    <xsl:variable name="week-number" select="floor(($days - $dow + 7) div 7)" />\r
534    <xsl:choose>\r
535       <xsl:when test="$start-day >= 4">\r
536          <xsl:value-of select="$week-number + 1" />\r
537       </xsl:when>\r
538       <xsl:otherwise>\r
539          <xsl:choose>\r
540             <xsl:when test="not($week-number)">\r
541                <xsl:call-template name="date:_week-in-year">\r
542                   <xsl:with-param name="days" select="365 + ((not($y-1 mod 4) and $y-1 mod 100) or not($y-1 mod 400))" />\r
543                   <xsl:with-param name="year" select="$y-1" />\r
544                </xsl:call-template>\r
545             </xsl:when>\r
546             <xsl:otherwise>\r
547                <xsl:value-of select="$week-number" />\r
548             </xsl:otherwise>\r
549          </xsl:choose>\r
550       </xsl:otherwise>\r
551    </xsl:choose>\r
552 </xsl:template>\r
553 \r
554 </xsl:stylesheet>\r