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
| Aspecto | RFC 3339 | ISO 8601 |
|---|---|---|
| Nome completo | RFC 3339: Data e hora na Internet | ISO 8601: Elementos de dados e formatos de intercâmbio |
| Objetivo | Protocolos de Internet e APIs da web | Intercâmbio geral de dados |
| Flexibilidade | Opções de formato restritas e limitadas | Variações flexíveis e múltiplas |
| Fuso horário | Obrigatório (offset ou Z) | Opcional |
| Segundos fracionários | Obrigatório para precisão inferior a um segundo | Opcional |
| Exemplo | 2024-01-15T12:30:45.123Z | 2024-01-15T12:30:45 ou 2024-01-15T12:30:45.123+05:30 |
| Corpo padrão | IETF | ISO |
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= DataT= Separador de tempo (literal)hh:mm:ss= Hora[.s]= Segundos fracionários opcionaisTZD= Designador de fuso horário obrigatório (Zou+/-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:
- APIs da Web – respostas JSON, cabeçalhos HTTP
- Protocolos de rede - E-mail, HTTP, WebSocket
- Tokens de autenticação - JWT, carimbos de data/hora OAuth
- Serviços em nuvem – respostas da AWS e da API do Google Cloud
- 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:
- Armazenamento de banco de dados - Colunas DATETIME
- Nomeação de arquivos - Logs, backups
- Arquivos de dados - CSV, JSON, XML
- Interfaces de usuário - Flexibilidade de exibição
- 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
| Idioma | Biblioteca | Notas |
|---|---|---|
| JavaScript | Date.toISOString() | Integrado |
| JavaScript | momento.js | Suporte total a RFC 3339 |
| JavaScript | luxão | Suporte total a RFC 3339 |
| Pitão | datahora | Parcial (use dateutil) |
| Pitão | seta | Suporte total a RFC 3339 |
| Java | java.time | Instant e ZonedDateTime |
| Vá | tempo | Constante de formato RFC3339 |
| Rubi | Tempo.iso8601 | Suporta 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
| Recurso | RFC 3339 | ISO 8601 | Vencedor |
|---|---|---|---|
| APIs da Web | ✓ Preferencial | ✓ | RFC 3339 |
| Protocolos de rede | ✓ Obrigatório | - | RFC 3339 |
| Armazenamento de banco de dados | ✓ | ✓ | Gravata |
| Nomeação de arquivos | ✓ | ✓ Preferencial | ISO 8601 |
| Flexibilidade | - | ✓ | ISO 8601 |
| Rigor | ✓ | - | RFC 3339 |
| Fuso horário obrigatório | ✓ | - | RFC 3339 |
| Suporte ao navegador | ✓ | ✓ | Gravata |
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.