Skip to content
go-libfossil Artifact [be8f9c6a93]
Login

Artifact [be8f9c6a93]

Artifact be8f9c6a938aaa56e9ccb7cb323042265a756a180bd103a0347b5ef485379b69:


package db

import "time"

// julianEpoch is the Julian Day Number for the Unix epoch (1970-01-01 12:00:00 UTC).
const julianEpoch = 2440587.5

// ScanJulianDay converts a scanned mtime value to a float64 Julian Day Number.
// SQLite drivers return mtime differently: modernc returns float64,
// ncruces returns time.Time for DATETIME/TIMESTAMP/DATE columns.
// Scan the column into an `any` variable, then pass it here.
func ScanJulianDay(v any) (float64, bool) {
	switch v := v.(type) {
	case float64:
		return v, true
	case time.Time:
		return timeToJulian(v), true
	case int64:
		return float64(v), true
	default:
		return 0, false
	}
}

// ScanTime converts a scanned mtime value to time.Time.
// Same driver-compatibility rationale as ScanJulianDay.
func ScanTime(v any) (time.Time, bool) {
	switch v := v.(type) {
	case time.Time:
		return v, true
	case float64:
		return julianToTime(v), true
	case int64:
		return julianToTime(float64(v)), true
	default:
		return time.Time{}, false
	}
}

// ScanInt converts a scanned value to int.
// SQLite drivers differ on BOOLEAN columns: modernc returns int64,
// ncruces returns bool. Scan the column into an `any` variable, then pass it here.
func ScanInt(v any) (int, bool) {
	switch v := v.(type) {
	case int64:
		return int(v), true
	case int:
		return v, true
	case bool:
		if v {
			return 1, true
		}
		return 0, true
	case float64:
		return int(v), true
	default:
		return 0, false
	}
}

func julianToTime(jd float64) time.Time {
	millis := int64((jd - julianEpoch) * 86400.0 * 1000.0)
	return time.UnixMilli(millis).UTC()
}

func timeToJulian(t time.Time) float64 {
	return julianEpoch + float64(t.UTC().UnixMilli())/(86400.0*1000.0)
}