Code Library

DAX · UDF

DataHora.Calendario

Gera uma tabela calendário com colunas gregorianas, ISO 8601 e fiscais, uma linha por dia.

Categoria: CalendárioTipo: UDFVersão: v1.2.0Fonte: Paulo André Jesus — OfficeTuningAtualizado em: 25/09/2026
Documentação completa na Function Library →

Sintaxe

DataHora.Calendario ( StartDate, EndDate, Locale, FirstDay, FiscalYearStartMonth [, Hemisphere] )

Argumentos

NomeTipoObrigatórioDescrição
StartDateSCALAR DATETIME VALSimPrimeira data (inclusive).
EndDateSCALAR DATETIME VALSimÚltima data (inclusive).
LocaleSCALAR STRING VALSimCultura dos nomes de mês e dia.
FirstDaySCALAR INT64 VALSimInício da semana, nos códigos de WEEKNUM: 1 (domingo), 2 ou 11 (segunda), 12 a 17 (terça a domingo), 21 (ISO 8601).
FiscalYearStartMonthSCALAR INT64 VALSimMês de início do ano fiscal, de 1 a 12. O ano fiscal leva o número do ano em que termina.
HemisphereSCALAR STRING VALNãoOpcional, padrão "S". Use "N" (ou "Norte", "North") para o hemisfério norte; qualquer outro valor vale como sul.

Retorno

Tabela

Código completo

DEFINE
    /// Gera uma tabela calendário com colunas gregorianas, ISO 8601, fiscais e estação do ano.
    /// @param {DATETIME} StartDate - Primeira data (inclusive).
    /// @param {DATETIME} EndDate - Última data (inclusive).
    /// @param {STRING} Locale - Cultura dos nomes de mês e dia, ex.: "pt-BR".
    /// @param {INT64} FirstDay - Início da semana, nos códigos de WEEKNUM: 1, 2, 11 a 17 ou 21 (ISO).
    /// @param {INT64} FiscalYearStartMonth - Mês de início do ano fiscal (1 a 12). O ano fiscal leva o número do ano em que termina.
    /// @param {STRING} Hemisphere - Opcional. "S" (padrão) ou "N": hemisfério usado nas estações do ano.
    /// @returns Tabela com uma linha por dia.
    FUNCTION DataHora.Calendario =
        (
            StartDate : SCALAR DATETIME VAL,
            EndDate : SCALAR DATETIME VAL,
            Locale : SCALAR STRING VAL,
            FirstDay : SCALAR INT64 VAL,
            FiscalYearStartMonth : SCALAR INT64 VAL,
            Hemisphere : SCALAR STRING VAL = "S"
        ) =>
        -- Dia em que a semana começa, na escala de WEEKDAY(data, 2): 1 = segunda ... 7 = domingo.
        -- WEEKDAY só aceita 1, 2 ou 3; os códigos 11 a 17 e 21 de WEEKNUM são convertidos aqui.
        VAR vInicioSemana =
            SWITCH (
                FirstDay,
                1, 7,  2, 1,  11, 1,  12, 2,  13, 3,
                14, 4, 15, 5, 16, 6,  17, 7,  21, 1,
                7
            )
        -- Hemisfério das estações: "N", "Norte" ou "North" = norte; qualquer outro valor = sul
        VAR vNorte = UPPER ( LEFT ( Hemisphere, 1 ) ) = "N"
        -- Idioma dos nomes das estações: pt e es; as demais culturas recebem inglês
        VAR vIdioma = LOWER ( LEFT ( Locale, 2 ) )
        VAR vCalendario =
            SELECTCOLUMNS ( CALENDAR ( StartDate, EndDate ), "Data Referência", [Date] )
        RETURN
            ADDCOLUMNS (
                vCalendario,
                "Data (AAAAMMDD)", FORMAT ( [Data Referência], "YYYYMMDD" ),
                "Data (ddd dd/mm/aaaa)", FORMAT ( [Data Referência], "DDD DD/MM/YYYY", Locale ),
                "Ano", YEAR ( [Data Referência] ),
                "Semestre #", IF ( MONTH ( [Data Referência] ) <= 6, 1, 2 ),
                "Semestre", "S" & IF ( MONTH ( [Data Referência] ) <= 6, 1, 2 ),
                "Trimestre #", QUARTER ( [Data Referência] ),
                "Trimestre", "T" & FORMAT ( [Data Referência], "Q" ),
                "Ano/Trimestre", FORMAT ( [Data Referência], "YYYY" ) & "/T" & FORMAT ( [Data Referência], "Q" ),
                "Mês #", MONTH ( [Data Referência] ),
                "Mês", FORMAT ( [Data Referência], "MMMM", Locale ),
                "Mês (Abreviado)", FORMAT ( [Data Referência], "MMM", Locale ),
                "Ano/Mês", FORMAT ( [Data Referência], "YYYY/MM" ),
                "Ano/Mês (Abreviado)", FORMAT ( [Data Referência], "YYYY/MMM", Locale ),
                "Semana #", WEEKNUM ( [Data Referência], FirstDay ),
                "Semana", WEEKNUM ( [Data Referência], FirstDay ) & "ª semana",
                -- Semana do mês de 1 a 6, contada a partir do dia em que a semana começa
                "Semana do Mês",
                    VAR vPrimeiroDia = DATE ( YEAR ( [Data Referência] ), MONTH ( [Data Referência] ), 1 )
                    VAR vDesloc = MOD ( WEEKDAY ( vPrimeiroDia, 2 ) - vInicioSemana + 7, 7 )
                    RETURN INT ( ( DAY ( [Data Referência] ) + vDesloc - 1 ) / 7 ) + 1,
                "Quinzena #", IF ( DAY ( [Data Referência] ) <= 15, 1, 2 ),
                "Quinzena", "Qz" & IF ( DAY ( [Data Referência] ) <= 15, 1, 2 ),
                -- 1 = primeiro dia da semana definido em FirstDay
                "Dia da Semana #", MOD ( WEEKDAY ( [Data Referência], 2 ) - vInicioSemana + 7, 7 ) + 1,
                "Dia da Semana", FORMAT ( [Data Referência], "dddd", Locale ),
                "Dia da Semana (Abreviado)", FORMAT ( [Data Referência], "ddd", Locale ),
                -- Verdadeiro/falso: sábado ou domingo
                "Fim-de-Semana", WEEKDAY ( [Data Referência], 2 ) >= 6,
                -- Estação meteorológica por trimestre de meses: 1 = dez a fev ... 4 = set a nov (use para classificar Estação)
                "Estação #", INT ( MOD ( MONTH ( [Data Referência] ), 12 ) / 3 ) + 1,
                "Estação",
                    VAR vTrimestre = INT ( MOD ( MONTH ( [Data Referência] ), 12 ) / 3 ) + 1
                    -- 1 = verão, 2 = outono, 3 = inverno, 4 = primavera; no norte, dez a fev é inverno
                    VAR vEstacao = IF ( vNorte, MOD ( vTrimestre + 1, 4 ) + 1, vTrimestre )
                    RETURN
                        SWITCH (
                            vEstacao,
                            1, "☀️ " & SWITCH ( vIdioma, "pt", "Verão", "es", "Verano", "Summer" ),
                            2, "🍂 " & SWITCH ( vIdioma, "pt", "Outono", "es", "Otoño", "Autumn" ),
                            3, "❄️ " & SWITCH ( vIdioma, "pt", "Inverno", "es", "Invierno", "Winter" ),
                            "🌸 " & SWITCH ( vIdioma, "pt", "Primavera", "es", "Primavera", "Spring" )
                        ),
                "Dia do Ano", DATEDIFF ( DATE ( YEAR ( [Data Referência] ), 1, 1 ), [Data Referência], DAY ) + 1,
                "Dia", DAY ( [Data Referência] ),
                "Início do Mês", DATE ( YEAR ( [Data Referência] ), MONTH ( [Data Referência] ), 1 ),
                "Fim do Mês", EOMONTH ( [Data Referência], 0 ),
                "Início do Trimestre", DATE ( YEAR ( [Data Referência] ), ( QUARTER ( [Data Referência] ) - 1 ) * 3 + 1, 1 ),
                "Fim do Trimestre", EOMONTH ( DATE ( YEAR ( [Data Referência] ), ( QUARTER ( [Data Referência] ) - 1 ) * 3 + 1, 1 ), 2 ),
                "Início do Ano", DATE ( YEAR ( [Data Referência] ), 1, 1 ),
                "Fim do Ano", DATE ( YEAR ( [Data Referência] ), 12, 31 ),
                "Semana ISO #", WEEKNUM ( [Data Referência], 21 ),
                -- Ano ISO = ano da quinta-feira da mesma semana
                "Ano ISO", YEAR ( [Data Referência] - ( WEEKDAY ( [Data Referência], 2 ) - 4 ) ),
                "Ano-Semana ISO",
                    YEAR ( [Data Referência] - ( WEEKDAY ( [Data Referência], 2 ) - 4 ) )
                        & "-" & RIGHT ( "00" & WEEKNUM ( [Data Referência], 21 ), 2 ),
                "Mês Fiscal #", MOD ( MONTH ( [Data Referência] ) - FiscalYearStartMonth + 12, 12 ) + 1,
                "Trimestre Fiscal #", ROUNDUP ( ( MOD ( MONTH ( [Data Referência] ) - FiscalYearStartMonth + 12, 12 ) + 1 ) / 3, 0 ),
                -- Ano fiscal = ano em que termina. Com início em janeiro, coincide com o ano civil.
                "Ano Fiscal #",
                    YEAR ( [Data Referência] )
                        + IF ( FiscalYearStartMonth > 1 && MONTH ( [Data Referência] ) >= FiscalYearStartMonth, 1, 0 ),
                "Ano Fiscal",
                    VAR vFYFim =
                        YEAR ( [Data Referência] )
                            + IF ( FiscalYearStartMonth > 1 && MONTH ( [Data Referência] ) >= FiscalYearStartMonth, 1, 0 )
                    RETURN
                        IF (
                            FiscalYearStartMonth = 1,
                            FORMAT ( vFYFim, "0" ),
                            RIGHT ( "0" & MOD ( vFYFim - 1, 100 ), 2 ) & "-" & RIGHT ( "0" & MOD ( vFYFim, 100 ), 2 )
                        )
            )

EVALUATE
DataHora.Calendario ( DATE ( 2026, 1, 1 ), DATE ( 2026, 12, 31 ), "pt-BR", 2, 7 )

-- Estações no hemisfério norte, em inglês: uma linha por mês
EVALUATE
FILTER (
    SELECTCOLUMNS (
        DataHora.Calendario ( DATE ( 2026, 1, 1 ), DATE ( 2026, 12, 31 ), "en-US", 2, 1, "N" ),
        "Data", [Data Referência],
        "Estação #", [Estação #],
        "Estação", [Estação]
    ),
    DAY ( [Data] ) = 1
)
-- jan e fev = ❄️ Winter · mar a mai = 🌸 Spring · jun a ago = ☀️ Summer · set a nov = 🍂 Autumn · dez = ❄️ Winter

Exemplos

TabDimCalendario =
DataHora.Calendario ( DATE ( 2023, 1, 1 ), DATE ( 2026, 12, 31 ), "pt-BR", 2, 7 )
// 2023 a 2026, semana começando na segunda, ano fiscal começando em julho

// 30/08/2026, com FirstDay = 1 e FiscalYearStartMonth = 1:
// Semana do Mês = 6 · Dia da Semana # = 1 · Ano Fiscal = "2026"

// Hemisfério norte, nomes das estações em inglês
TabDimCalendario =
DataHora.Calendario ( DATE ( 2026, 1, 1 ), DATE ( 2026, 12, 31 ), "en-US", 2, 1, "N" )

Dicas e observações

💡 Colunas: data (AAAAMMDD e ddd dd/mm/aaaa), ano, semestre, trimestre, mês, semana, semana do mês (1 a 6), quinzena, dia da semana, fim de semana (verdadeiro/falso), dia do ano, início e fim de mês, trimestre e ano, semana e ano ISO 8601, mês, trimestre e ano fiscais, estação do ano. 💡 Dia da Semana # começa em 1 no dia definido por FirstDay. 💡 Estação usa os meses meteorológicos (dez a fev, mar a mai, jun a ago, set a nov), não as datas de equinócio e solstício. Em Classificar por coluna, ordene Estação por Estação #. ⚠️ Nomes das estações em português (pt), espanhol (es) ou inglês (demais culturas). ⚠️ Depois de criar a tabela, marque-a como Tabela de Datas. ⚠️ A coluna Semana gera "ª semana" em qualquer Locale.