DynamoDB调度元组和取消调度元组的时间。

The sdk by default marshals time.Time values as RFC3339 strings. How can you choose to marshal and unmarshal in other ways e.g. millis since epoch?

The SDK mentions the Marshaler and Unmarshaler interfaces but does not explain how to use them.

(As I was about to post my question I figured out the answer by looking into how UnixTime worked).

To use a custom Marshaler and Unmarshaler you can create a custom type.

type MillisTime time.Time

func (e MillisTime) MarshalDynamoDBAttributeValue(av *dynamodb.AttributeValue) error {
    millis := timeAsMillis(time.Time(e))
    millisStr := fmt.Sprintf("%d", millis)
    av.N = &millisStr
    return nil
}

func (e *MillisTime) UnmarshalDynamoDBAttributeValue(av *dynamodb.AttributeValue) error {
    millis, err := strconv.ParseInt(*av.N, 10, 0)
    if err != nil {
        return err
    }
    *e = MillisTime(millisAsTime(millis))
    return nil
}

func timeAsMillis(t time.Time) int64 {
    nanosSinceEpoch := t.UnixNano()
    return (nanosSinceEpoch / 1_000_000_000) + (nanosSinceEpoch % 1_000_000_000)
}

func millisAsTime(millis int64) time.Time {
    seconds := millis / 1_000
    nanos := (millis % 1_000) * 1_000_000
    return time.Unix(seconds, nanos)
}

NOTE: Example above uses the new number literal syntax introduced in go 1.13.

You can easily marshal and unmarshal structs using MarshalMap and UnmarshalMap but the downside is that the fields in your struct type have to use MillisTime instead of time.Time. Conversion is not easy but is possible.

The SDK defines a UnixTime type which will handle marshaling and unmarshaling between time.Time <=> seconds since epoch.