Skip to content

Time Toolbox

A toolbox de tempos de datas é uma expansão da toolbox de Quantidades e Medidas que estende os conceitos relacionados a períodos de tempo e incorpora operações especificas relacionadas a tempos e datas.

O MiddleHeaven entende o Tempo como um continuum embora todas as operações são discretas ao nível do milissegundo. Este continuum é normalmente chamado “linha do tempo” e os pontos nessa linha “pontos no tempo” (TimePoint). Relógios não medem tempo, eles medem a passagem (elipse) do tempo. Ou seja, eles medem o intervalo entre dois pontos selecionados sobre a linha do tempo. O tempo que passou (ElapsedTime) é portanto a quantidade fundamental para toolbox de tempos e datas. A sua unidade no SI é o segundo.

Referencial Temporal

Embora o tempo é realmente mensurável em intervalos, na prática nós precisamos referir-nos a pontos na linha do tempo de forma destingível e univoca. Porque, fisicamente, nenhum ponto é destingível de outro, é necessário escolher um desses pontos como referencia e medir todo o tempo que passou em relação a esse ponto de referencia. Este ponto de referencia recebe o nome de Época (epoch). O Java usa a época definida pelo Unix ( 1 de Janeiro de 1970 às 00:00:00 horas ) e mantém o numero de milissegundos desde então. Em Java é possível obter esse numero invocando System.currentTimeMillis().

Relógios e o “tempo atual”

Obter o tempo passado diretamente com System.currentTimeMillis() é um problema. Quando é necessário testar aplicações (ou classes) você não pode esperar até um certo tempo para fazer o teste, nem pode ficar brincando de mexer no relógio do seu computador ( não é prático). Você precisa, então, controlar o conceito de “tempo atual”. O MiddleHeaven introduz o conceito de Relógio (Clock). Um relógio é um objeto capaz de especificar o “tempo atual”.

clocks2

Um relógio tem três propriedades principais:

  • O “tempo atual” – retorna o ponto na linha do tempo que é considerado “agora”.
  • Fuso Horário (TimeZone) – nem todos os relógios em cada cidade do mundo mostram o mesmo “tempo atual”. As diferenças são relacionadas à distancia geográfica, à posição relativa em relação ao movimento aparente do Sol e convenções  econômicas e politicas como o Horário de Verão.  O “tempo atual” em diferentes relógios só pode ser relacionado se um fuso horário for anexado a cada um deles e os diferentes fusos tiverem uma relação entre si.
  • Cadência – o ritmo em que o tempo passa. Em um relógio “normal” o tempo passa ao ritmo de 1 segundo por  segundo. Isto significa que para cada 1 segundo que passa na linha do tempo, o relógio indica a passagem de 1 segundo. Relógios defeituosos (ou submetidos a efeitos relativistas) tem cadências diferentes e é por isso que se atrasam ou adiantam. Prover relógios com diferentes cadências pode simular a passagem do tempo mais depressa, mais devagar, ou simplesmente ter um tempo fixo sem ter que esperar que o tempo “real” chegue nesse ponto.  Uma tarefa ativada a cada hora pode, assim, ser ativada a cada minuto , segundo ou dia.

O MiddleHeaven vem com vários relogios.

  • MachineClock é aquele que substitui a consulta aSystem.currentTimeMillis(). O fuso horário é o padrão para o local da máquina e a cadencia é 1.
  • StaticClock é um relogio de cadencia 0,o que significa que o tempo que ele indica não muda. Você pode escolher qual o ponto do tempo e o fuso horário que deseja. Muito util para testes.
  • SpeedyClock utiliza a cadencia real de um outro relogio (padrão Decorator) e multiplica-a por um fator de cadencia configurável. Desta forma podemos acelerar ou atrazar a passagem do tempo.
  • SNTPUniversalTimeClock é um relogio ainda experimental cujo propósito é sempre estar em sincronismo com outro relógio em um servidor externo, usando para isso o protocolo SNTP. Isto pode ser muito util se a sua aplicação é distribuida. diferentes parts da aplicação podem ter seu relogio sincronizado com o relogio de um servidor central de forma que todos os dados temporais registrados ( horas e datas ) tenham significado e estejam correlacionados.
  • AlarmClock é um relógio especial que envia um evento para todos ClockTickListener registrados. A mecânica de funcionamento é obtida de um outro Relógio ( padrão Decorator), assim,  você pode correr um AlarmClock normalmente embutindo um MachineClock ou acelerado com um SpeedyClock. O AlarmClock é utilizado na toolbox de agendamento de trabalho (Work Scheduling) e estes mecanism permitem testar o funcionamento em tempo não-real.

Cronologia

Após termos um relógio que nos dá um meio viável de conhecer o “tempo atual” precisamos de refinar o nosso modelo de épocas. Isto porque, diferentes culturas ao redor do mundo escolheram diferentes pontos no tempo para serem a origem do seu referencial temporal. Estes pontos são normalmente escolhidos por tradição e convenções entres os membros da mesma cultura. A partir deles outros pontos de relevância são determinados. Isto forma uma detalhamento especifico que atribui significado aos pontos na linha do tempo. Isto forma uma cronologia (Chronology)

Uma cronologia é uma sequencia de eventos de referencia para uma dada cultura ( ou culturas) que permitem aos seus membros determinar a posição relativa de outros quaisquer pontos na linha do tempo, mapeando qualquer evento para um ponto no tempo designado pelo tempo que passou desde o ponto original.

Além disso, diferentes culturas escolhem diferentes modelos para avaliar , contar e se referir a pontos na linha do tempo. A maioria das culturas tem o conceito de “dia”, “mês” e “ano”, nem elas diferem no tamanho desdes intervalos de tempo.

Adicionalmente eventos políticos na História das culturas cria hiatos entre modelos subsequentes utilizados pela mesma cultura. O objecto Chronology encapsula todas as logicas de calculo associadas a estas variações. Diferentes cronologias podem ser implementadas de acordo com a diferentes culturas e regras ou de acordo com diferentes tecnologias ou API subjacentes.

Calendários e Efemérides

Diferentes grupos  dentro da mesma cultura podem definir suas próprias categorias e classificações para os dias ou grupos de dias ( por exemplo, empresas podem definir os dias uteis de trabalho de acordo com o seu trabalho – férias coletivas, por exemplo)

Para manter registro de todas estas informações o conceito de calendários foi criado. Um calendário não é apenas um agrupamento de dias, mas um lembrete dos eventos para os diferentes dias :as efemérides. O MiddleHeaven introduz um modelo de efemérides (EphemerisModel) para modelar o uso dos calendários. O modelo de efemérides depende do cronologia subjacente e pode ser usado para definir várias efemérides para um dado dia.  O MiddleHeaven já vem com a classe EasterBasedCalculatedEphemerisModel que calcula dias de referencia a partir da Páscoa. O dia da páscoa, em si mesmo é calculado por algoritmo que usa o ano do calendário Gregoriano. As outras efemérides como o carnaval, quarta-feira de cinzas, pentecostes, etc… são calculados relativamente a esse dia através de regras fixas.

“Efeméride” é apenas um nome pomposo para “evento que acontece em uma data especifica”, portanto qualquer agendamento pessoal ou de negócios também cai nesta categoria.

Modelo

O diagrama mostra as classes principais e a relação entre elas.

timetoolbox1

A área azul é o elo para a relação com a toolbox de Quantidades e Medidas. TimeInterval  faz  a transição para o núcleo de tipos  da Time Toolbox. Ele herda da classe de uso genérico Interval e aproveita o fato de TimePoint ser Comparable ( já que existe uma ordem natural na linha do tempo). Os relógios dá significado ao conceito de “tempo atual” e permitem estimar a passagem do tempo. Relógios (Clock) são relacionados a Fusos Horários (TimeZone) que por sua vez são relacionados a posições geográficas e culturas. A classe Chonology provê mecanismos para contar e correlacionar o pontos do tempo entre culturas e epocas. O EphemerisModel relaciona eventos do dia a dia como a Pascoa, o Natal, o Dia da Árvore ou a sua proxima consulta ao dentista.

Um modelo do tempo só está completo selecionando uma implementação para cada conceito. O MiddleHeaven dá suporte a isto introduzindo a classe TimeContext. Um contexto temporal é formado por :

  • Um objeto Clock para definir o “tempo atual” e permitir a contagem do tempo.
  • Um objecto TimeZoneTable para correlacionar relogios ao redor do mundo
  • Uma Chronologia para dá significado a conceitos como “dia” e “mês” de uma forma dependente da cultura selecionada.
  • UmEphemerisModel para manter registro de eventos do dia a dia.

O objeto TimeContext atua como um registro (padrão Register) para ele mesmo para você possa definir um para cada aplicação.

Uso

Aqui está um extrato de um test unitário que exemplifica o uso da Time Toolbox, em particular a manipulação de tipos de tempo e data e o EphemerisModel. O EphemerisModel pode ser usado para trabalhar com aritmética dependente de  feriados/dias uteis. O código testa se 5 dias uteis depois de 2008-5-28 é o dia 2008-6-4. Por fim , testa se 2008-6-6 é o quinto dia util de Junho de 2008

01
02 EphemerisModel model = new EasterBasedCalculatedEphemerisModel () ;
03
04 DateHolder start = CalendarDate.date ( 2008 , 5 , 28 ) ;
05 DateHolder end = CalendarDate.date ( 2008 , 6 , 4 ) ;
06
07 assertEquals ( end, model.addWorkingDays ( 5 , start )) ;
08 assertEquals ( start, model.subtractWorkingDays ( 5 , end )) ;
09
10 start = CalendarDate.date ( 2008 , 6 , 2 ) ;
11 end = CalendarDate.date ( 2008 , 6 , 9 ) ;
12
13 assertEquals ( end, model.addWorkingDays ( 5 , start )) ;
14 assertEquals ( start, model.subtractWorkingDays ( 5 , end )) ;
15
16 assertEquals ( CalendarDate.date ( 2008 , 6 , 6 ) ,
model.getOrdinalWorkingDayOfMonth
( Month.ofYear ( 2008 , 6 ) , 5 )) ;
17
18


Code 1: exemplo de uso

Por detrás dos panos

A esta hora você deve estar pensando “Isto não é um clone da JSR 310?” A resposta é não. A Time Toolbox foi desenvolvida com vários objetivos de unificação que não existem na JSR 310, além de ser uma expansão da toolbox de Quantidades e Medidas. A Joda Time e a Time and Money API fora as principais inspirações (tal como foram para a JSR 310) mas o esforço foi secar a API e alguns conceitos foram realinhados ( por exemplo o conceito do objeto Duration no joda time é implementado pelo objeto Period no MiddleHeaven e vice-versa. Esta alteração foi feita para estar de acordo com o conceito físico de “periodo” que é usado na padronização da ISO e em ciencias.) Além disso nem a JSR 310 , nem a Joda Time permitem modelar contextos temporais ou modelos de efemérides, e portanto abstrações dessas API seriam necessárias em todo o caso, portanto, porquê não abstrair tudo logo de uma vez ?

Atualmente o MiddleHeaven apenas define uma Chronologia baseada na classe GregorianCalendar do Java padrão, contudo assim que o Java 1.7 for liberado uma nova cronologia baseada na JSR 310 será adicionada.

Agendamento de Tarefas (Work Scheduling)

O agendamento de tarefas pode ser alcançado por API como o Quartz ou classes padrão da plataforma Java como Timer. Contudo, estas API apenas usam o relogio interno do computador para o agendamento. Isto tornas os testes complicados e às vezes impossiveis. O MiddleHeaven abraça a necessidade real, prática ( podemos dizer, pragmática) de testar o desenvolvimento das aplicações favorecendo testes automáticos a experiencias de teste. Voltaremos ao assunto quando discutirmos a WorkToolbox.

O mdelo de efemérides pretente uma forma simples e extensivel do programador final poder implementar e disponibilizar informações pertinentes à aplicação em calendários. Normalmente feriados são importantes para calcular cronogramas, assim como periodos de férias. Além disso é possivel integrar este objeto como software de agendamento como o Google Calendar.

Deixe um Comentário

Deixe uma Resposta

Preencha os seus detalhes abaixo ou clique num ícone para iniciar sessão:

Logótipo da WordPress.com

Está a comentar usando a sua conta WordPress.com Terminar Sessão / Alterar )

Imagem do Twitter

Está a comentar usando a sua conta Twitter Terminar Sessão / Alterar )

Facebook photo

Está a comentar usando a sua conta Facebook Terminar Sessão / Alterar )

Google+ photo

Está a comentar usando a sua conta Google+ Terminar Sessão / Alterar )

Connecting to %s

%d bloggers like this: