2
  val date = "01-10-1967"
  val pattern = "dd-MM-yyyy"
  val formatter = DateTimeFormat.forPattern(pattern)
  formatter.parseMillis(date) // this line fails

The last line fails with:

Cannot parse "01-10-1967": Illegal instant due to time zone offset transition (America/Argentina/Buenos_Aires)

Any idea why?

(JodaTime version is 2.3)

Pablo Fernandez
  • 103,170
  • 56
  • 192
  • 232

1 Answers1

3

The 1st of October 1967 was in Argentina a day where they changed from standard time to summer time, i.e. added 1 hour, on 00:00.

Since you are not providing a concrete time, I would assume that it defaults to exactly 00:00 which simply did not exist on that day.

Cf. the official faq:

What does 'Illegal instant due to time zone offset transition' mean? Joda-Time only allows the key classes to store valid date-times. For example, 31st February is not a valid date so it can't be stored (except in Partial). The same principle of valid date-times applies to daylight savings time (DST). In many places DST is used, where the local clock moves forward by an hour in spring and back by an hour in autumn/fall. This means that in spring, there is a "gap" where a local time does not exist. The error "Illegal instant due to time zone offset transition" refers to this gap. It means that your application tried to create a date-time inside the gap - a time that did not exist. Since Joda-Time objects must be valid, this is not allowed.

Possible solutions might be (taken from the faq):

  • Use LocalDateTime, as all local date-times are valid.
  • When converting a LocalDate to a DateTime, then use toDateTimeAsStartOfDay() as this handles and manages any gaps.
  • When parsing, use parseLocalDateTime() if the string being parsed has no time-zone.

Since you aren't interested in time information anyway, I think you might even want to replace formatter.parseMillis(date) with formatter.parseLocalDate(date). If for some reason you still need milliseconds, this Stack Overflow question might help.

Community
  • 1
  • 1
Marvin
  • 13,325
  • 3
  • 51
  • 57
  • it's a birth date and I really don't care about the hours and minutes. what would be the correct way of getting the epoch time? – Pablo Fernandez Feb 03 '16 at 23:33
  • Thanks Marvin, I came up with this but it's still failing with the same error: `parseLocalDate(date).toDateTimeAtStartOfDay(ArgTimezone).getMillis` – Pablo Fernandez Feb 04 '16 at 00:10
  • `formatter.parseLocalDateTime("01-10-1967").toDateTime().getMillis()` works for me. It's a bit hard to predict where you're aiming at, though - there might be easier ways for your needs. – Marvin Feb 04 '16 at 00:47
  • I'm just trying to get a timestamp for a birth date, since the db field is an integer. – Pablo Fernandez Feb 04 '16 at 03:23
  • Thanks again for the insights. That same code is failing for me, perhaps because my timezone is `(America/Argentina/Buenos_Aires)` and your's is different? I guess you could resume the problem like this **given a date with format dd-MM-yyyy, return the epoch representation of first time of that day (in Argentina/GMT-3)** – Pablo Fernandez Feb 04 '16 at 03:27
  • Thought I had the time zone manually set to Argentina (and I could verify the exception with your initial approach). I'll have to double-check, I don't have the sources here right now. – Marvin Feb 04 '16 at 13:38
  • with your guidance I found the solution, it works using `toDateTimeAtStartOfDay` a particular code path didn't call that method, it's fixed now. **thanks so much!!** – Pablo Fernandez Feb 04 '16 at 14:03