Guide

RFC 3339 vs ISO 8601: Qual é a diferença?

Introdução

Ao trabalhar com carimbos de data/hora no desenvolvimento de software, você encontrará dois padrões principais: RFC 3339 e ISO 8601. Embora relacionados, eles servem a propósitos diferentes e têm distinções importantes. Este guia explica as principais diferenças e ajuda você a escolher o formato certo para suas necessidades.

Visão geral rápida

AspectoRFC 3339ISO 8601
Nome completoRFC 3339: Data e hora na InternetISO 8601: Elementos de dados e formatos de intercâmbio
ObjetivoProtocolos de Internet e APIs da webIntercâmbio geral de dados
FlexibilidadeOpções de formato restritas e limitadasVariações flexíveis e múltiplas
Fuso horárioObrigatório (offset ou Z)Opcional
Segundos fracionáriosObrigatório para precisão inferior a um segundoOpcional
Exemplo2024-01-15T12:30:45.123Z2024-01-15T12:30:45 ou 2024-01-15T12:30:45.123+05:30
Corpo padrãoIETFISO

Principais diferenças

1. Rigor de formato

RFC 3339 é mais rigoroso - define exatamente um formato:

YYYY-MM-DDThh:mm:ss[.s]TZD

Onde:

  • AAAA-MM-DD = Data
  • T = Separador de tempo (literal)
  • hh:mm:ss = Hora
  • [.s] = Segundos fracionários opcionais
  • TZD = Designador de fuso horário obrigatório (Z ou +/-HH:MM)

ISO 8601 é flexível - permite vários formatos:

// All valid ISO 8601 formats
2024-01-15                    // Date only
20240115                      // Basic format (no separators)
2024-01-15T12:30:45           // Without timezone
2024-01-15T12:30:45Z          // With Z (UTC)
2024-01-15T12:30:45+05:30     // With offset
2024-01-15T12:30:45.123456    // With microseconds
20240115T123045               // Basic format with time

2. Requisito de fuso horário

RFC 3339 requer fuso horário:

// Valid RFC 3339 timestamps
2024-01-15T12:30:45Z          // UTC (Z)
2024-01-15T12:30:45+05:30     // With offset
2024-01-15T12:30:45-08:00     // With offset

// Invalid RFC 3339 - missing timezone
2024-01-15T12:30:45           // ❌ Not RFC 3339

ISO 8601 torna o fuso horário opcional:

// Valid ISO 8601 timestamps
2024-01-15T12:30:45Z          // With timezone
2024-01-15T12:30:45+05:30     // With offset
2024-01-15T12:30:45           // Without timezone ✅

3. Segundos fracionários

RFC 3339 permite segundos fracionários, mas não os exige:

// Both valid RFC 3339
2024-01-15T12:30:45Z          // Whole seconds
2024-01-15T12:30:45.123Z      // With milliseconds
2024-01-15T12:30:45.123456Z    // With microseconds

ISO 8601 também permite segundos fracionários:

// All valid ISO 8601
2024-01-15T12:30:45Z
2024-01-15T12:30:45.123Z
2024-01-15T12:30:45.123456Z
2024-01-15T12:30:45.123456789Z // Nanoseconds

4. Separadores

RFC 3339 requer hífens e dois pontos:

// Valid RFC 3339
2024-01-15T12:30:45Z

// Invalid RFC 3339
20240115T123045Z      // ❌ Basic format
2024/01/15T12:30:45Z  // ❌ Wrong separators

ISO 8601 permite formato básico (sem separadores):

// Both valid ISO 8601
2024-01-15T12:30:45Z    // Extended format
20240115T123045Z        // Basic format ✅

Qual formato você deve usar?

Use RFC 3339 para:

  1. APIs da Web – respostas JSON, cabeçalhos HTTP
  2. Protocolos de rede - E-mail, HTTP, WebSocket
  3. Tokens de autenticação - JWT, carimbos de data/hora OAuth
  4. Serviços em nuvem – respostas da AWS e da API do Google Cloud
  5. Especificações OpenAPI – documentação da API

Exemplo: resposta da API Web

{
  "user_id": "12345",
  "created_at": "2024-01-15T12:30:45.123Z",
  "updated_at": "2024-01-15T14:20:30.456Z",
  "expires_at": "2024-02-15T12:30:45.123Z"
}

Use ISO 8601 para:

  1. Armazenamento de banco de dados - Colunas DATETIME
  2. Nomeação de arquivos - Logs, backups
  3. Arquivos de dados - CSV, JSON, XML
  4. Interfaces de usuário - Flexibilidade de exibição
  5. Arquivos de configuração - Quando o fuso horário depende do contexto

Exemplo: Registro de Banco de Dados

-- ISO 8601 in database
INSERT INTO events (id, timestamp, description)
VALUES (1, '2024-01-15T12:30:45', 'Event occurred');

Exemplo: Nomenclatura de Arquivo

# ISO 8601 basic format (no timezone needed for local files)
backup-20240115-123045.sql.gz
log-20240115-123045.txt

Exemplos de código

JavaScript

Analisando RFC 3339

// Both RFC 3339 and ISO 8601 parse correctly
const timestamp1 = new Date('2024-01-15T12:30:45.123Z');
console.log(timestamp1.toISOString()); // "2024-01-15T12:30:45.123Z"

const timestamp2 = new Date('2024-01-15T12:30:45+05:30');
console.log(timestamp2.toISOString()); // "2024-01-15T07:00:45.000Z"

Gerando RFC 3339

function toRFC3339(date) {
  // JavaScript's toISOString() returns RFC 3339-compatible format
  return date.toISOString();
}

console.log(toRFC3339(new Date()));
// "2024-01-15T12:30:45.123Z"

###Píton

Analisando RFC 3339

from datetime import datetime

# Both RFC 3339 and ISO 8601 work with datetime
timestamp1 = datetime.fromisoformat('2024-01-15T12:30:45.123')
print(timestamp1.isoformat())

# For parsing with timezone
from dateutil import parser

timestamp2 = parser.parse('2024-01-15T12:30:45.123+05:30')
print(timestamp2)

Gerando RFC 3339

from datetime import datetime, timezone

def to_rfc3339(dt):
    """Convert datetime to RFC 3339 format."""
    if dt.tzinfo is None:
        # Assume UTC if no timezone
        dt = dt.replace(tzinfo=timezone.utc)
    return dt.strftime('%Y-%m-%dT%H:%M:%S.%f%z').replace('+00:00', 'Z')

now = datetime.now(timezone.utc)
print(to_rfc3339(now))
# "2024-01-15T12:30:45.123456Z"

###Java

Analisando RFC 3339

import java.time.Instant;
import java.time.format.DateTimeFormatter;

// RFC 3339 formatter
DateTimeFormatter rfc3339 = DateTimeFormatter.ISO_INSTANT;

// Parse RFC 3339 timestamp
Instant instant = Instant.parse("2024-01-15T12:30:45.123Z");
System.out.println(instant); // 2024-01-15T12:30:45.123Z

// Format to RFC 3339
String formatted = instant.format(rfc3339);
System.out.println(formatted); // 2024-01-15T12:30:45.123Z

Casos de uso comuns

1. APIs RESTful

Prática recomendada: use RFC 3339

// API Response
app.get('/api/users/:id', (req, res) => {
  const user = getUser(req.params.id);

  res.json({
    id: user.id,
    name: user.name,
    created_at: user.createdAt.toISOString(), // RFC 3339
    updated_at: user.updatedAt.toISOString()  // RFC 3339
  });
});

2. Armazenamento de banco de dados

Prática recomendada: use ISO 8601 (ou DATETIME nativo)

-- MySQL
CREATE TABLE events (
  id INT PRIMARY KEY,
  event_time DATETIME(3),  -- Millisecond precision
  description VARCHAR(255)
);

-- ISO 8601 format for INSERT
INSERT INTO events VALUES (1, '2024-01-15 12:30:45.123', 'Event');

3. Arquivos de log

Prática recomendada: use ISO 8601 com fuso horário

# Nginx log format example
2024-01-15T12:30:45.123+00:00 [INFO] Request received
2024-01-15T12:30:45.456+00:00 [INFO] Processing complete

4. Autenticação

Prática recomendada: use RFC 3339

// JWT token with RFC 3339 timestamps
const token = {
  sub: 'user123',
  iat: Math.floor(Date.now() / 1000),           // Issued at
  exp: Math.floor(Date.now() / 1000) + 3600     // Expires in 1 hour
};

Guia de compatibilidade

Bibliotecas que suportam RFC 3339

IdiomaBibliotecaNotas
JavaScriptDate.toISOString()Integrado
JavaScriptmomento.jsSuporte total a RFC 3339
JavaScriptluxãoSuporte total a RFC 3339
PitãodatahoraParcial (use dateutil)
PitãosetaSuporte total a RFC 3339
Javajava.timeInstant e ZonedDateTime
tempoConstante de formato RFC3339
RubiTempo.iso8601Suporta ambos

Suporte ao navegador

// All modern browsers support RFC 3339 parsing
const date1 = new Date('2024-01-15T12:30:45.123Z');
const date2 = new Date('2024-01-15T12:30:45+05:30');

// IE 11 and older may have issues with fractional seconds
// Polyfill recommended for legacy browsers

Erros Comuns

1. Misturando formatos

// ❌ Bad: Mixing formats in same API
{
  "created_at": "2024-01-15T12:30:45Z",      // RFC 3339
  "updated_at": "2024-01-15 12:30:45",      // SQL format
  "expires_at": 1705313445000                  // Unix timestamp
}

// ✅ Good: Consistent RFC 3339 format
{
  "created_at": "2024-01-15T12:30:45.000Z",
  "updated_at": "2024-01-15T12:35:30.456Z",
  "expires_at": "2024-02-15T12:30:45.123Z"
}

2. Esquecendo o fuso horário

// ❌ Bad: Missing timezone (ambiguous)
const timestamp = '2024-01-15T12:30:45';

// ✅ Good: Include timezone
const timestamp = '2024-01-15T12:30:45Z';      // UTC
const timestamp = '2024-01-15T12:30:45+05:30'; // Local

3. Usando formatos fora do padrão

// ❌ Bad: Custom format
const timestamp = '01/15/2024 12:30:45 PM';

// ✅ Good: RFC 3339
const timestamp = '2024-01-15T12:30:45Z';

Tabela de comparação

RecursoRFC 3339ISO 8601Vencedor
APIs da Web✓ PreferencialRFC 3339
Protocolos de rede✓ Obrigatório-RFC 3339
Armazenamento de banco de dadosGravata
Nomeação de arquivos✓ PreferencialISO 8601
Flexibilidade-ISO 8601
Rigor-RFC 3339
Fuso horário obrigatório-RFC 3339
Suporte ao navegadorGravata

Perguntas frequentes

P: RFC 3339 é igual a ISO 8601?

R: A RFC 3339 é um subconjunto da ISO 8601. A RFC 3339 define um perfil estrito da ISO 8601 especificamente para uso em protocolos de Internet. Todos os carimbos de data/hora RFC 3339 são válidos para ISO 8601, mas nem todos os carimbos de data/hora ISO 8601 são válidos para RFC 3339.

P: Qual formato devo usar para minha API?

R: Use RFC 3339. É o padrão para APIs da web, garante a presença de informações de fuso horário e é amplamente suportado por todas as linguagens de programação e estruturas.

P: Posso armazenar carimbos de data/hora no banco de dados como ISO 8601?

R: Sim, mas a maioria dos bancos de dados possui tipos nativos de data e hora. Use o tipo de coluna DATETIME ou TIMESTAMP do seu banco de dados em vez de armazenar como string. Quando você precisar exportar/importar dados, use a representação de string ISO 8601.

P: Como posso validar o formato RFC 3339?

R: Use regex ou validação de biblioteca:

// Regex for RFC 3339
const rfc3339Regex = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d+)?(Z|[+-]\d{2}:\d{2})$/;

if (!rfc3339Regex.test(timestamp)) {
  throw new Error('Invalid RFC 3339 format');
}

P: E quanto aos carimbos de data/hora Unix?

R: Os carimbos de data/hora Unix (milissegundos ou segundos desde a época) também são válidos para muitos casos de uso, especialmente:

  • Cálculos internos
  • Aplicações de alto desempenho
  • Comparações de tempo

No entanto, o RFC 3339 é melhor para:

  • Respostas da API (legíveis por humanos)
  • Armazenamento em arquivos de texto
  • Exibir aos usuários

Conclusão

RFC 3339 e ISO 8601 servem a propósitos diferentes, mas relacionados:

  • Use RFC 3339 para APIs da Web, protocolos de rede e qualquer cenário que exija carimbos de data/hora rigorosos e com reconhecimento de fuso horário
  • Use a ISO 8601 para intercâmbio geral de dados, nomenclatura de arquivos e cenários onde a flexibilidade é necessária

Ambos os padrões são amplamente suportados e interoperáveis. Escolha com base em seu caso de uso específico, mas mantenha a consistência em seu aplicativo.

Recursos relacionados