99 lines
3.4 KiB
Go
99 lines
3.4 KiB
Go
package main
|
|
|
|
import (
|
|
"fmt"
|
|
// "math" // This import is no longer needed
|
|
"time"
|
|
)
|
|
|
|
// baseTime is the reference point for Stardate 0.0, which we'll
|
|
// set as January 1, 2000, 00:00:00 UTC.
|
|
var baseTime = time.Date(2000, 1, 1, 0, 0, 0, 0, time.UTC)
|
|
|
|
// secondsPerStardateYear defines the length of a standard year in seconds,
|
|
// accounting for leap years (365.25 days).
|
|
// The TNG-era logic is that 1000 Stardate units = 1 year.
|
|
const secondsPerStardateYear = 365.25 * 24 * 60 * 60
|
|
|
|
/*
|
|
CalculateStardate converts a standard time.Time object into its
|
|
corresponding Star Trek Stardate.
|
|
|
|
The formula is based on a modern, fan-based convention where:
|
|
- Stardate 0.0 = 2000-01-01 00:00:00 UTC
|
|
- 1000 Stardate units = 1 standard year (365.25 days)
|
|
*/
|
|
func CalculateStardate(t time.Time) float64 {
|
|
// 1. Convert the input time to UTC for a consistent baseline.
|
|
tUTC := t.UTC()
|
|
|
|
// 2. Find the duration (in seconds) between the input time and the base time.
|
|
duration := tUTC.Sub(baseTime)
|
|
totalSeconds := duration.Seconds()
|
|
|
|
// 3. Calculate how many "Stardate Years" (1000 units) have passed.
|
|
// We divide the total elapsed seconds by the number of seconds in one
|
|
// standard (365.25 day) year.
|
|
stardateYears := totalSeconds / secondsPerStardateYear
|
|
|
|
// 4. Multiply by 1000 to get the final Stardate value.
|
|
stardate := stardateYears * 1000
|
|
|
|
// For fun, we are returning the full precision float
|
|
// instead of rounding to one decimal place.
|
|
// This will show changes down to the second.
|
|
return stardate
|
|
}
|
|
|
|
func main() {
|
|
// Let's test with the current time you provided:
|
|
// Monday, November 10, 2025 at 10:02 AM CET
|
|
|
|
// 1. Get the local time zone for "CET" (Hamburg)
|
|
// Note: "CET" is Central European Time (UTC+1)
|
|
loc, err := time.LoadLocation("Europe/Berlin") // "Europe/Berlin" is a good proxy for Hamburg/CET
|
|
if err != nil {
|
|
fmt.Println("Error loading location:", err)
|
|
return
|
|
}
|
|
|
|
// 2. Define the time.
|
|
// time.Date(year, month, day, hour, min, sec, nsec, location)
|
|
currentTime := time.Date(2025, 11, 10, 10, 2, 0, 0, loc)
|
|
|
|
// 3. Calculate the Stardate.
|
|
stardate := CalculateStardate(currentTime)
|
|
|
|
fmt.Printf("Input Time: %s\n", currentTime.Format(time.RFC1123Z))
|
|
fmt.Printf("Calculated Stardate: %.5f\n", stardate)
|
|
|
|
// Let's also try with a known TNG-era date (for fun, though the base is different)
|
|
// "Encounter at Farpoint" aired Oct 1987, set in 2364.
|
|
// Stardate 41153.7 is cited for that year.
|
|
// Let's check our 2000-based calculator for a date in 2041.
|
|
|
|
futureTime := time.Date(2041, 2, 28, 12, 0, 0, 0, time.UTC)
|
|
futureStardate := CalculateStardate(futureTime)
|
|
fmt.Printf("\n--- Bonus Calculation ---\n")
|
|
fmt.Printf("Input Time: %s\n", futureTime.Format(time.RFC1123Z))
|
|
fmt.Printf("Calculated Stardate: %.5f\n", futureStardate)
|
|
fmt.Println("(Note: 41153.7 would be our equivalent of Feb 28, 2041!)")
|
|
|
|
// --- Add the new ticking timer ---
|
|
fmt.Println("\n--- Engaging Stardate Chronometer ---")
|
|
fmt.Println("--- Press CTRL+C to stop ---")
|
|
|
|
// Use time.NewTicker for a more accurate 1-second interval
|
|
ticker := time.NewTicker(1 * time.Second)
|
|
|
|
// Use a 'for range' on the ticker's channel. This is a clean
|
|
// way to loop every second.
|
|
for t := range ticker.C {
|
|
// t is the current time provided by the ticker (which is what we want)
|
|
stardate := CalculateStardate(t)
|
|
|
|
// Print the current time and the stardate on a new line each second.
|
|
fmt.Printf("Current Time: %s | Stardate: %.5f\n", t.Format(time.RFC1123), stardate)
|
|
}
|
|
}
|