Aritmética de Tempo
Parte da seção Lógica & Fluxo do Journey de GO da Coddy — lição 63 de 68.
Agora que você entende os objetos time.Time e os valores time.Duration, você pode realizar operações aritméticas para calcular horários passados ou futuros. Go fornece dois métodos essenciais para aritmética de tempo: Add e Sub.
O método Add recebe um time.Duration e retorna um novo time.Time que representa o horário original mais a duração:
now := time.Now()
tomorrow := now.Add(24 * time.Hour)
fmt.Println(tomorrow)O método Sub funciona de duas maneiras. Quando você subtrai um time.Time de outro, ele retorna um time.Duration representando a diferença entre eles:
start := time.Now()
end := start.Add(2 * time.Hour)
difference := end.Sub(start) // Retorna 2h0m0sEsses métodos tornam simples o cálculo de prazos, a medição do tempo decorrido ou o agendamento de eventos futuros. O objeto time.Time original permanece inalterado - ambos os métodos retornam novos valores, seguindo a preferência do Go por operações imutáveis.
Desafio
FácilCrie uma calculadora de prazos de projeto que utilize aritmética de tempo para determinar marcos e prazos do projeto. Este desafio testará sua habilidade de usar os métodos Add e Sub em objetos time.Time para calcular datas futuras e diferenças de tempo entre eventos.
Você receberá duas entradas:
- Uma string contendo informações de início do projeto no formato
"year:month:day:hour:minute"(ex:"2024:1:15:9:0") - Uma string contendo durações de tarefas no formato
"task1:duration_value:duration_unit,task2:duration_value:duration_unit"(ex:"Planning:5:Day,Development:3:Week,Testing:10:Day")
Sua tarefa é:
- Analisar a primeira entrada dividindo-a por dois pontos para extrair os valores de ano, mês, dia, hora e minuto
- Converter esses valores de string para inteiros e criar um horário de início do projeto usando
time.Date(usetime.UTCpara a localização, 0 para segundos e nanossegundos) - Analisar a segunda entrada dividindo-a por vírgulas para obter as entradas de tarefas individuais
- Para cada entrada de tarefa, dividir por dois pontos para extrair o nome da tarefa, o valor da duração e a unidade de duração
- Converter os valores de duração para inteiros e criar objetos
time.Durationusando as constantes apropriadas:- Para
"Day": multiplique por24 * time.Hour - Para
"Week": multiplique por7 * 24 * time.Hour - Para
"Hour": multiplique portime.Hour
- Para
- Exibir o cabeçalho da aplicação:
"=== PROJECT DEADLINE CALCULATOR ===" - Exibir o início do projeto:
"Project start time: [start_time_object]" - Calcular os prazos das tarefas adicionando a duração de cada tarefa ao horário de término da tarefa anterior (a primeira tarefa começa no horário de início do projeto):
- Para cada tarefa, exibir:
"Task: [task_name]"" Duration: [duration_object]"" Start: [task_start_time]"" End: [task_end_time]"(calculado usando o métodoAdd)
- Calcular e exibir a linha do tempo do projeto:
"=== PROJECT TIMELINE ===""Project start: [start_time_object]""Project end: [final_task_end_time]""Total project duration: [total_duration_object]"(calculado usando o métodoSubentre o fim e o início do projeto)
- Exibir a análise das tarefas:
"=== TASK ANALYSIS ===""Number of tasks: [number_of_tasks]""Longest task: [longest_task_name] ([longest_duration_object])""Shortest task: [shortest_task_name] ([shortest_duration_object])"
- Calcular o tempo entre tarefas consecutivas e exibir os intervalos:
"=== TASK TRANSITIONS ==="- Para cada par de tarefas consecutivas:
"[first_task_name] to [second_task_name]: [time_difference_object]"(deve ser 0, pois as tarefas são consecutivas)
- Exibir as estatísticas do projeto:
"=== PROJECT STATISTICS ===""Total working days: [total_duration_in_hours_divided_by_24]""Total working hours: [total_duration_in_hours]""Project spans [number_of_calendar_days] calendar days"
- Exibir a mensagem de conclusão:
"Project timeline calculation completed successfully"
Use o pacote time para operações de tempo, o pacote strings para dividir as strings de entrada, o pacote strconv para converter strings em inteiros e o pacote fmt para saída formatada. Lembre-se que o método Add retorna um novo objeto time.Time representando o tempo original mais a duração, e o método Sub retorna um time.Duration representando a diferença entre dois tempos. Este desafio demonstra como construir um cronograma de projeto completo usando operações aritméticas de tempo.
Experimente você mesmo
package main
import (
"fmt"
"strconv"
"strings"
"time"
)
func main() {
// Ler a entrada
var startInfo string
var taskInfo string
fmt.Scanln(&startInfo)
fmt.Scanln(&taskInfo)
// Analisar as informações do horário de início
startParts := strings.Split(startInfo, ":")
year, _ := strconv.Atoi(startParts[0])
month, _ := strconv.Atoi(startParts[1])
day, _ := strconv.Atoi(startParts[2])
hour, _ := strconv.Atoi(startParts[3])
minute, _ := strconv.Atoi(startParts[4])
// Criar o horário de início do projeto
startTime := time.Date(year, time.Month(month), day, hour, minute, 0, 0, time.UTC)
// Analisar as informações das tarefas
taskEntries := strings.Split(taskInfo, ",")
// TODO: Escreva seu código abaixo
// - Processar cada entrada de tarefa para extrair nome, valor de duração e unidade
// - Criar objetos de duração para cada tarefa
// - Calcular os horários de início e término das tarefas
// - Encontrar as tarefas mais longas e mais curtas
// - Calcular as estatísticas do projeto
// - Exibir todas as seções de saída obrigatórias
// A saída será gerada pela sua implementação acima
}Esta lição inclui um quiz rápido. Comece a lição para respondê-lo e acompanhar seu progresso.
Todas as lições de Lógica & Fluxo
1Fluxo de Controle Avançado
Switch com `fallthrough`Interrompendo Loops AninhadosContinuando um Loop EspecíficoA Instrução `goto`Recapitulação - Controle de Loop Avançado4Projeto: Lista de Tarefas Simples
Configuração do ProjetoAdicionando uma Tarefa7Tratamento de Erros em Profundidade
Tipos de Erro PersonalizadosWrapping de Erros com `%w`Unwrapping com `errors.Is`Unwrapping com `errors.As`Entendendo o `panic`Usando o `recover`Recapitulação - Divisão Segura10Trabalhando com Tempo
Obtendo o Horário AtualCriando um Horário EspecíficoFormatando o TempoParsing de Strings de TempoDuração de TempoAritmética de TempoSleep e TickersRecapitulação - Timer Simples2Structs e Métodos
Definindo Métodos em StructsRecebedores de ValorRecebedores de PonteiroEscolhendo RecebedoresMétodos vs FunçõesRecapitulação - Comportamento de Structs5Mapas em Profundidade
Mapas de StructsPonteiros como Valores de MapVerificando Mapas NilComparando MapasRecapitulação - Contador de Frequência de Palavras3Interfaces (O Básico)
O que é uma Interface?Definindo uma InterfaceImplementando uma InterfaceUsando Tipos de InterfaceInterface VaziaAsserções de TipoType SwitchRecapitulação - Formas e Comportamentos