Himalay Majumdar
Himalay Majumdar

Reputation: 3973

Java Date Time discrepancy

While writing integration test I was expecting a hardcoded date in the response.

Basically I hardcoded expected date value '2020-11-10T00:00:00.000-05:00' and ran new GregorianCalendar(2020, 10, 10).getTime()

When I put and assert and run it locally it passes, however when the same code was pushed to bamboo build server the actualValue it generated was'2020-11-10T00:00:00.000Z' and so my test failed.

  1. Why the same calendar.getTime generating two different times, is it because the server machine is configured to be on GMT?

  2. Can I do something to have them the same time or any other workaround?

NOTE: Making it string or comparing dates without time is not an option here, as I am using Spring MockWebServiceServer, where in I must hardcode the responseXML and specify date, something like this in Enum.

 REQUESTAUTOMATESETTLEMENTWORKCASE("<aut:AutomateSettlementWorkcaseRequest xmlns:aut=\"http://www.abcd.com/abcd/workflow/services/workcase/model/AutomateSettlementWorkcase_1_0_0\">" +
          "  <aut:customerAccountId>5049903033584324</aut:customerAccountId>\n" +
          "  <aut:settlementDate>2020-11-10T00:00:00.000-05:00</aut:settlementDate>\n" +
          "  </aut:AutomateSettlementWorkcaseRequest>"),

Upvotes: 2

Views: 280

Answers (2)

Basil Bourque
Basil Bourque

Reputation: 338795

Avoid legacy date-time classes

You are using terribly-flawed date-time classes that are now legacy. They were supplanted by the modern java.time classes defined in JSR 310.

Do not waste time struggling to understand the behaviors of those legacy classes. They are just that bad.

java.time

Your input string 2020-11-10T00:00:00.000-05:00 complies with the ISO 8601 standard for date-time formats.

Parse that string as an OffsetDateTime object. This class represents a date with time-of-day as seen from a particular offset. An offset is merely a number of hours-minutes-seconds ahead/behind the temporal meridian of UTC. (A time zone is a named history of the past, present, and future changes to the offset used by the people of a particular region as determined by their politicians.)

 OffsetDateTime odt = OffsetDateTime.parse( "2020-11-10T00:00:00.000-05:00" ) ;

You can ask for the count of milliseconds from the epoch reference of 1970-01-01T00:00Z (Z means offset-from-UTC of zero).

long millis = odt.toInstant().toEpochMilli() ;

Going the other direction.

Instant instant = Instant.ofEpochMilli( millis ) ;
ZoneOffset offset = ZoneOffset.ofHours ( -5 ) ;
OffsetDateTime odt = instant.atOffset( offset ) ;

Upvotes: 1

Jon Skeet
Jon Skeet

Reputation: 1500903

The "-5" part in your input data is throwing it off... ideally you should specify the time zone when constructing the calendar, and then set it to 5am UTC (for example). Basically, 2020-11-10T00:00:00.000-05:00 is the same instant as 2020-11-10T05:00:00.000Z.

Now, what we don't know is whether it's important to you that you preserve the offset from UTC. If it is, you need to set an appropriate time zone in the calendar - one which has the same rules as whatever's generating your input data. If it isn't, I'd use UTC and set the time appropriately.

I would personally recommend using Joda Time instead of Calendar and Date though - it's a much better date and time API. No 0-based months, for starters :)

Upvotes: 3

Related Questions