Menu
CoddyTech

创建指定时间

本课属于 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() 创建的对象完全相同,可以用于所有相同的时间操作。

challenge icon

挑战

简单

创建一个历史事件时间线应用,使用 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")

你的任务是:

  1. 按逗号拆分第一个输入,获取各个事件条目
  2. 对每个事件条目按冒号拆分,提取事件名称、年份、月份、日期、小时和分钟
  3. 将数字字符串转换为整数,并为每个事件使用 time.Date 创建一个 time.Time 对象(位置参数使用 time.UTC,秒和纳秒设为 0)
  4. 显示应用标题:"=== HISTORICAL TIMELINE APPLICATION ==="
  5. 显示事件加载确认信息:"Loading historical events..."
  6. 对每个事件,显示:"Loaded: [event_name] - [complete_time_object]"
  7. 按逗号拆分第二个输入,获取显示选项
  8. 处理每个显示选项:
    • 对于 "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]"
  9. 显示完成消息:"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. 显示完成消息
	
}
quiz icon自我测试

这节课包含一个小测验。开始学习即可作答,并记录你的进度。

逻辑与流程中的所有课

自己练习: Go 在线编译器