Operacje arytmetyczne na czasie
Część sekcji Logika i przepływ sterowania ścieżki GO w Coddy. Lekcja 63 z 68.
Teraz, gdy rozumiesz obiekty time.Time i wartości time.Duration, możesz wykonywać działania arytmetyczne, aby obliczać przeszłe lub przyszłe chwile. Go udostępnia dwie podstawowe metody do wykonywania działań arytmetycznych na czasie: Add i Sub.
Metoda Add przyjmuje wartość typu time.Duration i zwraca nową wartość time.Time, która reprezentuje pierwotny czas powiększony o czas trwania:
now := time.Now()
tomorrow := now.Add(24 * time.Hour)
fmt.Println(tomorrow)Metoda Sub działa na dwa sposoby. Gdy odejmujesz jedną wartość time.Time od drugiej, zwraca ona wartość time.Duration reprezentującą różnicę między nimi:
start := time.Now()
end := start.Add(2 * time.Hour)
difference := end.Sub(start) // Zwraca 2h0m0sTe metody ułatwiają obliczanie terminów, mierzenie upływu czasu lub planowanie przyszłych wydarzeń. Oryginalny obiekt time.Time pozostaje niezmieniony — obie metody zwracają nowe wartości, zgodnie z preferowaniem przez Go niezmiennych operacji.
Wyzwanie
ŁatwyUtwórz kalkulator terminów projektu, który wykorzystuje działania na czasie do określania kamieni milowych i terminów projektu. To wyzwanie sprawdzi Twoją umiejętność używania metod Add i Sub na obiektach time.Time do obliczania przyszłych dat i różnic czasu między zdarzeniami.
Otrzymasz dwa dane wejściowe:
- Ciąg zawierający informacje o rozpoczęciu projektu w formacie
"year:month:day:hour:minute"(np."2024:1:15:9:0") - Ciąg zawierający czas trwania zadań w formacie
"task1:duration_value:duration_unit,task2:duration_value:duration_unit"(np."Planning:5:Day,Development:3:Week,Testing:10:Day")
Twoje zadanie:
- Przeanalizować pierwsze dane wejściowe, dzieląc je po dwukropkach, aby wyodrębnić wartości roku, miesiąca, dnia, godziny i minuty
- Przekonwertować te wartości tekstowe na liczby całkowite i utworzyć czas rozpoczęcia projektu za pomocą
time.Date(użyćtime.UTCjako lokalizacji oraz 0 dla sekund i nanosekund) - Przeanalizować drugie dane wejściowe, dzieląc je po przecinkach, aby uzyskać poszczególne wpisy zadań
- Dla każdego wpisu zadania podzielić go po dwukropkach, aby wyodrębnić nazwę zadania, wartość czasu trwania i jednostkę czasu trwania
- Przekonwertować wartości czasu trwania na liczby całkowite i utworzyć obiekty
time.Duration, używając odpowiednich stałych:- Dla
"Day": pomnożyć przez24 * time.Hour - Dla
"Week": pomnożyć przez7 * 24 * time.Hour - Dla
"Hour": pomnożyć przeztime.Hour
- Dla
- Wyświetlić nagłówek aplikacji:
"=== PROJECT DEADLINE CALCULATOR ===" - Wyświetlić rozpoczęcie projektu:
"Project start time: [start_time_object]" - Obliczyć terminy zadań, dodając czas trwania każdego zadania do czasu zakończenia poprzedniego zadania (pierwsze zadanie rozpoczyna się w chwili rozpoczęcia projektu):
- Dla każdego zadania wyświetlić:
"Task: [task_name]"" Duration: [duration_object]"" Start: [task_start_time]"" End: [task_end_time]"(obliczone za pomocą metodyAdd)
- Obliczyć i wyświetlić harmonogram projektu:
"=== PROJECT TIMELINE ===""Project start: [start_time_object]""Project end: [final_task_end_time]""Total project duration: [total_duration_object]"(obliczone za pomocą metodySubmiędzy końcem projektu a jego rozpoczęciem)
- Wyświetlić analizę zadań:
"=== TASK ANALYSIS ===""Number of tasks: [number_of_tasks]""Longest task: [longest_task_name] ([longest_duration_object])""Shortest task: [shortest_task_name] ([shortest_duration_object])"
- Obliczyć czas między kolejnymi zadaniami i wyświetlić przerwy:
"=== TASK TRANSITIONS ==="- Dla każdej pary kolejnych zadań:
"[first_task_name] to [second_task_name]: [time_difference_object]"(powinno wynosić 0, ponieważ zadania następują bezpośrednio po sobie)
- Wyświetlić statystyki projektu:
"=== 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"
- Wyświetlić komunikat o ukończeniu:
"Project timeline calculation completed successfully"
Użyj pakietu time do operacji na czasie, pakietu strings do dzielenia ciągów wejściowych, pakietu strconv do konwertowania ciągów na liczby całkowite oraz pakietu fmt do formatowania danych wyjściowych. Pamiętaj, że metoda Add zwraca nowy obiekt time.Time reprezentujący pierwotny czas powiększony o czas trwania, a metoda Sub zwraca obiekt time.Duration reprezentujący różnicę między dwoma czasami. To wyzwanie pokazuje, jak zbudować kompletny harmonogram projektu za pomocą działań arytmetycznych na czasie.
Spróbuj swoich sił
package main
import (
"fmt"
"strconv"
"strings"
"time"
)
func main() {
// Wczytaj dane wejściowe
var startInfo string
var taskInfo string
fmt.Scanln(&startInfo)
fmt.Scanln(&taskInfo)
// Przetwórz informacje o czasie rozpoczęcia
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])
// Utwórz czas rozpoczęcia projektu
startTime := time.Date(year, time.Month(month), day, hour, minute, 0, 0, time.UTC)
// Przetwórz informacje o zadaniach
taskEntries := strings.Split(taskInfo, ",")
// TODO: Napisz swój kod poniżej
// - Przetwórz każdy wpis zadania, aby wyodrębnić nazwę, wartość czasu trwania i jednostkę
// - Utwórz obiekty czasu trwania dla każdego zadania
// - Oblicz czas rozpoczęcia i zakończenia każdego zadania
// - Znajdź najdłuższe i najkrótsze zadania
// - Oblicz statystyki projektu
// - Wyświetl wszystkie wymagane sekcje wyników
// Dane wyjściowe zostaną wygenerowane przez Twój kod powyżej
}Ta lekcja zawiera krótki quiz. Zacznij lekcję, żeby na niego odpowiedzieć i śledzić swoje postępy.
Wszystkie lekcje w sekcji Logika i przepływ sterowania
1Zaawansowane sterowanie przepływem
Instrukcja switch z `fallthrough`Przerywanie zagnieżdżonych pętliKontynuowanie określonej pętliInstrukcja `goto`Podsumowanie — zaawansowane sterowanie pętlami4Projekt: Prosta lista zadań
Konfiguracja projektuDodawanie zadania7Obsługa błędów — dogłębnie
Własne typy błędówOpakowywanie błędów za pomocą `%w`Rozpakowywanie za pomocą `errors.Is`Rozpakowywanie za pomocą `errors.As`Zrozumienie `panic`Używanie `recover`Podsumowanie — bezpieczne dzielenie10Praca z czasem
Pobieranie bieżącego czasuTworzenie określonej godzinyFormatowanie czasuParsowanie ciągów czasuCzas trwaniaOperacje arytmetyczne na czasieUśpienia i tickeryPodsumowanie — prosty timer2Struktury i metody
Definiowanie metod dla strukturOdbiorniki przez wartośćOdbiorniki przez wskaźnikWybór odbiornikówMetody a funkcjePodsumowanie — działanie struktur5Mapy w szczegółach
Mapy strukturWskaźniki jako wartości mapSprawdzanie, czy mapy są nilPorównywanie mapPodsumowanie — licznik częstości słów3Interfejsy (podstawy)
Czym jest interfejs?Definiowanie interfejsuImplementowanie interfejsuUżywanie typów interfejsowychPusty interfejsAsercje typuPrzełącznik typówPodsumowanie – kształty i zachowaniaPoćwicz samodzielnie: Kompilator Go online