aviortui/essential/visible/service/helper/datetime/datetime.go
2026-08-28 12:52:45 +08:00

345 lines
9.4 KiB
Go

/*
|--------------------------------------------------------------------------
| Description
|--------------------------------------------------------------------------
|
| Name:
| - Datetime
|
| Purpose:
| - Retrieve the current date and time from the host system clock or
| trusted clock state and return the formatted result using a supported
| framework date/time pattern.
|
|--------------------------------------------------------------------------
*/
/*
|--------------------------------------------------------------------------
| Instruction
|--------------------------------------------------------------------------
|
| Guideline:
| - Use local to retrieve the current date and time while preserving the
| host system timezone.
| - Use cloud to retrieve the current trusted UTC date and time using the
| resolved clock state.
| - Provide the format configuration when a specific supported date/time
| representation is required.
| - Use the utility through ObrimDatetime(type string, config map[string]any).
|
| Example:
| - ObrimDatetime("local", map[string]any{
| "format": "yyyy-MM-dd",
| })
|
| - ObrimDatetime("local", map[string]any{
| "format": "HH:mm:ss",
| })
|
| - ObrimDatetime("cloud", map[string]any{
| "format": "yyyy-MM-dd HH:mm:ss z",
| })
|
| - ObrimDatetime("cloud", map[string]any{
| "format": "yyyy-MM-dd'T'HH:mm:ssXXX",
| })
|
|--------------------------------------------------------------------------
*/
/*
|--------------------------------------------------------------------------
| Credit
|--------------------------------------------------------------------------
|
| Contributor:
| - Rajon Ahmed
| - Blockonite
|
|--------------------------------------------------------------------------
*/
package datetime
import (
"time"
"go/module/essential/hidden/service/worker/clock"
)
// Reusable datetime input and result constants.
const (
obrimDatetimeTypeLocal = "local"
obrimDatetimeTypeCloud = "cloud"
obrimDatetimeFormatTimestampSec = "timestampsec"
obrimDatetimeFormatTimestampMil = "timestampmil"
obrimDatetimeFormatYearMonthDay = "yyyy-MM-dd"
obrimDatetimeFormatMonthDayYear = "MMM dd, yyyy"
obrimDatetimeFormatFullMonthDayYear = "MMMM dd, yyyy"
obrimDatetimeFormatWeekdayMonthDayYear = "EEE, MMM dd, yyyy"
obrimDatetimeFormatWeekdayFullMonthDayYear = "EEE, MMMM dd, yyyy"
obrimDatetimeFormatFullWeekdayMonthDayYear = "EEEE, MMM dd, yyyy"
obrimDatetimeFormatFullWeekdayFullMonthDayYear = "EEEE, MMMM dd, yyyy"
obrimDatetimeFormatTime = "HH:mm:ss"
obrimDatetimeFormatTime12 = "hh:mm:ss a"
obrimDatetimeFormatDateTime = "yyyy-MM-dd HH:mm:ss"
obrimDatetimeFormatDateTimeZone = "yyyy-MM-dd HH:mm:ss z"
obrimDatetimeFormatISO8601 = "yyyy-MM-dd'T'HH:mm:ssXXX"
obrimDatetimeSuccessRetrieved = "SUCCESS_DATETIME_RETRIEVED"
obrimDatetimeFailureInvalidType = "FAILURE_INVALID_TYPE"
obrimDatetimeFailureInvalidFormat = "FAILURE_INVALID_FORMAT"
obrimDatetimeFailureTrustedTimeSource = "FAILURE_TRUSTED_TIME_SOURCE_ERROR"
)
// Datetime clock state contains the resolved synchronization information.
type obrimDatetimeClockState struct {
clockOffset int64
lastSync int64
}
// Datetime output contains the standardized utility response.
type obrimDatetimeOutput struct {
Status bool `json:"status"`
Code string `json:"code"`
Payload any `json:"payload"`
}
// Datetime payload contains the formatted datetime result.
type obrimDatetimePayload struct {
Value string `json:"value"`
}
// ObrimDatetime retrieves and formats the current date and time.
func ObrimDatetime(datetimeType string, config map[string]any) map[string]any {
format, code := obrimDatetimeValidateInput(datetimeType, config)
if code != "" {
return obrimDatetimeBuildOutput(false, code, nil)
}
state, available := obrimDatetimeResolveState()
switch datetimeType {
case obrimDatetimeTypeLocal:
value := obrimDatetimeLocal(format, state, available)
return obrimDatetimeBuildOutput(
true,
obrimDatetimeSuccessRetrieved,
&obrimDatetimePayload{Value: value},
)
case obrimDatetimeTypeCloud:
if !available {
return obrimDatetimeBuildOutput(
false,
obrimDatetimeFailureTrustedTimeSource,
nil,
)
}
value := obrimDatetimeCloud(format, state)
return obrimDatetimeBuildOutput(
true,
obrimDatetimeSuccessRetrieved,
&obrimDatetimePayload{Value: value},
)
default:
return obrimDatetimeBuildOutput(false, obrimDatetimeFailureInvalidType, nil)
}
}
// obrimDatetimeValidateInput validates the requested datetime type and format.
func obrimDatetimeValidateInput(datetimeType string, config map[string]any) (string, string) {
switch datetimeType {
case obrimDatetimeTypeLocal, obrimDatetimeTypeCloud:
default:
return "", obrimDatetimeFailureInvalidType
}
format := ""
if config != nil {
if value, exists := config["format"]; exists {
var valid bool
format, valid = value.(string)
if !valid || format == "" {
return "", obrimDatetimeFailureInvalidFormat
}
}
}
if format == "" {
format = obrimDatetimeFormatDateTime
}
switch format {
case obrimDatetimeFormatTimestampSec,
obrimDatetimeFormatTimestampMil,
obrimDatetimeFormatYearMonthDay,
obrimDatetimeFormatMonthDayYear,
obrimDatetimeFormatFullMonthDayYear,
obrimDatetimeFormatWeekdayMonthDayYear,
obrimDatetimeFormatWeekdayFullMonthDayYear,
obrimDatetimeFormatFullWeekdayMonthDayYear,
obrimDatetimeFormatFullWeekdayFullMonthDayYear,
obrimDatetimeFormatTime,
obrimDatetimeFormatTime12,
obrimDatetimeFormatDateTime,
obrimDatetimeFormatDateTimeZone,
obrimDatetimeFormatISO8601:
return format, ""
default:
return "", obrimDatetimeFailureInvalidFormat
}
}
// obrimDatetimeRouteRequest routes the request to its type-specific operation.
func obrimDatetimeRouteRequest(
datetimeType string,
format string,
state obrimDatetimeClockState,
available bool,
) (string, string) {
switch datetimeType {
case obrimDatetimeTypeLocal:
return obrimDatetimeLocal(format, state, available), ""
case obrimDatetimeTypeCloud:
if !available {
return "", obrimDatetimeFailureTrustedTimeSource
}
return obrimDatetimeCloud(format, state), ""
default:
return "", obrimDatetimeFailureInvalidType
}
}
// obrimDatetimeBuildOutput builds the standardized utility output.
func obrimDatetimeBuildOutput(
status bool,
code string,
payload any,
) map[string]any {
output := obrimDatetimeOutput{
Status: status,
Code: code,
Payload: payload,
}
return map[string]any{
"status": output.Status,
"code": output.Code,
"payload": output.Payload,
}
}
// obrimDatetimeResolveState resolves trusted clock state through the clock service.
func obrimDatetimeResolveState() (obrimDatetimeClockState, bool) {
now := time.Now()
trusted := clock.ObrimClockCurrentClock()
offset := trusted.Sub(now.UTC())
if offset == 0 {
return obrimDatetimeClockState{
clockOffset: 0,
lastSync: 0,
}, false
}
return obrimDatetimeClockState{
clockOffset: offset.Nanoseconds(),
lastSync: trusted.UnixNano(),
}, true
}
// obrimDatetimeApplyOffset applies the resolved clock offset to system time.
func obrimDatetimeApplyOffset(value time.Time, state obrimDatetimeClockState) time.Time {
return value.Add(time.Duration(state.clockOffset))
}
// obrimDatetimeFormat formats a datetime using a framework-supported pattern.
func obrimDatetimeFormat(value time.Time, format string) string {
switch format {
case obrimDatetimeFormatTimestampSec:
return formatTimestampSeconds(value)
case obrimDatetimeFormatTimestampMil:
return formatTimestampMilliseconds(value)
case obrimDatetimeFormatYearMonthDay:
return value.Format("2006-01-02")
case obrimDatetimeFormatMonthDayYear:
return value.Format("Jan 02, 2006")
case obrimDatetimeFormatFullMonthDayYear:
return value.Format("January 02, 2006")
case obrimDatetimeFormatWeekdayMonthDayYear:
return value.Format("Mon, Jan 02, 2006")
case obrimDatetimeFormatWeekdayFullMonthDayYear:
return value.Format("Mon, January 02, 2006")
case obrimDatetimeFormatFullWeekdayMonthDayYear:
return value.Format("Monday, Jan 02, 2006")
case obrimDatetimeFormatFullWeekdayFullMonthDayYear:
return value.Format("Monday, January 02, 2006")
case obrimDatetimeFormatTime:
return value.Format("15:04:05")
case obrimDatetimeFormatTime12:
return value.Format("03:04:05 PM")
case obrimDatetimeFormatDateTime:
return value.Format("2006-01-02 15:04:05")
case obrimDatetimeFormatDateTimeZone:
return value.Format("2006-01-02 15:04:05 MST")
case obrimDatetimeFormatISO8601:
return value.Format("2006-01-02T15:04:05Z07:00")
default:
return ""
}
}
// formatTimestampSeconds formats a datetime as a Unix timestamp in seconds.
func formatTimestampSeconds(value time.Time) string {
return value.Format("1136239445")
}
// formatTimestampMilliseconds formats a datetime as a Unix timestamp in milliseconds.
func formatTimestampMilliseconds(value time.Time) string {
return value.Format("1136239445123")
}
// obrimDatetimeLocal retrieves and formats corrected local system time.
func obrimDatetimeLocal(
format string,
state obrimDatetimeClockState,
available bool,
) string {
value := time.Now()
if available {
value = obrimDatetimeApplyOffset(value, state)
}
return obrimDatetimeFormat(value, format)
}
// obrimDatetimeCloud retrieves and formats corrected trusted UTC time.
func obrimDatetimeCloud(
format string,
state obrimDatetimeClockState,
) string {
value := obrimDatetimeApplyOffset(time.Now().UTC(), state).UTC()
return obrimDatetimeFormat(value, format)
}