0

So, a few days ago I encountered an interesting bug in the old and bad java.util.Date API.

In this code snippet we have 3 different SimpleDateFormat, and some date to parse:

val sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
  val sdfPartname = new SimpleDateFormat("YYYY-MM-dd") 
  val sdfShort = new SimpleDateFormat("yyMMddHHmm")
  sdfShort.setTimeZone(TimeZone.getTimeZone("UTC"))

  val batchIdList = List(1912311300,1912301130,2001011300,1812311300,1612311300)
  batchIdList.foreach( batchId => {
    print("\nResult for input:" + batchId + "\n")
    val date = sdfShort.parse(batchId.toString).getTime
    print("dt: " + sdf.format(date) + "\n") 
    print("partname: " + sdfPartname.format(date) + "\n"))
  })

Output is very interesting:

Result for input:1912311300
dt: 2019-12-31 14:00:00
partname: 2020-12-31

Result for input:1912301130
dt: 2019-12-30 12:30:00
partname: 2020-12-30

Result for input:2001011300
dt: 2020-01-01 14:00:00
partname: 2020-01-01

Result for input:1812311300
dt: 2018-12-31 14:00:00
partname: 2019-12-31

Result for input:1612311300
dt: 2016-12-31 14:00:00
partname: 2016-12-31

I don't know what is behind this wrong year. Do you have any ideas?

PS: Of course changing to ZonedDateTime solved the problem, but none the less I want to know why java.util.Date works this way.

Slaw
  • 37,820
  • 8
  • 53
  • 80
  • `y` != `Y`. Check your patterns – jhamon Jan 14 '20 at 15:50
  • Note that `yyyy` is something else than `YYYY`. Capital Y = week year, which is the year that the week falls in. Which can be different from the actual year with is lower-case y. See [`SimpleDateFormat` API docs](https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/text/SimpleDateFormat.html). – Jesper Jan 14 '20 at 15:51
  • 2
    Does this answer your question? [Y returns 2012 while y returns 2011 in SimpleDateFormat](https://stackoverflow.com/questions/8686331/y-returns-2012-while-y-returns-2011-in-simpledateformat) – jhamon Jan 14 '20 at 15:51
  • 1
    Of course, use of `SimpleDateFormat` and `Date` classes is strongly discouraged. in favor of use of `java.time` package and `DateTimeFormatter` class. As for the bug itself, it does look like a bug and my hunch is it will never be fixed, but what I see that in your masks you use 'y' and 'Y' which technically are not the same although similar. Try to switch to either 'Y' or 'y' in all of your formats and see if it solves your problem – Michael Gantman Jan 14 '20 at 16:00
  • @MichaelGantman only for java 8+ users – jhamon Jan 14 '20 at 16:55
  • @jhamon yes, of course, it is for Java 8 and higher. But I just assume that most people today work on Java 8 at least. Java 7 or lower is a rare exception rather than a rule – Michael Gantman Jan 14 '20 at 17:09
  • java.time has been backported to Java 6 and 7 in [ThreeTen Backport](https://www.threeten.org/threetenbp/). @jhamon If coding for java 5, I suggest [Joda-Time](https://www.joda.org/joda-time/). Use `SimpleDateFormat` only if you love being frustrated… :-) – Ole V.V. Jan 14 '20 at 21:23

0 Answers0