Formação Oracle DBA Completa


Curiosidade: Como é feito o cálculo do timestamp e ISO

Curiosidade: Como é feito o cálculo do timestamp e ISO

27 de maio de 2019 0 Por Ramos de Souza Janones
Powered by Rock Convert

Este artigo tem como objetivo aprofundar em como é feito o cálculo do timestamp desde sua origem, passando pelo Java e outras linguagens de programação, em especial o SQL.

Como é feito esse cálculo?

Existe alguma padronização para esse cálculo uma ISO ou algo parecido?

timestamp do unix corresponde ao número de segundos desde a meia-noite do dia 01/01/1970 no fuso horário UTC sem considerar os segundos bissextos (tal como mencionado na resposta do ctgPi). Para simplificar, vamos denominar este momento no tempo de ponto zero. Assim, o timestamp do unixé o número de segundos desde o ponto zero.

timestamp do unix costuma ser representado de várias formas:

  • Quando representado como um inteiro de 32 bits com sinal, o timestamp do unix pode representar datas entre 13/12/1901 20:45:52 até 19/01/2038 03:14:07, ambas no UTC. O MySQL por exemplo, usa o tipo TIMESTAMP armazenado assim, e por causa disso é susceptível ao bug do ano 2038, o que é mais-ou-menos uma versão Unix do infame bug do ano 2000.
  • Quando representado como um inteiro de 32 bits sem sinal, ele pode representar datas entre 01/01/1970 00:00:00 até 07/02/2106 06:28:15, novamente ambas no UTC.
  • Quando representado por um número de 64 bits com sinal, ele pode representar datas entre 27/01/-292277022657 08:29:52 até 04/12/292277026596 15:30:07 (desconsiderando-se o fato de que antes de 1582 o calendário aplicado não era o gregoriano). Isso é um intervalo grande o bastante para incluir todo o período de tempo desde muito antes do Big Bang até muito depois do tempo calculado como o fim do universo como o conhecemos.

Há várias formas de se converter de timestamp do unix para uma data e vice-versa. Algumas formas são mais simples, outras mais complicadas. Mas o que importa é que todas elas cheguem no mesmo resultado em todos os casos. Então, eis o algoritmo para obter uma data/hora a partir do timestamp do unix:

Algoritmo de conversão de timestamp do unix para data/hora:

  1. Se pegarmos o timestamp do unix e dividirmos por 60, o quociente da divisão (vamos denominá-lo de minutosUnix) será o número de minutos desde o ponto zero. O resto será a quantidade de segundos transcorridos no minuto. Para valores negativos do timestamp do unix, aonde o quociente é zero ou negativo e o resto é negativo (mas não zero), deve-se somar 60 ao resto obtido e subtrair 1 do quociente obtido.
  2. Se pegarmos o minutosUnix e dividirmos por 60, o quociente da divisão (vamos denominá-lo de horasUnix) será o número de horas desde o ponto zero. O resto será a quantidade de minutos transcorridos na hora. Para valores negativos de minutosUnix, aonde o quociente é zero ou negativo e o resto é negativo (mas não zero), deve-se somar 60 ao resto obtido e subtrair 1 do quociente obtido.
  3. Se pegarmos o horasUnix e dividirmos por 24, o quociente da divisão (vamos denominá-lo de diasUnix) será o número de dias desde o ponto zero. O resto será a quantidade de horas transcorridas no dia. Para valores negativos de horasUnix, aonde o quociente é zero ou negativo e o resto é negativo (mas não zero), deve-se somar 24 ao resto obtido e subtrair 1 do quociente obtido.

A partir daqui, a situação fica um pouco mais complicada. O calendário gregoriano se repete a cada 400 anos, uma vez que temos anos bissextos a cada 4 anos (os anos cujo número é divisível por 4) mas com três exceções, que a saber, são os anos divisíveis por 100 mas não por 400.

VAI GOSTAR: Guia Jurídico Definitivo para Startups

VEJA TAMBÉM: Sucesso na Carreira com o LinkedIn

RECOMENDAMOS: Curso de Desenvolvimento de Games Completo

LEIA: Como Aprender Java e ir além do mercado de trabalho tradicional


Desta forma, cada ciclo de 400 anos no calendário gregoriano tem 146097 dias, pois:

((365 * 4) + 1) * 100 - 3 = 146097
  1. Vamos denominar como ciclosDe400Anos o quociente da divisão de diasUnix por 146097 e como diasEm400Anos o resto. Para valores negativos de diasUnix, aonde o quociente é zero ou negativo e o resto é negativo (mas não zero), deve-se somar 146097 ao resto obtido e subtrair 1 do quociente obtido.

Neste ciclo de 400 anos, com as três exceções citadas, temos ciclos de 4 anos com três anos não-bissextos e um ano bissexto, totalizando 1461 dias. Isso significa que nestes 400 anos há 97 ciclos de 4 anos com 1461 dias e 3 ciclos de 4 anos com 1460 dias.

Considerando que o ciclo de 4 anos de número 0 começa em 01/01/1970 e termina em 31/12/1973, então os ciclos de 4 anos que tem 1460 dias dentro destes 400 anos são os ciclos de número 32 – que corresponde ao ciclo de 2098-2101 contendo o ano 2100, o ciclo de número 57 – que corresponde ao ciclo de 2198-2201 contendo o ano 2200 e o ciclo de número 82 – que corresponde ao ciclo de 2298-2301 contendo o ano 2300. Estes três ciclos estão sem o dia 29 de fevereiro, mas podemos acrescentar artificialmente os dias 29 de fevereiro faltantes ao somar um dia a partir de 01/03/2100, mais um dia a partir de 01/03/2200 e mais um a partir de 01/03/2300, fazendo todos os ciclos terem 1461 dias. Assim, o dia 29 de fevereiro pulado (que na verdade é 1º de março), ocorre após serem transcorridos 789 dias em cada um destes ciclos de 4 anos (dois anos de 365 dias mais janeiro de 31 dias mais fevereiro de 28 dias = 789 dias). Desta forma:

  1. Incrementamos diasEm400Anos se o valor for maior ou igual a (32 * 1461 + 789), incrementamos novamente se for maior ou igual a (57 * 1461 + 789) e incrementamos uma terceira vez se for maior ou igual a (82 * 1461 + 789). Isso dará conta dos três dias 29 de fevereiro pulados, e fará o calendário resultante se repetir a cada quatro anos de 1461 dias e os três dias introduzidos artificialmente nunca ocorrerão.
  2. Vamos denominar como ciclosDeQuatroAnos o quociente da divisão de diasEmQuatroAnos por 1461 e como diasEmQuatroAnos o resto.

Para reduzir o período para um ano ao invés de quatro, podemos fazer algo semelhante ao que foi feito no passo 5 para considerar os três dias 29 de fevereiro pulados nos quatro anos. Considerando que no ciclo de quatro anos iniciado em 1970 (o mesmo valerá para todos os demais), o primeiro 29 de fevereiro pulado (em 1970) seria após transcorridos 59 dias (31 em janeiro e 28 em fevereiro), o de 1971 seria após 424 dias e o de 1973 após 1155 dias, então:

  1. Incrementamos diasEmQuatroAnos se o valor for maior ou igual a 59, incrementamos novamente se for maior ou igual a 425 e incrementamos uma terceira vez se for maior ou igual a 1157.
  2. Isso dará conta dos três dias 29 de fevereiro pulados, e fará o calendário resultante se repetir a cada um ano de 366 dias.
  3. O número 425 é usado ao invés de 424 por causa do dia acrescentado após o 59. O número 1157 é usado ao invés do 1155 por causa dos dois dias acrescentados no 59 e no 425.

Agora, teremos anos de 366 dias, já pulados todos os dias 29 de fevereiro que deveriam ser pulados e teremos um ciclo de 4 anos com 1464 dias (incluindo os três dias acrescentados artificialmente que nunca ocorrerão). Assim, podemos finalmente obter o ano:

  1. Vamos denominar como anoEmQuatroAnos o quociente da divisão de diasEmQuatroAnos por 366 e como diasNoAno o resto.
  2. O ano será a soma de anoEmQuatroAnos, mais quatro vezes o valor de ciclosDeQuatroAnos, mais quatrocentas vezes o valor de ciclosDe400Anos mais 1970.

E finalmente, obtemos o dia e o mês:

  1. Constrói-se uma tabela com o número de dias em cada mês, que corresponde a [31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31] e conta-se qual dia de qual mês corresponde o valor de diasNoAno, subtraindo de diasNoAno os dias de cada mês até que não seja mais possível subtrair. O mês em que não for possível subtrair é o mês correspondente ao timestamp do unixdado. O número de dias restantes mais um é o dia correspondente ao timestamp do unix dado.

O algoritmo delineado acima só funciona para datas do calendário gregoriano. Isso significa que ele produzirá resultados incorretos para timestamps do unix correspondentes a datas anteriores a adoção deste calendário.

Após a implementação disso, se você quiser, poderá fazer a conversão de fuso horário para algum que não seja UTC. Novamente, vale frisar que os segundos bissextos são desconsiderados.

Algoritmo de conversão de data/hora para timestamp do unix:

Para fazer o procedimento inverso:

  1. Subtraia 1970 do ano.
  2. Pegamos o ano subtraído de 1970 e dividimos por 400, denominando o quociente da divisão de periodosDe400Anos e o resto de anoNoPeriodoDe400Anos. Para valores aonde o ano subtraído de 1970 é negativo e o quociente é zero ou negativo e o resto é negativo (mas não zero), deve-se somar 400 ao resto obtido e subtrair 1 do quociente obtido.
  3. Pegamos o anoNoPeriodoDe400Anos e dividimos por 4, denominando o quociente da divisão de periodosDe4AnosNos400 e o resto de anoNoPeriodoDe4Anos.
  4. Calculamos o número de dias nos anos anteriores no período de quatro anos (e denominamos isso de diasNosAnosAnterioresDoPeriodoDe4Anos) ao olhar para o valor de anoNoPeriodoDe4Anos. Serão 365 dias para cada ano anterior.
  5. Se o valor de anoNoPeriodoDe4Anos for 3 (ou seja, o último do período de 4 anos), então o ano imediatamente anterior era bissexto (desconsiderando por ora os casos dos anos 2100, 2200 e 2300), e por causa disso, deve-se somar ainda mais um dia neste caso.
  6. Calculamos o número de dias transcorridos no ano ao pegar o número do dia, subtrair 1 e somar na tabela de número de meses o número de dias em todos os meses anteriores no ano. A tabela é [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]. Note que estou considerando fevereiro como tendo 28 dias. Isso será corrigido posteriormente se necessário.
  7. Calcula-se o número de dias desde 01/01/1970 (ainda necessitando correção posterior por causa de anos bissextos). Isso é computado como a soma do número de dias no ano, diasNosAnosAnterioresDoPeriodoDe4AnosperiodosDe4AnosNos400 vezes 1461 e periodosDe400Anos vezes 146097.
  8. Aplica-se a correção dos anos bissextos. Se anoNoPeriodoDe4Anos for igual a 2 e o mês for março para frente, soma-se um dia. Se anoNoPeriodoDe400Anos for maior que 130, ou igual a 130 em março ou depois, soma-se um dia. O mesmo vale para os anos de número 230 e 330. Com isso obtém-se o número total de dias desde 01/01/1970.
  9. timestamp do unix resultante é o número de segundos, mais o número de minutos vezes 60, mais o número de horas vezes 3600 (1 hora = 3600 segundos), mais o número de dias desde 01/01/1970 vezes 86400 (1 dia = 86400 segundos).

Novamente, o algoritmo delineado acima só funciona para datas do calendário gregoriano.

Algoritmo para se obter o dia da semana a partir do timestamp do unix:

Para obter-se o dia da semana a partir do timestamp do unix, o procedimento também é simples:

Powered by Rock Convert
  1. Divida o timestamp do unix por 86400 para obter o número de dias desde 01/01/1970 ao invés de o número de segundos. Para valores negativos do timestamp do unix, aonde o quociente é zero ou negativo e o resto é negativo (mas não zero), deve-se subtrair 1 do quociente obtido.
  2. Some 4 dias e obtenha o resto da divisão por 7. Para valores negativos de números de dias (após somar 4), aonde o quociente é zero ou negativo e o resto é negativo (mas não zero), deve-se somar 7 ao resto obtido.
  3. Mapeie o número resultante de forma que 0 seja domingo, 1 seja segunda-feira, etc.

Implementação:

Aqui vai uma implementação estilo reinventar a roda em Java, em especial no construtor que recebe como parâmetro o timestampUnix. O método getTimestamp() faz o processo inverso.

O método getDiaDaSemana() obtém o dia da semana. Traduzir o código abaixo para outras linguagens de programação deverá ser algo relativamente fácil também:

import java.util.Objects;
public final class DataUTC implements Comparable<DataUTC> {
private final int segundo;
private final int minuto;
private final int hora;
private final int dia;
private final int mes;
private final long ano;
private static int restoSemSinal(long a, int b) {
return (int) (a >= 0L
? a % b // Positivo.
: (b + (a % b)) % b); // Negativo.
}
private static long divisaoSemSinal(long a, int b) {
return a >= 0L
? a / b // Positivo.
: (a / b) - (a % b == 0 ? 0 : 1); // Negativo.
}
public DataUTC(int segundo, int minuto, int hora, int dia, int mes, long ano) {
this.segundo = segundo;
this.minuto = minuto;
this.hora = hora;
this.dia = dia;
this.mes = mes;
this.ano = ano;
}
public DataUTC(long timestampUnix) {
// Passo 1.
long minutosUnix = divisaoSemSinal(timestampUnix, 60);
segundo = restoSemSinal(timestampUnix, 60);
// Passo 2.
long horasUnix = divisaoSemSinal(minutosUnix, 60);
minuto = restoSemSinal(minutosUnix, 60);
// Passo 3.
long diasUnix = divisaoSemSinal(horasUnix, 24);
hora = restoSemSinal(horasUnix, 24);
// Passo 4.
long ciclosDe400Anos = divisaoSemSinal(diasUnix, 146097);
int diasEm400Anos = restoSemSinal(diasUnix, 146097);
// Passo 5.
if (diasEm400Anos >= 32 * 1461 + 789) diasEm400Anos++;
if (diasEm400Anos >= 57 * 1461 + 789) diasEm400Anos++;
if (diasEm400Anos >= 82 * 1461 + 789) diasEm400Anos++;
// Passo 6.
int ciclosDe4Anos = diasEm400Anos / 1461;
int diasEm4Anos = diasEm400Anos % 1461;
// Passo 7.
if (diasEm4Anos >= 59) diasEm4Anos++;
if (diasEm4Anos >= 425) diasEm4Anos++;
if (diasEm4Anos >= 1157) diasEm4Anos++;
// Passo 8.
int anoEm4Anos = diasEm4Anos / 366;
int diasNoAno = diasEm4Anos % 366;
// Passo 9.
ano = anoEm4Anos + ciclosDe4Anos * 4 + ciclosDe400Anos * 400 + 1970;
// Passo 10.
int[] tabelaDeMeses = {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
int contagemDeMeses = 0;
while (diasNoAno >= tabelaDeMeses[contagemDeMeses]) {
diasNoAno -= tabelaDeMeses[contagemDeMeses];
contagemDeMeses++;
}
mes = contagemDeMeses + 1;
dia = diasNoAno + 1;
}
public long getTimestamp() {
// Passo 1.
long anosDesde1970 = ano - 1970;
// Passo 2.
long periodosDe400Anos = divisaoSemSinal(anosDesde1970, 400);
int anoNoPeriodoDe400Anos = restoSemSinal(anosDesde1970, 400);
// Passo 3.
int periodosDe4AnosNos400 = anoNoPeriodoDe400Anos / 4;
int anoNoPeriodoDe4Anos = anoNoPeriodoDe400Anos % 4;
// Passo 4.
int diasNosAnosAnterioresDoPeriodoDe4Anos = 365 * anoNoPeriodoDe4Anos + (anoNoPeriodoDe4Anos == 3 ? 1 : 0);
// Passo 5.
long diasNoAno = dia - 1;
int[] tabelaDeMeses = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
for (int i = 0; i < mes - 1; i++) {
diasNoAno += tabelaDeMeses[i];
}
// Passo 6.
long dias = diasNoAno
+ diasNosAnosAnterioresDoPeriodoDe4Anos
+ periodosDe4AnosNos400 * 1461
+ periodosDe400Anos * 146097;
// Passo 7.
if (anoNoPeriodoDe4Anos == 2 && mes > 2) dias++;
if (anoNoPeriodoDe400Anos > 130 || (anoNoPeriodoDe400Anos == 130 && mes > 2)) dias--;
if (anoNoPeriodoDe400Anos > 230 || (anoNoPeriodoDe400Anos == 230 && mes > 2)) dias--;
if (anoNoPeriodoDe400Anos > 330 || (anoNoPeriodoDe400Anos == 330 && mes > 2)) dias--;
// Passo 8.
return segundo + 60 * minuto + 60 * 60 * hora + 60 * 60 * 24 * dias;
}
public static enum DiaDaSemana {
DOMINGO, SEGUNDA_FEIRA, TERCA_FEIRA, QUARTA_FEIRA, QUINTA_FEIRA, SEXTA_FEIRA, SABADO;
}
public DiaDaSemana getDiaDaSemana() {
// Passo 1.
long diasDesde1970 = divisaoSemSinal(getTimestamp(), 86400);
// Passo 2.
int diaDaSemana = restoSemSinal(diasDesde1970 + 4, 7);
// Passo 3.
return DiaDaSemana.values()[diaDaSemana];
}
public int getSegundo() {
return segundo;
}
public int getMinuto() {
return minuto;
}
public int getHora() {
return hora;
}
public int getDia() {
return dia;
}
public int getMes() {
return mes;
}
public long getAno() {
return ano;
}
@Override
public int hashCode() {
return Objects.hash(segundo, minuto, hora, dia, mes, ano);
}
@Override
public boolean equals(Object obj) {
if (!(obj instanceof DataUTC)) return false;
DataUTC outro = (DataUTC) obj;
return this.segundo == outro.segundo && this.minuto == outro.minuto && this.hora == outro.hora
&& this.dia == outro.dia && this.mes == outro.mes && this.ano == outro.ano;
}
@Override
public int compareTo(DataUTC other) {
Objects.requireNonNull(other);
if (this.ano != other.ano) return this.ano > other.ano ? 1 : -1;
if (this.mes != other.mes) return this.mes > other.mes ? 1 : -1;
if (this.dia != other.dia) return this.dia > other.dia ? 1 : -1;
if (this.hora != other.hora) return this.hora > other.hora ? 1 : -1;
if (this.minuto != other.minuto) return this.minuto > other.minuto ? 1 : -1;
if (this.segundo != other.segundo) return this.segundo > other.segundo ? 1 : -1;
return 0;
}
@Override
public String toString() {
return String.format("%02d/%02d/%04d %02d:%02d:%02d", dia, mes, ano, hora, minuto, segundo);
}
}

E aqui vai o teste da classe acima:

import static DataUTC.DiaDaSemana.*;
public class Main {
public static void main(String[] args) {
test(-12_005_355_554L, "26/07/1589 03:00:46", QUARTA_FEIRA);
test( -1_234_567_890L, "18/11/1930 00:28:30", TERCA_FEIRA);
test(   -777_777_777L, "09/05/1945 22:37:03", QUARTA_FEIRA);
test(              -1, "31/12/1969 23:59:59", QUARTA_FEIRA);
test(              0L, "01/01/1970 00:00:00", QUINTA_FEIRA);
test(              1L, "01/01/1970 00:00:01", QUINTA_FEIRA);
test(      451551900L, "23/04/1984 07:05:00", SEGUNDA_FEIRA);
test(    915_148_801L, "01/01/1999 00:00:01", SEXTA_FEIRA);
test(  1_000_000_000L, "09/09/2001 01:46:40", DOMINGO);
test(  1_234_567_890L, "13/02/2009 23:31:30", SEXTA_FEIRA);
test(  4_294_967_295L, "07/02/2106 06:28:15", DOMINGO);
test(  6_505_355_555L, "23/02/2176 11:12:35", SEXTA_FEIRA);
test( 15_505_445_554L, "07/05/2461 04:12:34", SABADO);
}
public static void test(long timestamp, String esperado, DataUTC.DiaDaSemana diaEsperado) {
DataUTC data = new DataUTC(timestamp);
String dataObtida = data.toString();
long timestampObtido = data.getTimestamp();
DataUTC.DiaDaSemana diaObtido = data.getDiaDaSemana();
if (!esperado.equals(dataObtida) || timestamp != data.getTimestamp() || diaEsperado != diaObtido) {
System.out.println("Falhou para " + timestamp + " -> " + esperado + " " + diaEsperado
+ ", veio " + dataObtida + " (" + timestampObtido + ") " + diaObtido);
} else {
System.out.println("Funcionou para " + timestamp + " -> " + esperado + " " + diaEsperado + ".");
}
}
}

E aqui vai o resultado do teste:

Funcionou para -12005355554 -> 26/07/1589 03:00:46 QUARTA_FEIRA.
Funcionou para -1234567890 -> 18/11/1930 00:28:30 TERCA_FEIRA.
Funcionou para -777777777 -> 09/05/1945 22:37:03 QUARTA_FEIRA.
Funcionou para -1 -> 31/12/1969 23:59:59 QUARTA_FEIRA.
Funcionou para 0 -> 01/01/1970 00:00:00 QUINTA_FEIRA.
Funcionou para 1 -> 01/01/1970 00:00:01 QUINTA_FEIRA.
Funcionou para 451551900 -> 23/04/1984 07:05:00 SEGUNDA_FEIRA.
Funcionou para 915148801 -> 01/01/1999 00:00:01 SEXTA_FEIRA.
Funcionou para 1000000000 -> 09/09/2001 01:46:40 DOMINGO.
Funcionou para 1234567890 -> 13/02/2009 23:31:30 SEXTA_FEIRA.
Funcionou para 4294967295 -> 07/02/2106 06:28:15 DOMINGO.
Funcionou para 6505355555 -> 23/02/2176 11:12:35 SEXTA_FEIRA.
Funcionou para 15505445554 -> 07/05/2461 04:12:34 SABADO.

Representações no banco de dados e linguagens de programação

Os bancos de dados representam datas de diversas formas diferentes, não necessariamente com o timestamp do unix.

Outros formatos:

Existem outros sabores de timestamp?

  • O Excel (tal como o ctgPi mencionou na resposta dele) usa como base o número de dias desde 01/01/1900, tendo as horas como parte fracionária. Curiosamente, este formato advém do paleozóico Lotus 1-2-3, que tinha um bug que fazia o ano de 1900 ser considerado bissexto e este bug existe no Excel até hoje (fonte).
  • Corrigindo-se o bug, a data base dele passa a ser 31/12/1899. A implementação deste formato, seria parecida com a implementação acima dada para o timestamp do unix, apenas usando como base o ano de 1900 ao invés de 1970, trabalhando-se com números de ponto flutuante ao invés de inteiros, multiplicando-se/dividindo-se o timestamppor 86400 e dando-se um jeitinho no dia (que não existiu) 29 de fevereiro de 1900.
  • Existe uma variante do timestamp do unix que consiste na contagem de milisegundos desde 01/01/1970 ao invés do número de segundos. Basta multiplicar/dividir o timestamp por 1000 e somar os milisegundos.
  • Outro exemplo notável é o antigo formato de data/hora do MS-DOS, que também foi utilizado pelo formato ZIP. Este formato consistia do armazenamento da data em 2 bytes e a hora em outros 2 bytes:
    • Para a data, os 7 primeiros bits representavam o ano desde 1980 (e portanto só podia representar anos de 1980 até 2107), os próximos 4 bits representavam o mês e os últimos 5 bits representavam o dia.
    • O horário, era armazenado com 5 bits para a hora, 6 bits para o minuto e 5 bits para o segundo dividido por dois. Este detalhe dos segundos, fazia com que a precisão/resolução dele fosse de 2 segundos, sendo o número de segundos resultantes sempre par, pois ele era armazenado como um número de 0 a 29 a ser multiplicado por 2, o que causava vários problemas em programas que esperavam que o número do segundo não tivesse este comportamento.

E o ISO?

Há um formato ISO 8601 de representação de datas (na verdade um conjunto de formatos). Isso não tem a ver com o timestamp do unix, é apenas uma forma universal de representar datas, vez que diferentes países a representam de forma diferente, o que pode gerar confusão. Por exemplo, no Brasil costuma-se usar DD/MM/YYYY, enquanto que nos EUA usa-se MM/DD/YYYY, na Armênia usa-se DD.MM.YYYY, no Japão usa-se YYYY年MM月DD日(fonte)

O formato ISO 8601 consiste em um dos seguintes:

  • Ano no formato YYYY.
  • Ano e mês no formato YYYY-MM.
  • Ano, mês e dia no formato YYYY-MM-DD.
  • Ano, mês, dia, horas, minutos e fuso horário no formato YYYY-MM-DDThh:mmTZD.
  • Ano, mês, dia, horas, minutos, segundos e fuso horário no formato YYYY-MM-DDThh:mm:ssTZD.
  • Ano, mês, dia, horas, minutos, segundos, frações de segundos e fuso horário no formato YYYY-MM-DDThh:mm:ss.sTZD.

Aonde:

  • YYYY é o ano com quatro dígitos.
  • MM é o mês com dois dígitos.
  • DD é o dia com dois dígitos.
  • hh é a hora com dois dígitos.
  • mm são os minutos com dois dígitos.
  • ss são os segundos com dois dígitos.
  • s são as frações de segundos, com um ou mais dígitos.
  • TZD é o fuso horário.
  • Os caracteres -:T e . são escritos literalmente.

O fuso horário pode ter o formato +hh:mm ou -hh:mm para especificar um deslocamento em relação ao UTC, ou pode ser representado como Z para expressar o próprio UTC.

Desta forma, estas são algumas datas e horas expressas no ISO 8601:

  • 2012
  • 2012-04
  • 2012-04-21
  • 2012-04-21T12:21Z
  • 2012-04-21T12:21+03:00
  • 2012-04-21T12:21:44-10:30
  • 2012-04-21T12:21:44.6-04:00
  • 2012-04-21T12:21:44.67893-09:20
  • 2012-04-21T12:21:44.67893Z

Mais detalhes sobre o calendário gregoriano fornecido pelo PPK (obrigado ao ctgPi pelo comentário). Eis o link: http://www.quirksmode.org/blog/archives/2009/04/making_time_saf.html

Powered by Rock Convert
Siga os bons!

Ramos de Souza Janones

Janones, é um empreendedor brasileiro apaixonado por empreendedorismo e tecnologia. Ao longo dos anos trabalhando com o desenvolvimento de softwares desktop desde a linguagem Clipper, passando pelo Delphi e atualmente com Java.

Optou pela formação de Publicidade e Marketing por sua segunda empresa de tecnologia ter participado do "boom" da internet nos anos 90 e na procura de melhorar seus conhecimentos em negócios.

Em razão da principal formação e profundos conhecimentos em programação e banco de dados, é capaz de realizar o desenvolvimento de aplicativos web, desktop e mobile com maior criatividade e inovação que profissionais de desenvolvimento com uma formação única e mais especifica, dedicada somente ao desenvolvimento de softwares.

Com toda sua experiência com empresas de software, sua formação e paixão por negócios escreveu o livro "Marketing para Empresas e Profissionais de Software", publicado pela editora carioca Ciência Moderna em 2012. Além de outros livros sobre programação.

Últimos posts por Ramos de Souza Janones (exibir todos)

Sumário
Curiosidade: Como é feito o cálculo do timestamp e ISO
Nome do artigo
Curiosidade: Como é feito o cálculo do timestamp e ISO
Descrição
Este artigo tem como objetivo aprofundar em como é feito o cálculo do timestamp desde sua origem, passando pelo Java e outras linguagens de programação, em especial o SQL.
Autor
Nome
Ramos da Informática
Logo

Frontend Do Zero Ao Profissional