Рассчитать номер недели из значения даты - PullRequest
5 голосов
/ 07 октября 2008

Есть ли какой-нибудь простой способ вычислить значение Weeknumber из значения даты, сохраненного в XML?

Это должно быть чистое решение XSLT. Я не могу использовать любой код: (

Ответы [ 6 ]

5 голосов
/ 08 октября 2008

Если вы можете использовать EXSLT, есть несколько функций даты . Все они реализованы в Saxon, но если вы используете MSXSL, Крис Байес реализовал их как функции расширения, которые вы можете фактически поместить в свое преобразование внутри элемента msxsl: script. Его реализации связаны с каждой конкретной страницы функции даты.

Является ли неделя в году () функцией, которую вы ищете?

Редактировать: Согласно комментарию JeniT, на том же сайте доступен шаблон XSLT 1.0 с той же функциональностью, что и за неделю () (которую она написала, я думаю), что может соответствовать вашим требованиям лучше.

1 голос
/ 16 ноября 2008

Это чисто решение XSLT 1.0 :

Можно использовать модуль таблиц стилей datetime_lib.xsl от Martin Rowlinson, который поставляется с XSelerator (отличная среда XSLT, недавно сделанная свободно доступной SourceForge). Вам нужно будет скачать и установить это приложение, тогда вы найдете множество дополнительных библиотек и примеры передовых методов и решений.

Файл datetime_lib.xsl можно найти (для обычной установки) в:

C: \ Program Files \ Marrowsoft \ Xselerator25 \ Samples \ Libraries \

Из этой библиотеки вот шаблон с именем "номер недели":

<xsl:template name="week-number">
    <xsl:param name="year"/>
    <xsl:param name="month"/>
    <xsl:param name="day"/>
    <!-- or -->
    <xsl:param name="date" select="''"/>  <!-- format: yyyymmdd or yyyy-mm-dd -->
    <!-- or -->
    <xsl:param name="julian-day" select="''"/>
    <!-- trim down date -->
    <xsl:variable name="tdate" select="translate($date,'-','')"/>
    <!-- decide which params were passed -->
    <xsl:variable name="yyyy">
        <xsl:choose>
            <xsl:when test="string-length($date) > 0"><xsl:value-of select="substring($tdate,1,4)"/></xsl:when>
            <xsl:when test="string-length($julian-day) > 0">
                <xsl:variable name="jdate">
                    <xsl:call-template name="julian-day-to-date">
                        <xsl:with-param name="julian-day" select="$julian-day"/>
                    </xsl:call-template>
                </xsl:variable>
                <xsl:value-of select="substring($jdate,1,4)"/>
            </xsl:when>
            <xsl:otherwise><xsl:value-of select="$year"/></xsl:otherwise>
        </xsl:choose>
    </xsl:variable>
    <!-- get the julian day number -->
    <xsl:variable name="jd">
        <xsl:choose>
            <xsl:when test="string-length($julian-day) > 0"><xsl:value-of select="$julian-day"/></xsl:when>
            <xsl:otherwise>
                <xsl:call-template name="date-to-julian-day">
                    <xsl:with-param name="year" select="$year"/>
                    <xsl:with-param name="month" select="$month"/>
                    <xsl:with-param name="day" select="$day"/>
                    <xsl:with-param name="date" select="$date"/>
                </xsl:call-template>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:variable>
    <!-- get the julian day number for the first working day of next year -->
    <xsl:variable name="fyjd">
        <xsl:call-template name="first-day-of-year">
            <xsl:with-param name="year" select="$yyyy+1"/>
            <xsl:with-param name="as-julian-day" select="true()"/>
        </xsl:call-template>
    </xsl:variable>
    <!-- decide which the 'working' year for this date is -->
    <xsl:variable name="start-jd">
        <xsl:choose>
            <xsl:when test="$jd >= $fyjd"><xsl:value-of select="$fyjd"/></xsl:when>
            <xsl:otherwise>
                <xsl:call-template name="date-to-julian-day">
                    <xsl:with-param name="date">
                        <xsl:call-template name="first-day-of-year">
                            <xsl:with-param name="year" select="$yyyy"/>
                        </xsl:call-template>
                    </xsl:with-param>
                </xsl:call-template>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:variable>
    <!-- final calc output -->
    <xsl:value-of select="floor(($jd - $start-jd) div 7) + 1"/>
</xsl:template>



Вот простое преобразование XSLT с использованием шаблона "номер недели":


<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:msxsl="urn:schemas-microsoft-com:xslt">

 <xsl:import href=
 "C:\Program Files\Marrowsoft\Xselerator25\Samples\Libraries\datetime_lib.xsl"/>

 <xsl:output method="text"/>

 <xsl:template match="/">
     <xsl:call-template name="week-number">
       <xsl:with-param name="date" select="'2008-11-16'"/>
     </xsl:call-template>
 </xsl:template>
</xsl:stylesheet>

При применении к любому исходному XML-документу (не используется), получается желаемый результат:

46

Надеюсь, что на этот раз ответ был действительно более полезным.

Приветствия

Димитр Новатчев.

1 голос
/ 07 октября 2008

Расчет недели может быть довольно сложным, если вы всегда хотите, чтобы неделя начиналась в один и тот же день, потому что первый день года всегда меняется. Существует стандарт ISO для его расчета, см. эту статью в Википедии .

0 голосов
/ 08 октября 2008

Ознакомьтесь с поваренной книгой XSLT от Sal Mangano. Интересно, что он доступен на Google Книгах .

Способ xslt 2.0:

<xsl:function name="chkbk:calculate-week-number" as="xs:integer">
    <xsl:param name="date" as="xs:date" />
    <xsl:sequence select="xs:integer(format-date($date,'[W]'))" />
</xsl:function>

Для способа 1.0 смотрите предварительный просмотр cookbox. Кстати, я просто набрал в поисках xslt номер недели.

0 голосов
/ 07 октября 2008

А в C #:

DateTime date = DateTime.Now;
int week = date.DayOfYear / 7;
Console.WriteLine(week);
0 голосов
/ 07 октября 2008

Я программирую на Visual Basic, поэтому знаю, как это сделать, используя VB.NET. Считайте свою XML-дату в переменную (назовем ее SomeDate ). Затем вы создаете новую дату, которую вы знаете, является началом года, который содержит вашу неизвестную дату. Затем вы позволяете функции DateDiff сообщать вам номер недели.

Dim SomeDate As Date = ReadDateFromXML()
Dim YearStart As New Date(Year(SomeDate), 1, 1)
Dim WeekNumber As Integer = DateDiff(DateInterval.WeekOfYear, YearStart, SomeDate)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...