Best approach to handle Java8 date and time in DynamoDB
Asked Answered
P

2

8

I investigated the DynamoDB options for storing the date and time using the Java SDK. As far as I can see, custom converters are needed for the Java8 LocalDate and LocalDateTime, while for the old Date, Calendar and the Joda time LocalDateTime there are some annotations.

According to the documentation, @DynamoDBTypeConvertedTimestamp supports the standard Date type-conversions such as java.util.Calendar, Long. @DynamoDBTypeConvertedEpochDate can be used to convert the Date, Calendar and org.joda.time.DateTime to numerical values.

At the same time, if I don't put any annotation on a Date field, it is saved just like it would have @DynamoDBTypeConvertedTimestamp on it, and even range queries work successfully.

Does anybody have the knowledge to explain the different possible approaches, and to give an opinion on the best approach to store and retrieve Java date and time objects from DynamoDB?

Pimply answered 10/11, 2017 at 8:28 Comment(0)
E
10

TLDR; It depends on how the date, time, etc are going to be used.

Long Answer

It's going to depend on your use case so there's no hard and fast "best" approach. However, there are a few considerations to keep in mind.

How is the value being used in your table schema?

If the Java 8 date/time is going to be used as a sort key, consider using a custom converter that converts it to a string. If you do this, then you can use the begins_with operator in the key condition expression of a query, such as begins_with(myDate, "2018-12"). Being able to query like this will make your code a lot simpler if you want to search for everything in a specific year, month, day, hour, etc.

If you are using the value as a DynamoDB TTL attribute, then it must be converted to a numeric timestamp. That is a requirement to use the TTL feature.

Which one of the java.time classes are we talking about?

Some of the classes in the java.time package don't have as natural of a conversion to a number. For example, LocalDate would be unwieldy, at best, to convert to a number. The LocalDate 2018-12-10 would make most sense being converted to 20181210, but at that point, you're having to write enough code that you may as well just use the built in LocalDate.toString() and LocalDate.parse().

How often do you have to look at the database to track down a bug or fix bad data?

If you're messing around in the database frequently (hopefully that's not the case), use something that's human readable. Nobody wants to have to figure out if 2018-12-05T17:23:19.483+08:30 is before or after 1544572463 when they get paged in the middle of the night.

How sensitive is your application to increased latency?

I have not observed any measurable performance difference from DynamoDB related to storing dates as Strings vs Numbers. However, string parsing is slower that using a number to create a java.time object, so there may be a slight impact in your application if you store the dates as Strings.

Don't let custom converters scare you away

They're really easy to write for the java.time api. Here's how you would implement a converter for LocalDateTime that converts to a String.

public class LocalDateTimeToStringTypeConverter implements DynamoDBTypeConverter<String, LocalDateTime> {

    @Override
    public String convert(LocalDateTime localDateTime) {
        return localDateTime.toString();
    }

    @Override
    public LocalDateTime unconvert(String s) {
        return LocalDateTime.parse(s);
    }
}
Extine answered 12/12, 2018 at 0:6 Comment(3)
Not knowing DynamoDB and curious: Hasn’t it got date, datetime, time and timestamp with timezone datatypes like standard SQL databases have? In case it hasn’t: LocalDate can be easily converted to and from a number, namely the epoch day. I still agree with you to prefer the text representation like 2018-12-12, though.Boschbok
@OleV.V. DynamoDB is more of a key-value or document-oriented database. It provides a few basic data types so that you can construct your own rich data model, and it makes no assumptions about the meaning of your data. You can see the supported data types here: docs.aws.amazon.com/amazondynamodb/latest/developerguide/…Extine
@OleV.V. Some of the SDKs provide conversions for other data types. For example, the Java SDK also supports Date and Calendar which it converts to millisecond-precision ISO-8601 strings. docs.aws.amazon.com/amazondynamodb/latest/developerguide/…Extine
S
1

Try annotating Date fields with @DynamoDBTyped, This is a Annotation to override the standard attribute type binding in dynamoDB. So it will covert date to Attribute Type = S ,which is String in DynamoDM. Hope it will help

@DynamoDBTyped(DynamoDBAttributeType.S)
private LocalDate startDate;
Submerged answered 26/9, 2019 at 11:53 Comment(1)
Thanks, saved me from going the converter routeBingaman

© 2022 - 2024 — McMap. All rights reserved.