upd: essential/file updated
helper datetime updated
This commit is contained in:
parent
ebc7dc3800
commit
9611622ab3
@ -0,0 +1,344 @@
|
|||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| 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)
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user