refactor: represent time fields as int64 Unix seconds throughout the stack
Collapses a four-step conversion chain (time_t → int64 → time.Time → RFC3339 string → string → time.Time) to a direct int64 pass-through: C time_t → rawJobData int64 → JobInfo int64 → JSON integer → QueryJob int64 → time.Unix() for display Changes: - apiserver/models/jobs.go: SubmitTime, QueueTime, StartTime, EndTime, ReserveTime in JobInfo and JobAdditionalFields: time.Time → int64 - apiserver/models/common.go: ActionControl.SubmitTime: time.Time → int64 - backend/convert_pure.go: remove time.Unix() calls; assign int64 directly - backend/convert_test.go: update time assertions to compare int64 values - xcecli/models/jobs.go: SubmitTime, StartTime, EndTime, ReserveTime in QueryJob: string/time.Time → int64; remove time import - xcecli/common/output/time.go: replace parseJobTime(string) with unixToTime(int64) and fmtUnixTime(int64) helpers - xcecli/common/output/page_print_jobs.go: replace parseJobTime() calls with unixToTime()/fmtUnixTime(); remove !startTime.IsZero() guard (unixToTime returns false for ts<=0, making it redundant) - xcecli/common/output/page_print_array_elements_jobs.go: replace string-split+time.Parse submit-time block with fmtUnixTime(); remove unused time import Side effect: eliminates the "0001-01-01T00:00:00Z" zero-time serialization issue at the source — zero timestamps are now 0 (integer) and unixToTime/fmtUnixTime return false/"-" for ts<=0 without special- casing needed in callers.
This commit is contained in:
parent
14de6c4fa6
commit
ce2edf0dac
8 changed files with 55 additions and 82 deletions
|
|
@ -4,7 +4,6 @@ import (
|
|||
"encoding/json"
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
jobfmt "xcecli/common/format"
|
||||
"xcecli/models"
|
||||
)
|
||||
|
|
@ -96,7 +95,7 @@ func (p *ArrayElementsPagePrinter) initColumnWidths(jobs *models.JobsResponse) {
|
|||
case models.HEADER_JOB_NAME:
|
||||
width = len(job.JobName)
|
||||
case models.HEADER_JOB_SUBMIT_TIME:
|
||||
width = len(job.SubmitTime)
|
||||
width = len(fmtUnixTime(job.SubmitTime))
|
||||
}
|
||||
|
||||
if !p.wideFormat && width > 15 {
|
||||
|
|
@ -190,21 +189,7 @@ func (p *ArrayElementsPagePrinter) formatRows(jobs *models.JobsResponse, truncat
|
|||
case models.HEADER_JOB_NAME:
|
||||
mainRow = appendOrDefault(mainRow, FormatStringField(job.JobName, width, truncatFlag, true), "-")
|
||||
case models.HEADER_JOB_SUBMIT_TIME:
|
||||
// remove the timezone part and parse the time
|
||||
timeStr := strings.Split(job.SubmitTime, " ")[0:2]
|
||||
timeStrWithoutTZ := strings.Join(timeStr, " ")
|
||||
|
||||
if submitTime, err := time.Parse("2006-01-02 15:04:05", timeStrWithoutTZ); err == nil {
|
||||
month := submitTime.Format("Jan")
|
||||
displayTime := fmt.Sprintf("%s %02d %02d:%02d",
|
||||
month,
|
||||
submitTime.Day(),
|
||||
submitTime.Hour(),
|
||||
submitTime.Minute())
|
||||
mainRow = appendOrDefault(mainRow, FormatStringField(displayTime, width, truncatFlag, true), "-")
|
||||
} else {
|
||||
mainRow = appendOrDefault(mainRow, fmt.Sprintf("%"+align+"*s", width, "-"), "-")
|
||||
}
|
||||
mainRow = appendOrDefault(mainRow, FormatStringField(fmtUnixTime(job.SubmitTime), width, truncatFlag, true), "-")
|
||||
}
|
||||
}
|
||||
rows = append(rows, mainRow)
|
||||
|
|
|
|||
|
|
@ -98,7 +98,7 @@ func (p *JobsPagePrinter) initColumnWidths(jobs *models.JobsResponse) {
|
|||
case models.HEADER_JOB_NAME:
|
||||
width = len(job.JobName)
|
||||
case models.HEADER_JOB_SUBMIT_TIME:
|
||||
width = len(job.SubmitTime)
|
||||
width = len(fmtUnixTime(job.SubmitTime))
|
||||
case models.HEADER_JOB_CORE_LIMIT:
|
||||
width = len(fmt.Sprintf("%f", job.CoreLimit))
|
||||
case models.HEADER_JOB_MEM_LIMIT:
|
||||
|
|
@ -201,11 +201,7 @@ func (p *JobsPagePrinter) formatRows(jobs *models.JobsResponse, truncatFlag bool
|
|||
mainRow = appendOrDefault(mainRow, fmt.Sprintf("%"+align+"*s", width, "-"), "-")
|
||||
}
|
||||
case models.HEADER_JOB_SUBMIT_TIME:
|
||||
if submitTime, err := parseJobTime(job.SubmitTime); err == nil {
|
||||
mainRow = appendOrDefault(mainRow, FormatStringField(formatJobTime(submitTime), width, truncatFlag, true), "-")
|
||||
} else {
|
||||
mainRow = appendOrDefault(mainRow, fmt.Sprintf("%"+align+"*s", width, "-"), "-")
|
||||
}
|
||||
mainRow = appendOrDefault(mainRow, FormatStringField(fmtUnixTime(job.SubmitTime), width, truncatFlag, true), "-")
|
||||
|
||||
// normal fields
|
||||
case models.HEADER_JOB_NAME:
|
||||
|
|
@ -223,9 +219,9 @@ func (p *JobsPagePrinter) formatRows(jobs *models.JobsResponse, truncatFlag bool
|
|||
case models.HEADER_JOB_PROJECT_NAME:
|
||||
mainRow = appendOrDefault(mainRow, FormatStringField(job.ProjectName, width, truncatFlag, true), "-")
|
||||
case models.HEADER_JOB_START_TIME:
|
||||
mainRow = appendOrDefault(mainRow, FormatStringField(job.StartTime, width, truncatFlag, true), "-")
|
||||
mainRow = appendOrDefault(mainRow, FormatStringField(fmtUnixTime(job.StartTime), width, truncatFlag, true), "-")
|
||||
case models.HEADER_JOB_END_TIME:
|
||||
mainRow = appendOrDefault(mainRow, FormatStringField(job.EndTime, width, truncatFlag, true), "-")
|
||||
mainRow = appendOrDefault(mainRow, FormatStringField(fmtUnixTime(job.EndTime), width, truncatFlag, true), "-")
|
||||
case models.HEADER_JOB_CWD:
|
||||
mainRow = appendOrDefault(mainRow, FormatStringField(job.CWD, width, truncatFlag, true), "-")
|
||||
case models.HEADER_JOB_LAUNCH_TYPE:
|
||||
|
|
@ -303,7 +299,7 @@ func printJobsVerboseOutput(jobs *models.JobsResponse, filter []string) {
|
|||
|
||||
// (2) print the submit time info
|
||||
submitLine := ""
|
||||
if submitTime, err := parseJobTime(job.SubmitTime); err == nil {
|
||||
if submitTime, ok := unixToTime(job.SubmitTime); ok {
|
||||
submitLine = submitLine + fmt.Sprintf("%s %s %02d:%02d:%02d: ",
|
||||
submitTime.Format("Jan"), submitTime.Format("02"),
|
||||
submitTime.Hour(), submitTime.Minute(), submitTime.Second())
|
||||
|
|
@ -335,7 +331,7 @@ func printJobsVerboseOutput(jobs *models.JobsResponse, filter []string) {
|
|||
if job.JobStatus == "PEND" || job.JobStatus == "PSUSP" {
|
||||
goto printEndLine
|
||||
}
|
||||
if startTime, err := parseJobTime(job.StartTime); err == nil && !startTime.IsZero() {
|
||||
if startTime, ok := unixToTime(job.StartTime); ok {
|
||||
month := startTime.Format("Jan")
|
||||
day := startTime.Format("02")
|
||||
exec_hostname := ""
|
||||
|
|
@ -395,7 +391,7 @@ func printJobsVerboseOutput(jobs *models.JobsResponse, filter []string) {
|
|||
// (4) print end line
|
||||
endLine := ""
|
||||
if job.JobStatus == "DONE" || job.JobStatus == "EXIT" {
|
||||
if endTime, err := parseJobTime(job.EndTime); err == nil {
|
||||
if endTime, ok := unixToTime(job.EndTime); ok {
|
||||
endLine = endLine + fmt.Sprintf("%s %s %02d:%02d:%02d: ",
|
||||
endTime.Format("Jan"), endTime.Format("02"),
|
||||
endTime.Hour(), endTime.Minute(), endTime.Second())
|
||||
|
|
|
|||
|
|
@ -5,17 +5,23 @@ import (
|
|||
"time"
|
||||
)
|
||||
|
||||
// parseJobTime parses a job time string supporting RFC3339 and space-separated formats.
|
||||
func parseJobTime(s string) (time.Time, error) {
|
||||
if s == "" {
|
||||
return time.Time{}, fmt.Errorf("empty time string")
|
||||
// unixToTime converts a Unix-second timestamp to time.Time.
|
||||
// Returns (time, true) for ts > 0; (zero, false) for unset/zero values.
|
||||
func unixToTime(ts int64) (time.Time, bool) {
|
||||
if ts <= 0 {
|
||||
return time.Time{}, false
|
||||
}
|
||||
for _, f := range []string{time.RFC3339Nano, time.RFC3339, "2006-01-02 15:04:05", "2006-01-02 15:04:05 MST"} {
|
||||
if t, err := time.Parse(f, s); err == nil {
|
||||
return t, nil
|
||||
}
|
||||
return time.Unix(ts, 0), true
|
||||
}
|
||||
|
||||
// fmtUnixTime formats a Unix timestamp as "Jan 02 15:04" for table display.
|
||||
// Returns "-" for zero/unset values.
|
||||
func fmtUnixTime(ts int64) string {
|
||||
t, ok := unixToTime(ts)
|
||||
if !ok {
|
||||
return "-"
|
||||
}
|
||||
return time.Time{}, fmt.Errorf("cannot parse time: %q", s)
|
||||
return formatJobTime(t)
|
||||
}
|
||||
|
||||
// formatJobTime formats a time.Time as "Jan 02 15:04" for table display.
|
||||
|
|
|
|||
|
|
@ -3,8 +3,6 @@ package models
|
|||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
)
|
||||
|
||||
const (
|
||||
|
|
@ -115,10 +113,10 @@ type QueryJob struct {
|
|||
TermTime string `json:"term_time"`
|
||||
UserPriority int `json:"user_priority"`
|
||||
DependCond string `json:"depend_cond"`
|
||||
SubmitTime string `json:"submit_time"`
|
||||
ReserveTime time.Time `json:"reserve_time"`
|
||||
StartTime string `json:"start_time"`
|
||||
EndTime string `json:"end_time"`
|
||||
SubmitTime int64 `json:"submit_time"`
|
||||
ReserveTime int64 `json:"reserve_time"`
|
||||
StartTime int64 `json:"start_time"`
|
||||
EndTime int64 `json:"end_time"`
|
||||
JobRusage string `json:"job_rusage"`
|
||||
MaxMem float64 `json:"max_mem"`
|
||||
AvgMem float64 `json:"avg_mem"`
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue