Skip to content

ExpirationDate/DateField differences #136

Description

@m-r-78

This is a suggestion for improving/consolidating the handling of DateField and PassGeneratorRequest.ExpirationDate.

I am bringing this up as I ran into the following issue which took me a little while to figure out:

Suppose the created pass should have an expiration date that you also want to display on the pass.
Therefore you apply the same DateTime value (let's call it expDate) to both the PassGeneratorRequest.ExpirationDate (implicit conversion from DateTime to DateTimeOffset) and some DateField object.

This will work fine when the expDate has a DateTimeKind of Utc or Local but will result in different times when the expDate's DateTimeKind is Unspecified. The reason for this is as follows: when you assign an Unspecified DateTime to a DateTimeOffset the implicit conversion interprets the underlying value as Local (see Converting between DateTime and DateTimeOffset) whereas in the serialization code of DateField (WriteValue(...)) an Unspecified DateTime value is interpreted as UTC time.

Steps to reproduce:

Set up a new PassGeneratorRequest similar to the following:

PassGeneratorRequest req = new (); //properly initialize the request
expDate = new DateTime(2021, 4, 21, 14, 54, 21, DateTimeKind.Unspecified)
req.ExpirationDate = expDate;
req.AddPrimaryField(new DateField("key_validUntil", "Pass.Label.ValidUntil", FieldDateTimeStyle.PKDateStyleMedium, FieldDateTimeStyle.PKDateStyleMedium, expDate) {

Resulting pass.json:

{
  ...
  "expirationDate": "2021-04-21T14:54:21+02:00",
    ...
    "secondaryFields": [
      {
        "key": "key_validUntil",
        "label": "Pass.Label.ValidUntil",
        "dateStyle": "PKDateStyleMedium",
        "timeStyle": "PKDateStyleMedium",
        "value": "2021-04-21T14:54:21Z"
      }
    ],
  ...
}

The time difference between the actual expiration time of the wallet pass and the value that is displayed is 2 hours (CEST timezone).

I ran into this issue because we are providing a REST service to create passes and one of the consumers passed the expiration date in a format that was interpreted as DateTimeKind.Unspecified by the JSON framework.

SUGGESTION: The problem can be solved/mitigated in various ways when you are aware of this behaviour but I would suggest to improve the handling directly in the library. I am not sure behind the reasoning why DateTimeOffset is used for ExpirationDate (and also for the beacon's RelevantDate) whereas DateTime is used as the underlying data type for DateField. In my opinion this should be consolidated to use the same data type.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions