Tạo thời điểm cụ thể
Thuộc phần Logic và luồng điều khiển trong hành trình GO của Coddy. Bài học 59 trên 68.
Dù time.Now() cho bạn biết thời điểm hiện tại, bạn thường sẽ cần làm việc với ngày giờ cụ thể. Go cung cấp hàm time.Date để tạo đối tượng time.Time biểu thị ngày giờ bất kỳ mà bạn chỉ định.
Hàm time.Date nhận tám tham số theo đúng thứ tự này: năm, tháng, ngày, giờ, phút, giây, nano giây và múi giờ. Đây là cú pháp cơ bản:
birthday := time.Date(1990, time.March, 15, 14, 30, 0, 0, time.UTC)Lưu ý rằng Go dùng các hằng số như time.March để biểu thị tháng, giúp code dễ đọc hơn so với khi dùng số. Nếu muốn, bạn cũng có thể dùng số nguyên (1-12). Tham số múi giờ thường dùng time.UTC cho giờ UTC hoặc time.Local cho múi giờ cục bộ của hệ thống.
Cách này giúp bạn kiểm soát hoàn toàn việc tạo ra bất kỳ thời điểm cụ thể nào, dù đó là ngày sinh nhật, hạn chót hay ngày lịch sử. Đối tượng time.Time tạo ra hoạt động giống hệt đối tượng từ time.Now() và có thể dùng với mọi thao tác thời gian tương tự.
Thử thách
DễTạo ứng dụng dòng thời gian cho các sự kiện lịch sử, sử dụng time.Date để biểu diễn ngày và giờ cụ thể trong lịch sử. Thử thách này sẽ kiểm tra khả năng tạo các đối tượng time.Time cho những thời điểm lịch sử chính xác và hiển thị chúng theo định dạng có tổ chức.
Bạn sẽ nhận được hai đầu vào:
- Một chuỗi chứa các sự kiện lịch sử theo định dạng
"event1:year:month:day:hour:minute,event2:year:month:day:hour:minute"(ví dụ:"Moon Landing:1969:7:20:20:17,Berlin Wall Fall:1989:11:9:21:0") - Một chuỗi chứa các tùy chọn hiển thị được phân tách bằng dấu phẩy theo định dạng
"option1,option2,option3"(ví dụ:"chronological,details,summary")
Nhiệm vụ của bạn là:
- Phân tích đầu vào thứ nhất bằng cách tách theo dấu phẩy để lấy từng mục sự kiện
- Với mỗi mục sự kiện, tách theo dấu hai chấm để trích xuất tên sự kiện, năm, tháng, ngày, giờ và phút
- Chuyển các chuỗi số thành số nguyên và tạo một đối tượng
time.Timecho mỗi sự kiện bằngtime.Date(dùngtime.UTClàm tham số múi giờ, đồng thời đặt giây và nano giây là 0) - Hiển thị tiêu đề ứng dụng:
"=== HISTORICAL TIMELINE APPLICATION ===" - Hiển thị thông báo xác nhận đang tải sự kiện:
"Loading historical events..." - Với mỗi sự kiện, hiển thị:
"Loaded: [event_name] - [complete_time_object]" - Phân tích đầu vào thứ hai bằng cách tách theo dấu phẩy để lấy các tùy chọn hiển thị
- Xử lý từng tùy chọn hiển thị:
- Với
"chronological": Hiển thị"=== CHRONOLOGICAL ORDER ===", tiếp theo là các sự kiện được sắp xếp theo ngày, từ sớm nhất đến muộn nhất, theo định dạng"[event_name]: [year]-[month]-[day] at [hour]:[minute] UTC" - Với
"details": Hiển thị"=== DETAILED INFORMATION ===", tiếp theo là các dòng sau cho mỗi sự kiện (bốn dòng cuối được thụt vào hai dấu cách):Event: [event_name] Date: [year]-[month]-[day] Time: [hour]:[minute] UTC Weekday: [weekday_name] Unix timestamp: [unix_seconds] - Với
"summary": Hiển thị"=== TIMELINE SUMMARY ===", tiếp theo là:"Total events: [number_of_events]""Earliest event: [earliest_event_name] ([year])""Latest event: [latest_event_name] ([year])""Time span: [years_between_earliest_and_latest] years"
- Với
"years": Hiển thị"=== EVENTS BY DECADE ===", tiếp theo là các sự kiện được nhóm theo thập kỷ, theo định dạng"[decade]s: [comma_separated_event_names]" - Hiển thị thông báo hoàn tất:
"Historical timeline processing completed"
Quy tắc định dạng: dòng Loaded: in giá trị time.Time nguyên dạng bằng %v, ví dụ Loaded: Moon Landing - 1969-07-20 20:17:00 +0000 UTC. Mọi ngày và giờ khác đều được tạo thủ công: tháng, ngày và giờ không có số 0 ở đầu, còn phút luôn có hai chữ số (%02d), vì vậy cùng sự kiện đó sẽ được in như Moon Landing: 1969-7-20 at 20:17 UTC, và phút 0 được in là 21:00. [unix_seconds] là giá trị của Unix(), giá trị này âm với những ngày trước năm 1970. Trong danh sách thập kỷ, các thập kỷ được sắp xếp từ sớm nhất đến muộn nhất, còn tên các sự kiện trong mỗi thập kỷ được nối bằng dấu phẩy, không có dấu cách và theo thứ tự đầu vào.
Dùng gói time để tạo các ngày cụ thể bằng time.Date, gói strings để tách chuỗi đầu vào, gói strconv để chuyển chuỗi số thành số nguyên và gói fmt để định dạng đầu ra. Hãy nhớ rằng time.Date nhận các tham số theo đúng thứ tự: năm, tháng, ngày, giờ, phút, giây, nano giây, múi giờ. Để sắp xếp theo trình tự thời gian, bạn có thể so sánh các đối tượng time.Time bằng phương thức Before(). Thử thách này minh họa cách tạo những thời điểm cụ thể và làm việc với dữ liệu lịch sử bằng các chức năng thời gian của Go.
Tự làm thử
package main
import (
"bufio"
"fmt"
"os"
"strconv"
"strings"
"time"
)
func main() {
// Đọc đầu vào (input) bằng bufio.Scanner để xử lý đúng khoảng trắng
scanner := bufio.NewScanner(os.Stdin)
scanner.Scan()
eventsInput := scanner.Text()
scanner.Scan()
optionsInput := scanner.Text()
// Phân tích các sự kiện (event) từ đầu vào
eventEntries := strings.Split(eventsInput, ",")
// Phân tích các tùy chọn hiển thị từ đầu vào
displayOptions := strings.Split(optionsInput, ",")
// TODO: Viết code của bạn bên dưới
// 1. Phân tích từng mục sự kiện để lấy tên, năm, tháng, ngày, giờ, phút
// 2. Nhớ kiểm tra lát cắt parts có đủ phần tử (element) trước khi truy cập
// 3. Dùng strconv.Atoi() để chuyển các chuỗi (string) số thành số nguyên (integer)
// 4. Dùng time.Date() để tạo đối tượng (object) time.Time cho từng sự kiện
// 5. Hiển thị tiêu đề ứng dụng và các thông báo đang tải
// 6. Xử lý từng tùy chọn hiển thị (theo thứ tự thời gian, chi tiết, tóm tắt, các năm)
// 7. Hiển thị thông báo hoàn tất
}Bài học này có một bài trắc nghiệm ngắn. Bắt đầu bài học để trả lời và theo dõi tiến độ.
Tất cả bài học trong Logic và luồng điều khiển
1Luồng điều khiển nâng cao
Switch với `fallthrough`Thoát khỏi vòng lặp lồng nhauTiếp tục một vòng lặp cụ thểCâu lệnh `goto`Ôn tập: điều khiển vòng lặp nâng cao4Dự án: Danh sách việc cần làm đơn giản
Thiết lập dự ánThêm một việc cần làm7Xử lý lỗi chuyên sâu
Kiểu lỗi tùy chỉnhBọc lỗi bằng `%w`Gỡ bọc lỗi bằng `errors.Is`Gỡ bọc lỗi bằng `errors.As`Tìm hiểu `panic`Sử dụng `recover`Ôn tập: phép chia an toàn10Làm việc với thời gian
Lấy thời gian hiện tạiTạo thời điểm cụ thểĐịnh dạng thời gianPhân tích chuỗi thời gianKhoảng thời gianPhép tính thời gianTạm dừng và bộ đánh dấu thời gianÔn tập: Bộ hẹn giờ đơn giản2Struct và phương thức
Định nghĩa phương thức cho structReceiver giá trịReceiver con trỏChọn receiverPhương thức và hàmÔn tập: hành vi của struct5Tìm hiểu chuyên sâu về map
Map chứa structCon trỏ làm giá trị của mapKiểm tra map nilSo sánh các mapÔn tập: bộ đếm tần suất từ8Dự án: Quản lý hàng tồn kho đơn giản
Tổng quan dự ánKiểm tra hàng tồn kho3Interface (cơ bản)
Interface là gì?Định nghĩa interfaceTriển khai interfaceDùng kiểu interfaceInterface rỗngKhẳng định kiểuType switchÔn tập: hình dạng và hành viTự luyện tập: Trình biên dịch Go online