创建指定时间
本课属于 Coddy GO 学习旅程的“逻辑与流程”单元。第 59 课,共 68 课。
虽然 time.Now() 可以获取当前时刻,但你通常还需要处理特定的日期和时间。Go 提供了 time.Date 函数,用于创建表示你指定的任意日期和时间的 time.Time 对象。
time.Date 函数按以下顺序接收 8 个参数:年、月、日、小时、分钟、秒、纳秒和位置。基本语法如下:
birthday := time.Date(1990, time.March, 15, 14, 30, 0, 0, time.UTC)注意,Go 使用 time.March 这样的常量表示月份,这比使用数字更易于阅读。你也可以根据喜好使用整数(1-12)。location 参数通常使用 time.UTC 表示 UTC 时间,或使用 time.Local 表示系统的本地时区。
这种方法让你可以完全控制任意特定时刻的创建,无论是生日、截止日期还是历史日期。得到的 time.Time 对象与通过 time.Now() 创建的对象完全相同,可以用于所有相同的时间操作。
挑战
简单创建一个历史事件时间线应用,使用 time.Date 表示历史上的特定日期和时间。这个挑战将测试你创建 time.Time 对象来表示精确历史时刻,并以有条理的格式显示它们的能力。
你会收到两个输入:
- 一个包含历史事件的字符串,格式为
"event1:year:month:day:hour:minute,event2:year:month:day:hour:minute"(例如"Moon Landing:1969:7:20:20:17,Berlin Wall Fall:1989:11:9:21:0") - 一个包含显示选项的字符串,选项之间以逗号分隔,格式为
"option1,option2,option3"(例如"chronological,details,summary")
你的任务是:
- 按逗号拆分第一个输入,获取各个事件条目
- 对每个事件条目按冒号拆分,提取事件名称、年份、月份、日期、小时和分钟
- 将数字字符串转换为整数,并为每个事件使用
time.Date创建一个time.Time对象(位置参数使用time.UTC,秒和纳秒设为 0) - 显示应用标题:
"=== HISTORICAL TIMELINE APPLICATION ===" - 显示事件加载确认信息:
"Loading historical events..." - 对每个事件,显示:
"Loaded: [event_name] - [complete_time_object]" - 按逗号拆分第二个输入,获取显示选项
- 处理每个显示选项:
- 对于
"chronological":显示"=== CHRONOLOGICAL ORDER ===",然后按日期排序显示事件(从最早到最晚),格式为"[event_name]: [year]-[month]-[day] at [hour]:[minute] UTC" - 对于
"details":显示"=== DETAILED INFORMATION ===",然后为每个事件显示以下各行(最后四行缩进两个空格):Event: [event_name] Date: [year]-[month]-[day] Time: [hour]:[minute] UTC Weekday: [weekday_name] Unix timestamp: [unix_seconds] - 对于
"summary":显示"=== TIMELINE SUMMARY ===",然后显示:"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"
- 对于
"years":显示"=== EVENTS BY DECADE ===",然后按年代分组显示事件,格式为"[decade]s: [comma_separated_event_names]" - 显示完成消息:
"Historical timeline processing completed"
格式规则:Loaded: 行使用 %v 原样打印 time.Time 值,例如 Loaded: Moon Landing - 1969-07-20 20:17:00 +0000 UTC。其他日期和时间都需要手动构建:月份、日期和小时不带前导零,分钟始终显示两位数字(%02d),因此同一个事件会显示为 Moon Landing: 1969-7-20 at 20:17 UTC,分钟为 0 时则显示为 21:00。[unix_seconds] 是 Unix(),对于 1970 年之前的日期,它是负数。在年代列表中,年代按从早到晚的顺序排列,每个年代中的名称按输入顺序排列,并用逗号连接,逗号后不加空格。
使用 time 包通过 time.Date 创建特定日期,使用 strings 包拆分输入字符串,使用 strconv 包将数字字符串转换为整数,并使用 fmt 包进行格式化输出。请记住,time.Date 的参数顺序固定为:年份、月份、日期、小时、分钟、秒、纳秒、位置。要按时间顺序排序,你可以使用 Before() 方法比较 time.Time 对象。这个挑战展示了如何使用 Go 的时间功能创建特定时刻并处理历史数据。
亲手试试
package main
import (
"bufio"
"fmt"
"os"
"strconv"
"strings"
"time"
)
func main() {
// 使用 bufio.Scanner 读取输入,正确处理空格
scanner := bufio.NewScanner(os.Stdin)
scanner.Scan()
eventsInput := scanner.Text()
scanner.Scan()
optionsInput := scanner.Text()
// 从输入中解析事件
eventEntries := strings.Split(eventsInput, ",")
// 从输入中解析显示选项
displayOptions := strings.Split(optionsInput, ",")
// TODO:在下方编写你的代码
// 1. 解析每条事件记录,提取名称、年、月、日、小时和分钟
// 2. 访问 parts 切片前,记得检查元素是否足够
// 3. 使用 strconv.Atoi() 将数字字符串转换为整数
// 4. 使用 time.Date() 为每个事件创建 time.Time 对象
// 5. 显示应用标题和加载消息
// 6. 处理每个显示选项(chronological、details、summary、years)
// 7. 显示完成消息
}这节课包含一个小测验。开始学习即可作答,并记录你的进度。
逻辑与流程中的所有课
自己练习: Go 在线编译器