java.time through desugaring
Consider using java.time, the modern Java date and time API, for your date work.
To get the first day of the current year — excuse my Java syntax:
LocalDate firstDayOfThisYear
= LocalDate.now(ZoneId.systemDefault()).withDayOfYear(1);
System.out.println("First day of the year: " + firstDayOfThisYear);
Output so far:
First day of the year: 2021-01-01
To format into your desired format:
String formattedDate = firstDayOfThisYear.atStartOfDay()
.format(RECORD_DTM_FORMAT);
System.out.println("Formatted date: " + formattedDate);
I used this static formatter:
private static final DateTimeFormatter RECORD_DTM_FORMAT
= DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss", Locale.ENGLISH);
Formatted date: 2021-01-01 00:00:00
What went wrong in your code?
One error is in this line:
calendar.set(Calendar.YEAR,0,1)
You were finding the first day, not of this year, but of year 1 AD (2020 years ago). You were using the constant Calendar.YEAR
incorrectly. It’s a constant to use for accessing the year field of a Calendar
object and has the value 1. So you were specifying year 1. It was a common mistake with Calendar
. In your output you can see that you get year 1 (the digit 1 at the end):
last Tue Jan 01 13:09:48 GMT+05:30 1
You also notice that the call to set()
has not got rid of the time of day, which you might have wanted to.
This method call effectively does nothing (or really very little):
recordDtmFormat.parse(recordDtmFormat.format(date))
You are formatting a Date
object into a String
only to parse it back into a Date
object again. What you get is a Date
object equal to the one you had. Only the millisecond of the second has been discarded because they are not in your string format. It’s the only difference.
A couple of further details that don’t contribute to your unexpected output, but you still might like to know: You have commented out this line:
// private val recordDtmFormat = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", Locale("en","IN"))
Hardcoding T
as a literal in your format pattern string is correct since there should always be a T
there and it doesn’t carry any semantics. The Z
carries semantics: it’s an offset of 0 from UTC. So you must never hardcode it as a literal in your format pattern string. You need to parse it as an offset, or you will get an incorrect result.
Also in your output it seems that you have set your default time zone to GMT+05:30
. This is incorrect for India. You need to set it to Asia/Kolkata. Always use the region/city format for time zones. While both give the same results for dates in this year, there are differences for historic dates and there may come differences again for future dates if the Indian politicians decide to change India’s time zone offset again some time. Experiences from other parts of the world say that this happens a lot.
Question: Doesn’t java.time require Android API level 26?
java.time works nicely on both older and newer Android devices. It just requires at least Java 6.
- On newer Android devices (from API level 26) the modern API comes built-in.
- On older Android use desugaring. See the link below.
Links