В настоящее время вы работаете в автономном режиме; ожидается повторное подключение к Интернету

BUG: Формат или функции DatePart может вернуть неправильный номер недели последний понедельник в год

ВНИМАНИЕ! Перевод данной статьи был выполнен не человеком, а с помощью программы машинного перевода, разработанной корпорацией Майкрософт. Корпорация Майкрософт предлагает вам статьи, переведенные как людьми, так и средствами машинного перевода, чтобы у вас была возможность ознакомиться со статьями базы знаний KB на родном языке. Однако машинный перевод не всегда идеален. Он может содержать смысловые, синтаксические и грамматические ошибки, подобно тому как иностранец делает ошибки, пытаясь говорить на вашем языке. Корпорация Майкрософт не несет ответственности за неточности, ошибки и возможный ущерб, причиненный в результате неправильного перевода или его использования. Корпорация Майкрософт также часто обновляет средства машинного перевода.

Эта статья на английском языке:200299
Эта статья помещена в архив. Она предлагается "как есть" и обновляться не будет.
Проблема
При использовании любойФормат:-или-Функции DatePartфункции для определения номера недели для даты, используя следующий синтаксис:
Format(AnyDate, "ww", vbMonday, vbFirstFourDays)DatePart("ww", AnyDate, vbMonday, vbFirstFourDays)				
последний понедельник в некоторых календарного года возвращаются в виде Неделя 53, когда он должен быть 1 неделя.
Причина
При определении количества недель дату в соответствии с ISO 8601 стандартных, базовые функции файл Oleaut32.dll ошибочно возвращает Неделя 53 вместо неделя 1 последний понедельник в определенные годы.
Решение
Использование определяемой пользователем функции для возвращения числа неделя, в соответствии с правилами стандарта ISO 8601. Пример включен в этой статье.
Статус
Корпорация Майкрософт подтверждает, что это является проблемой в файл Oleaut32.dll.
Дополнительная информация
Стандарт ISO 8601 широко используется в Европе и включает в себя следующее:
  ISO 8601 "Data elements and interchange formats - Information interchange   - Representation of dates and times"  ISO 8601 : 1988 (E) paragraph 3.17:  "week, calendar: A seven day period within a calendar year, starting  on a Monday and identified by its ordinal number within the year;  the first calendar week of the year is the one that includes the  first Thursday of that year. In the Gregorian calendar, this is  equivalent to the week which includes 4 January."				
Это может быть реализовано путем применения этих правил для недели календаря:
  • Год делится на 52 или 53 календарных недель.
  • Неделя в календаре имеет 7 дней. Понедельник — день 1, воскресенье — 7 дней.
  • Первой недели года календаря является, содержащий хотя бы на 4 дня.
  • Если год не является памятью на воскресенье, принадлежат его последнего дня 1-3 для следующего года первая неделя календаря или первые дни 1-3 следующего года принадлежит последняя неделя в календаре текущего года.
  • Только начальную или concluding на четверг году 53 календарных недель.
В Visual Basic и Visual Basic для приложений, все даты за исключением функций,DateSerialфункции, поступают из вызовов файла Oleaut32.dll. Так как обаFormat()иDatePart()функции могут возвращать номер недели в календаре для определенной даты, оба подвержены этой ошибки. Чтобы избежать этого, необходимо использовать другой код, эта статья содержит.

Действия для воспроизведения поведения:

  1. Запустите стандартный EXE-файла проекта в Visual Basic. По умолчанию будет создана форма Form1..
  2. Добавить дваCommandButtonsв форму Form1.
  3. Вставьте следующий код в окно кода Form1:
    Option ExplicitPrivate Sub Command1_Click()' This code tests a "problem" date and the days around itDim DateValue As DateDim i As IntegerDebug.Print "   Format function:"DateValue = #12/27/2003#For i = 1 To 4   ' examine the last 4 days of the year    DateValue = DateAdd("d", 1, DateValue)    Debug.Print "Date: " & DateValue & "   Day: " & _      Format(DateValue, "ddd") & "   Week: " & _      Format(DateValue, "ww", vbMonday, vbFirstFourDays)Next iEnd SubPrivate Sub Command2_Click()' This code lists all "Problem" dates within a specified range  Dim MyDate As Date  Dim Years As Long  Dim days As Long  Dim woy1 As Long  Dim woy2 As Long  Dim ToPrint As String  For Years = 1850 To 2050    For days = 0 To 3      MyDate = DateSerial(Years, 12, 28 + days)      woy1 = Format(MyDate, "ww", vbMonday, vbFirstFourDays)      woy2 = Format(MyDate, "ww", vbMonday, vbFirstFourDays)      If woy2 > 52 Then        If Format(MyDate + 7, "ww", vbMonday, vbFirstFourDays) = 2 Then _          woy2 = 1      End If      If woy1 <> woy2 Then        ToPrint = MyDate & String(13 - Len(CStr(MyDate)), " ")        ToPrint = ToPrint & Format(MyDate, "dddd") & _          String(10 - Len(Format(MyDate, "dddd")), " ")        ToPrint = ToPrint & woy1 & String(5 - Len(CStr(woy1)), " ")        ToPrint = ToPrint & woy2        Debug.Print ToPrint      End If    Next days  Next YearsEnd Sub					
  4. Удерживая клавишу CTRL и нажмите клавишу G, чтобы открыть окно "Интерпретация".
  5. Запустите проект, выберите командуCommand1и обратите внимание на следующие результаты в окне интерпретации.
       Format function:Date: 12/28/03   Day: Sun   Week: 52Date: 12/29/03   Day: Mon   Week: 53Date: 12/30/03   Day: Tue   Week: 1Date: 12/31/03   Day: Wed   Week: 1						
    Обратите внимание, что все недель данного формата начинаются с понедельника, таким образом, чтобы 12/29/2003 должны быть рассмотрены 1 неделя и не является частью Неделя 53.
  6. Нажмите на кнопкуCommand2Чтобы просмотреть список дат в указанном диапазоне, эта проблема. Список содержит дату, день недели (всегда понедельник) недели # формат (53) и она должна возвращать число недель (1). Например,:
    12/29/1851   Monday    53   112/31/1855   Monday    53   112/30/1867   Monday    53   112/29/1879   Monday    53   112/31/1883   Monday    53   112/30/1895   Monday    53   1...					

Устранение проблем

При использованииФормат:-или-Функции DatePartфункции, необходимо проверить возвращаемое значение и, когда 53, проверка другой и принудительного возврата 1, если это необходимо. Этот пример кода демонстрирует один из способов сделать это:
Function WOY (MyDate As Date) As Integer   ' Week Of Year  WOY = Format(MyDate, "ww", vbMonday, vbFirstFourDays)  If WOY > 52 Then    If Format(MyDate + 7, "ww", vbMonday, vbFirstFourDays) = 2 Then WOY = 1  End IfEnd Function				
Можно избежать с помощью этих функций для определения номера недель путем написания кода, который реализует правила ISO 8601, описанные выше. В следующем примере демонстрируется замена функция, возвращающая номер недели.

Пример выполнения шага

  1. Запустите стандартный EXE-файла проекта в Visual Basic. По умолчанию будет создана форма Form1..
  2. ИзProjectменю Добавить новый модуль, а затем вставьте в следующем коде:
    Option ExplicitFunction WeekNumber(InDate As Date) As Integer  Dim DayNo As Integer  Dim StartDays As Integer  Dim StopDays As Integer  Dim StartDay As Integer  Dim StopDay As Integer  Dim VNumber As Integer  Dim ThurFlag As Boolean  DayNo = Days(InDate)  StartDay = Weekday(DateSerial(Year(InDate), 1, 1)) - 1  StopDay = Weekday(DateSerial(Year(InDate), 12, 31)) - 1  ' Number of days belonging to first calendar week  StartDays = 7 - (StartDay - 1)  ' Number of days belonging to last calendar week  StopDays = 7 - (StopDay - 1)  ' Test to see if the year will have 53 weeks or not  If StartDay = 4 Or StopDay = 4 Then ThurFlag = True Else ThurFlag = False  VNumber = (DayNo - StartDays - 4) / 7  ' If first week has 4 or more days, it will be calendar week 1  ' If first week has less than 4 days, it will belong to last year's  ' last calendar week  If StartDays >= 4 Then      WeekNumber = Fix(VNumber) + 2   Else      WeekNumber = Fix(VNumber) + 1  End If  ' Handle years whose last days will belong to coming year's first   ' calendar week  If WeekNumber > 52 And ThurFlag = False Then WeekNumber = 1  ' Handle years whose first days will belong to the last year's   ' last calendar week  If WeekNumber = 0 Then     WeekNumber = WeekNumber(DateSerial(Year(InDate) - 1, 12, 31))  End IfEnd FunctionFunction Days(DayNo As Date) As Integer  Days = DayNo - DateSerial(Year(DayNo), 1, 0)End Function					
  3. ДобавитьCommandButtonв форму Form1.
  4. Вставьте следующий код в окно кода Form1:
    Private Sub Command1_Click()   Dim DateValue As Date, i As Integer      Debug.Print "   WeekNumber function:"   DateValue = #12/27/2003#   For i = 1 To 4   ' examine the last 4 days of the year       DateValue = DateAdd("d", 1, DateValue)       Debug.Print "Date: " & DateValue & "   Day: " & _          Format(DateValue, "ddd") & "   Week: " & WeekNumber(DateValue)   Next iEnd Sub					
  5. Удерживая клавишу CTRL и нажмите клавишу G, чтобы открыть окно "Интерпретация".
  6. Запустите проект и выберите командуCommand1для просмотра в окно проверки следующие результаты:
       WeekNumber function:Date: 12/28/03   Day: Sun   Week: 52Date: 12/29/03   Day: Mon   Week: 1Date: 12/30/03   Day: Tue   Week: 1Date: 12/31/03   Day: Wed   Week: 1					
    Обратите внимание, что понедельник считается равным 1 неделя, как оно должно быть.

Внимание! Эта статья переведена автоматически

Свойства

Номер статьи: 200299 — последний просмотр: 12/05/2015 10:27:25 — редакция: 2.0

Microsoft Visual Basic 6.0 Professional Edition, Microsoft Visual Basic Control Creation Edition, Microsoft Visual Basic 5.0 Learning Edition, Microsoft Visual Basic 5.0 Professional Edition, Microsoft Visual Basic 5.0 Enterprise Edition, Microsoft Visual Basic 4.0 Standard Edition, Microsoft Visual Basic for Applications 6.0

  • kbnosurvey kbarchive kbbug kbdatetime kbpending kbmt KB200299 KbMtru
Отзывы и предложения