0
class TimeStampFormat {

    private val recordDtmFormat = SimpleDateFormat("yyyy-MM-dd HH:mm:ss",Locale.ENGLISH)
   // private val recordDtmFormat = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", Locale("en","IN"))
    fun getTimeStamp(): Date{
        return recordDtmFormat.parse(Calendar.getInstance().time.toString())!!
    }
    fun parseDate(date:Date):Date {
        return recordDtmFormat.parse(recordDtmFormat.format(date))!!.also {
           Log.i("mpurusharth","last $it")
        }
    }
    fun formatDate(time : String):Date{
        return recordDtmFormat.parse(time)!!.also {
            Log.i("mpurusharth","last $it")
        }
    }

my default date is supposed to be the first day of the year which I get by

   val calendar = Calendar.getInstance()
        calendar.set(Calendar.YEAR,0,1)
        val date = calendar.time

when I pass the date to the function it gives the wrong format of date

lastSyncDttm = TimeStampFormat().parseDate(date)

gives

last Tue Jan 01 13:09:48 GMT+05:30 1

why is the date not properly formatted. Even if I use the formatDate function and pass a string the format is still incorrect what am I missing ??

Pemba Tamang
  • 1,235
  • 16
  • 38
  • 1
    I'm not able to understand what's the issue here! can you please elaborate? – Jeel Vankhede Aug 26 '21 at 07:55
  • when I am using the format pattern `"yyyy-MM-dd HH:mm:ss"` any the output should be `2021-02-01 13:09:48` but what I get is `Tue Jan 01 13:09:48 GMT+05:30 1` – Pemba Tamang Aug 26 '21 at 08:24
  • the output format is completely different for some reason it it in the format of `E MMM dd HH:mm:ss z` and there is a `1` at the end for some reason – Pemba Tamang Aug 26 '21 at 08:29
  • I recommend you don’t use `SimpleDateFormat`, `Date` and `Calendar`. Those classes are poorly designed and long outdated, the first in particular notoriously troublesome. Instead use `LocalDateTime` and `DateTimeFormatter`, both from [java.time, the modern Java date and time API](https://docs.oracle.com/javase/tutorial/datetime/). – Ole V.V. Aug 26 '21 at 16:23
  • A `Date` hasn’t got, as in cannot have a format. So when you print the ´Date`, you are just getting the return value from uts `toString` method which is always in the format you obsertved, `Tue Jan 01 13:09:48 GMT+05:30 1` (for January 1 year 1 AD). – Ole V.V. Aug 26 '21 at 16:25
  • Your `fun formatDate(time : String):Date` is parsing, not formatting. Those are opposite operations. Maybe the method name confused yourself? – Ole V.V. Aug 26 '21 at 17:32
  • Does this answer your question? [display Java.util.Date in a specific format](https://stackoverflow.com/questions/6262310/display-java-util-date-in-a-specific-format) – Ole V.V. Aug 26 '21 at 17:38

2 Answers2

2

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

Ole V.V.
  • 81,772
  • 15
  • 137
  • 161
1

The reason you're not getting your desired output format in the log is because you're trying to print "date" object directly while not formatting it.

Whenever you try to print object directly as in output, it would be represented by toString() method provided from that class or from it's super. That's the reason you're not getting your desired output while you put this:

Log.i("mpurusharth","last $it")

Instead try this:

Log.i("mpurusharth","last ${recordDtmFormat.format(it)}")

Here, using format() from recordDtmFormat will generate your desired output.

Jeel Vankhede
  • 11,592
  • 2
  • 28
  • 58