Erro: Formato ou funções PartData podem retornar número errado de semana para a última segunda-feira no ano

Traduções deste artigo Traduções deste artigo
ID do artigo: 200299 - Exibir os produtos aos quais esse artigo se aplica.
Expandir tudo | Recolher tudo

Neste artigo

Sintomas

Quando você usar a formato ou PartData a função para determinar o número da semana para datas usando a seguinte sintaxe:
Format(AnyDate, "ww", vbMonday, vbFirstFourDays)

DatePart("ww", AnyDate, vbMonday, vbFirstFourDays)
				
última segunda-feira em alguns anos de calendário é retornado como semana 53 quando deveria ser semana 1.

Causa

Ao determinar o número da semana de uma data de acordo com o padrão ISO 8601, chamada de função subjacente para o arquivo Oleaut32.dll retorna por engano semana 53 em vez da semana 1 para a última segunda-feira em alguns anos.

Resolução

Use uma função definida pelo usuário para retornar o número da semana com base nas regras para o padrão ISO 8601. Um exemplo é incluído neste artigo.

Situação

A Microsoft confirmou que este é um problema no arquivo Oleaut32.dll.

Mais Informações

O padrão ISO 8601 é usado extensivamente na Europa e inclui o seguinte:
  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."
				
isso pode ser implementado aplicando essas regras para semanas do calendário:
  • Um ano é dividido em semanas do calendário ou 52 53.
  • Uma semana tem 7 dias. Segunda-feira é dia 1, domingo é dia 7.
  • A primeira semana de um ano é aquele que contém pelo menos quatro dias.
  • Se um ano não é concluído em um domingo, seus últimos dias 1-3 pertencem a primeira semana de calendário do próximo ano ou primeiros dias de 1-3 do próximo ano pertencem a última semana de calendário do ano atual.
  • Apenas um ano de início ou concluir uma quinta-feira possui 53 semanas do calendário.
No Visual Basic e Visual Basic for Applications, toda a funcionalidade data, exceto para a função DateSerial , proveniente de chamadas para o ficheiro Oleaut32.dll. Porque os Format() e DatePart() funções podem retornar o número da semana do calendário para uma determinada data, ambos são afetados por esse bug. Para evitar esse problema, você deve usar o código alternativo que este artigo fornece.

Etapas para reproduzir o problema

  1. Inicie um projeto Standard EXE no Visual Basic. O Form1 é criado por padrão.
  2. Adicione dois CommandButtons ao Form1.
  3. Cole o código a seguir na janela código do Form1:
    Option Explicit
    
    Private Sub Command1_Click()
    ' This code tests a "problem" date and the days around it
    Dim DateValue As Date
    Dim i As Integer
    
    Debug.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 i
    End Sub
    
    Private 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 Years
    End Sub
    					
  4. Mantenha pressionada a tecla CTRL e pressione a tecla G para abrir a janela imediata.
  5. Executa o projeto, clique no Command1 e observe os seguintes resultados na janela Verificação imediata:
       Format function:
    Date: 12/28/03   Day: Sun   Week: 52
    Date: 12/29/03   Day: Mon   Week: 53
    Date: 12/30/03   Day: Tue   Week: 1
    Date: 12/31/03   Day: Wed   Week: 1
    						
    Observe que com este formato, todas as semanas começar com segunda-feira, para que 29/12/2003 deve ser considerada o início da semana 1 e não faz parte do semana 53.
  6. Clique no Command2 para ver uma lista de datas que esse problema ocorrer no intervalo especificado. A lista inclui a data, o dia de semana (de sempre segunda), a semana # retornado pelo formato (53) e o número da semana deve retornar (1). Por exemplo:
    12/29/1851   Monday    53   1
    12/31/1855   Monday    53   1
    12/30/1867   Monday    53   1
    12/29/1879   Monday    53   1
    12/31/1883   Monday    53   1
    12/30/1895   Monday    53   1
    ...
    					

Soluções alternativas

Se você usar as funções Format ou PartData , você precisará verificar o valor de retorno e, quando ele for 53, executar outra verificação e forçar um retorno de 1, se necessário. Este exemplo de código demonstra uma maneira de fazer isso:
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 If
End Function
				
você pode evitar o uso dessas funções para determinar o número da semana ao escrever código que implementa as regras de ISO 8601 descritas acima. O exemplo a seguir demonstra uma função de substituição para retornar o número da semana.

Exemplo passo a passo

  1. Inicie um projeto Standard EXE no Visual Basic. O Form1 é criado por padrão.
  2. A partir do menu Project , adicione um novo módulo e cole-o no código a seguir:
    Option Explicit
    
    Function 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 If
    End Function
    
    Function Days(DayNo As Date) As Integer
      Days = DayNo - DateSerial(Year(DayNo), 1, 0)
    End Function
    					
  3. Adicione um CommandButton ao Form1.
  4. Cole o código a seguir na janela código do 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 i
    End Sub
    					
  5. Mantenha pressionada a tecla CTRL e pressione a tecla G para abrir a janela imediata.
  6. Executa o projeto e clique no Command1 para ver os seguintes resultados na janela Verificação imediata:
       WeekNumber function:
    Date: 12/28/03   Day: Sun   Week: 52
    Date: 12/29/03   Day: Mon   Week: 1
    Date: 12/30/03   Day: Tue   Week: 1
    Date: 12/31/03   Day: Wed   Week: 1
    					
    Observação Essa segunda é considerada como como deve ser 1 semana.

Propriedades

ID do artigo: 200299 - Última revisão: quinta-feira, 24 de junho de 2004 - Revisão: 3.0
A informação contida neste artigo aplica-se a:
  • Microsoft Visual Basic 6.0 Learning Edition
  • Microsoft Visual Basic 6.0 Professional Edition
  • Microsoft Visual Basic Enterprise Edition for Windows 6.0
  • 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 4.0 Professional Edition
  • Microsoft Visual Basic 4.0 de 32 Bits Enterprise Edition
  • Microsoft Visual Basic for Applications 5.0
  • Microsoft Visual Basic for Applications 6.0
Palavras-chave: 
kbmt kbbug kbdatetime kbpending KB200299 KbMtpt
Tradução automática
IMPORTANTE: Este artigo foi traduzido por um sistema de tradução automática (também designado por Machine Translation ou MT), não tendo sido portanto traduzido ou revisto por pessoas. A Microsoft possui artigos traduzidos por aplicações (MT) e artigos traduzidos por tradutores profissionais, com o objetivo de oferecer em português a totalidade dos artigos existentes na base de dados de suporte. No entanto, a tradução automática não é sempre perfeita, podendo conter erros de vocabulário, sintaxe ou gramática. A Microsoft não é responsável por incoerências, erros ou prejuízos ocorridos em decorrência da utilização dos artigos MT por parte dos nossos clientes. A Microsoft realiza atualizações freqüentes ao software de tradução automática (MT). Obrigado.
Clique aqui para ver a versão em Inglês deste artigo: 200299

Submeter comentários

 

Contact us for more help

Contact us for more help
Connect with Answer Desk for expert help.
Get more support from smallbusiness.support.microsoft.com