Bajrang Hudda
Bajrang Hudda

Reputation: 3268

What is the correct way to format a date string to m/d/yyyy from "2020-05-08T11:01:48.3300000Z" datetime string in java/ Kotlin

I am trying to format a DateTime string that is received from the server. I have used the below formats and none is working - AppConstants.API_DATE_TIME_FORMAT =

 - `"yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"`
 - `"yyyy-MM-dd'T'HH:mm:ss.SSSZ'Z'"`
 - `"yyyy-MM-dd'T'HH:mm:ss.SSSZ"`
 - `"yyyy-MM-dd'T'HH:mm:ss.SSSXX'Z'"`
 - `"yyyy-MM-dd'T'hh:mm:ss.SSSSSS'Z'"`

 and - 

     fun getFormattedDate(apiFormatDateTime: String): String {
        return try{
            val parser = SimpleDateFormat(AppConstants.API_DATE_TIME_FORMAT, Locale.getDefault())
            val formatter = SimpleDateFormat(AppConstants.UI_DATE_FORMAT, Locale.getDefault())
            val date = parser.parse(apiFormatDateTime)!!
            formatter.format(date)
        }catch (ex : Exception){
            apiFormatDateTime
        }
    }

Upvotes: 0

Views: 2326

Answers (5)

Anonymous
Anonymous

Reputation: 86324

java.time

I recommend that you use java.time, the modern Java date and time API, for your date and time work. In Java (because this is what I can write):

    ZoneId zone = ZoneId.of("Asia/Kolkata");
    DateTimeFormatter uiDateFormatter = DateTimeFormatter.ofPattern("M/d/uuuu");

    String isoF8601ormatDateTime = "2020-05-08T11:01:48.3300000Z";
    Instant time = Instant.parse(isoF8601ormatDateTime);
    String uiString = time.atZone(zone)
            .format(uiDateFormatter);

    System.out.println(uiString);

Output is:

5/8/2020

Points to note:

  • The format from your API is ISO 8601. The classes of java.time parse the most common ISO 8601 variants as their default, that is, we need not specify any formatter.
  • My code also converts the date to the user’s time zone before formatting. Most users will expect this. Please put your user’s time zone where I put Asia/Kolkata.

Bonus info: to format the time, in the user’s time zone too:

    DateTimeFormatter uiTimeFormatter
            = DateTimeFormatter.ofPattern("hh:mm:ss a", Locale.ENGLISH);
    String uiTimeString = time.atZone(zone).format(uiTimeFormatter);
    System.out.println(uiTimeString);

04:31:48 PM

What went wrong in your attemtps?

  • There exists no way that SimpleDateFormat can parse 7 decimals on the seconds correctly. It only supports milliseconds, exactly three decimals. SimpleDateFormat takes 3300000 to be milliseconds, that is 3300 seconds or nearly an hour, which it adds to the time parsed.
  • Z in your incoming string is a UTC offset (of zero) and needs to be parsed as such, or you will get an incorrect result.
  • Z without quotes will parse an offset like +0000, but not Z. XX will parse Z, but that attempt failed because you additionally required (one more) Z after the Z.
  • You did not convert to the user’s time zone before formatting.

Links

Upvotes: 1

Bajrang Hudda
Bajrang Hudda

Reputation: 3268

Here is how I did it for getting date and time from UTC format -

    const val API_DATE_TIME_FORMAT = "yyyy-MM-dd'T'HH:mm:ss.SSSSSSS'Z'"
    const val UI_DATE_FORMAT = "MM/dd/yyyy"
    const val UI_TIME_FORMAT = "hh:mm:ss a"

/**
     * Function for getting date from api datetime string
     * @return formatted time
     */
    fun getFormattedDate(apiFormatDateTime: String): String {
        return try{
            val parser = SimpleDateFormat(AppConstants.API_DATE_TIME_FORMAT, Locale.getDefault())
            parser.timeZone = TimeZone.getTimeZone("UTC")
            val formatter = SimpleDateFormat(AppConstants.UI_DATE_FORMAT, Locale.getDefault())
            val date = parser.parse(apiFormatDateTime)!!
            formatter.timeZone = TimeZone.getDefault()
            formatter.format(date)
        }catch (ex : Exception){
            apiFormatDateTime
        }
    }

    /**
     * Function for getting time from api datetime string
     * @return formatted time
     */
    fun getFormattedTime(apiFormatDateTime: String): String {
        return try{
            val parser = SimpleDateFormat(AppConstants.API_DATE_TIME_FORMAT, Locale.getDefault())
            parser.timeZone = TimeZone.getTimeZone("UTC")
            val formatter = SimpleDateFormat(AppConstants.UI_TIME_FORMAT, Locale.getDefault())
            formatter.timeZone = TimeZone.getDefault()
            formatter.format(parser.parse(apiFormatDateTime)!!)
        }catch (ex : Exception){
            apiFormatDateTime
        }
    }

Upvotes: 0

NKR
NKR

Reputation: 186

You can try it like below

try {
            XMLGregorianCalendar dt = DatatypeFactory.newInstance().newXMLGregorianCalendar("2020-05-13T12:12:12.123456Z");
            String dateValue = new SimpleDateFormat("MM/dd/yyyy").format(dt.toGregorianCalendar().getTime());
            System.out.println("datevalue="+dateValue);
        } catch (DatatypeConfigurationException e) {
            e.printStackTrace();
        }   

output: datevalue=05/13/2020

Upvotes: 0

sheunglaili
sheunglaili

Reputation: 318

You could try using LocalDateTime and DateTimeFormatter

String str = "1986-04-08 12:30";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm");
LocalDateTime dateTime = LocalDateTime.parse(str, formatter);
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm");
LocalDateTime dateTime = LocalDateTime.of(1986, Month.APRIL, 8, 12, 30);
String formattedDateTime = dateTime.format(formatter); // "1986-04-08 12:30"

credit to :https://stackoverflow.com/a/22463063/9297896

Upvotes: 0

This works

        String d="2020-05-08T11:01:48.3300000Z";
        DateFormat originalFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSSSSS'Z'");
        DateFormat targetFormat = new SimpleDateFormat("yyyyMMdd");
        Date date = originalFormat.parse(d);
        String formattedDate = targetFormat.format(date); 
        System.out.println("date==>"+formattedDate);

Output::

date==>20200508

Upvotes: 3

Related Questions