1

Simply I have the following class to get my JSON body that received from remote response to deserialize to CreditCardDTO the date recieved inside exp_date like "0820" for 8/2010, and "0240" for 2/2040:

import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonProperty;

import java.util.Date;

@JsonInclude(JsonInclude.Include.NON_EMPTY)
@JsonPropertyOrder(alphabetic = true)
public class CreditCardDTO {
    private String brand;
    private Date expirationDate;

    @JsonProperty("brand")
    public String getBrand() {
        return brand;
    }

    @JsonProperty("credit_card_type")
    public CreditCardDTO setBrand(String brand) {
        this.brand = brand;
        return this;
    }

    @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss.SSSZ")
    @JsonProperty("expirationDate")
    public Date getExpirationDate() {
        return expirationDate;
    }

    @JsonFormat(pattern = "MMyy")
    @JsonProperty("exp_date")
    public CreditCardDTO setExpirationDate(Date expirationDate) {
        System.out.println(expirationDate);
        this.expirationDate = expirationDate;
        return this;
    }
}

The problem that if it is before Year 2038 everything is OK, but once the data is after that critical date, it still happens, the data is back to 1941, I searched about the problem and found that it should not be happen in Java 8 : Why should a Java programmer care about year 2038 bug? , so I'm wondering what the issue here!

Jackson version 2.8.0, Java 8 for sure.

4

1 回答 1

4

While I don't know about Jackson, i can tell you that you've taken a poor approach to handling this credit card expiration data.

Firstly you chose to roll-your-own rather than look to existing classes and standards. Always search for prior work; roll-your-own approach should be a last resort, not first. Less wild-cowboy, more judge-guided-by-precedent.

Secondly, you are using troublesome old date-time classes that are legacy, now supplanted by the java.time classes.

YearMonth

To represent a year and a month, use the YearMonth class built into Java. The months are numbered sanely, 1-12 for January-December, unlike the legacy classes.

YearMonth ym = YearMonth.of( 2040 , 3 ) ; 

By the way, you may find the Month enum handy in your work.

YearMonth ym = YearMonth.of( 2040 , Month.MARCH ) ; 

Use this YearMonth class as your member rather than a specific date.

When comparing to a date such as today, get the YearMonth for that date.

ZoneId z = ZoneId.of( "Asia/Amman" ) ;
LocalDate today = LocalDate.now( z ) ;
YearMonth ymToday = YearMonth.from( today ) ;

Boolean isExpired = ymToday.isAfter( ym ) ;

ISO 8601

The ISO 8601 standard defines many practical sensible formats for representing date-time values as text.

The standard format for year-month is YYYY-MM. So March 2040 is 2040-03.

The java.time classes use the standard formats by default when parsing or generating strings.

Generate a string.

ym.toString()  

2040-03

Parse a string.

YearMonth ym = YearMonth.parse( "2040-03" );

Always use 4-digit years

For both storage and presentation, always use four digits for years. The endless confusion, errors, and ambiguity is not worth saving two octets of memory/storage or half a centimeter of space on paper.

于 2017-07-03T15:37:49.017 回答