Converting Dates from Excel Format to Standard in Go

When working with Excel files in Go, you often encounter dates represented as serial numbers. This is the internal format used by Excel to store dates: an integer that represents the number of days since January 1, 1900 (or 1904, depending on the version).

In this article, we’ll see how to convert these numbers into Go time.Time objects, so they can be easily used and formatted.

What is Excel's date format?

Excel represents dates as serial numbers. For example:

  • 1 corresponds to January 1, 1900
  • 44561 corresponds to July 10, 2021

However, there's an important quirk: Excel mistakenly treats 1900 as a leap year. So, February 29, 1900 is considered valid (even though it isn’t). This introduces a 1-day error for all dates after February 28, 1900.

Conversion in Go

Here’s a Go function to convert an Excel date (in float64 format) to a correct time.Time:


package main

import (
	"fmt"
	"time"
)

// ExcelEpoch is the starting point: January 1, 1900
var ExcelEpoch = time.Date(1899, 12, 30, 0, 0, 0, 0, time.UTC)

func excelDateToTime(serial float64) time.Time {
	return ExcelEpoch.AddDate(0, 0, int(serial))
}

func main() {
	excelSerial := 44561.0
	t := excelDateToTime(excelSerial)
	fmt.Println("Converted date:", t.Format("2006-01-02"))
}

Important Notes

  • The function correctly handles Excel dates based on the 1900 epoch (standard on Windows).
  • If you’re working with files generated on Mac, Excel may use the 1904 epoch. In that case, change the base to 1904-01-01.
  • Decimal values represent fractions of a day (e.g., 0.5 = noon). If needed, you can use time.Duration to handle them.

Conclusion

Converting dates from Excel to Go is simple once you understand Excel’s numbering system. With just a few lines of code, you can turn these numbers into readable and usable dates for your applications.

Back to top