Manish
Manish

Reputation: 59

Parsing custom date with MM/dd/yyyy hh:mm:ss zzz format in android

I have a string that represents a date with a format MM/dd/yyyy hh:mm:ss that looks like:

"03/26/2014 17:32:25 IST"<BR>

When I parse the string into a date as:

SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yyyy hh:mm:ss zzz");
Calendar cal = Calendar.getInstance();
cal.setTimeZone(TimeZone.getDefault());
cal.setTime(sdf.parse("03/26/2014 17:32:25 IST"));
String output = sdf.parse(sdf.format(cal.getTime()));

While parsing the date in Android using sdf.Parse, I get an exception as java.text.ParseException: Unparseable date: "03/26/2015 17:32:25 IST" (at offset 20). Any idea??

I have tried adding Locale.getDefault() in the SimpleDateFormat but it didn't work.

Any help will be appreciated.

Upvotes: 2

Views: 7883

Answers (5)

Arvind Kumar Avinash
Arvind Kumar Avinash

Reputation: 78945

Avoid using abbreviations for time zone ID

Given below is an excerpt from the legacy TimeZone documentation:

Three-letter time zone IDs

For compatibility with JDK 1.1.x, some other three-letter time zone IDs (such as "PST", "CTT", "AST") are also supported. However, their use is deprecated because the same abbreviation is often used for multiple time zones (for example, "CST" could be U.S. "Central Standard Time" and "China Standard Time"), and the Java platform can then only recognize one of them.

So, educate the publisher of a date-time string with such an abbreviation about providing the full zone ID e.g. "Asia/Kolkata".

java.time

In March 2014, Java 8 introduced the modern, java.time date-time API which supplanted the error-prone legacy java.util date-time API. Any new code should use the java.time API.

Solution using modern date-time API

Given below is an expert from DateTimeFormatterBuilder#appendZoneText(TextStyle textStyle, Set<ZoneId> preferredZones) documentation:

During parsing, either the textual zone name, the zone ID or the offset is accepted. Many textual zone names are not unique, such as CST can be for both "Central Standard Time" and "China Standard Time". In this situation, the zone id will be determined by the region information from formatter's locale and the standard zone id for that area, for example, America/New_York for the America Eastern zone. This method also allows a set of preferred ZoneId to be specified for parsing. The matched preferred zone id will be used if the textural zone name being parsed is not unique.

So, if you get a date-time string with an ambiguous abbreviated time zone ID, you can use DateTimeFormatterBuilder#appendZoneText to define these abbreviations.

Apart from this, you have mistakenly used h instead of H. The symbol h is used when you have clock-hour-of-am-pm (1-12) and therefore it makes sense only when you have am/pm marker in the time.

Demo:

public class Main {
    public static void main(String[] args) {
        Set<ZoneId> preferredZones = Set.of(ZoneId.of("Asia/Kolkata"));
        DateTimeFormatter dtf = new DateTimeFormatterBuilder()
                .appendPattern("MM/dd/uuuu HH:mm:ss")
                .appendLiteral(' ')
                .appendZoneText(TextStyle.SHORT, preferredZones)
                .toFormatter(Locale.ENGLISH);

        ZonedDateTime zdt = ZonedDateTime.parse("03/26/2014 17:32:25 IST", dtf);
        System.out.println(zdt);
    }
}

Output:

2014-03-26T17:32:25+05:30[Asia/Kolkata]

Online Demo

Note: If for some reason, you need an instance of java.util.Date, let java.time API do the heavy lifting of parsing your date-time string and convert zdt from the above code into a java.util.Date instance using Date date = Date.from(zdt.toInstant()).

Learn more about the modern Date-Time API from Trail: Date Time.

Upvotes: 2

Nikunj Desai
Nikunj Desai

Reputation: 121

Try Below code

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    String date_parse="2015-04-09 05:06:14";
    try{
        SimpleDateFormat sdfSource = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date date = sdfSource.parse(date_parse);

        SimpleDateFormat sdfDestination = new SimpleDateFormat("MMMM dd,yyyy hh:mm a");
        date_parse = sdfDestination.format(date);

        System.out.println("Date is converted from dd/MM/yy format to MMMM dd,yyyy hh:mm a");
        System.out.println("Converted date is : " + date_parse);

    } catch(Exception e){
        System.out.println(e.getMessage());
    }
}

output: Date is converted from dd/MM/yy format to MMMM dd,yyyy hh:mm a Converted date is : April 09,2015 05:06 AM

Upvotes: 0

Meno Hochschild
Meno Hochschild

Reputation: 44061

First error: You try to case a java.util.Date (the result of parse-method) on String (compile-error).

Second error: You should use pattern symbol HH not hh (twenty-four-hour-clock according to hour input of 17h).

Third error: Set the timezone on the format object, not on Calendar (and it hopefully corresponds to timezone IST - either you are in Israel or in India).

Updated: It appears that "IST" is not a known time zone name on your Android device. The motivation of Google-Android was probably to avoid ambiguous names ("Israel Standard Time" or "India Standard Time") so Android has other different names in its resource repository. You might try text preprocessing like this workaround:

if (timestampText.endsWith(" IST")) {
  timestampText = timestampText.substring(0, timestampText.length() - 4);
}

SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss");
sdf.setTimeZone(TimeZone.getTimeZone("Asia/Kolkata"));
java.util.Date d = sdf.parse(timestampText);

Also check the output of method DateFormatSymbols.getInstance().getZoneStrings() in order to see if Android expects another timezone name instead of "IST" (which is more wide spread on Java-VMs).

Upvotes: 2

deadfish
deadfish

Reputation: 12304

umm, something like this? Make sure you are using proper imports..

import android.app.Activity;
import android.os.Bundle;
import android.widget.Toast;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

public class MyActivity extends Activity {
    /**
     * Called when the activity is first created.
     */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss zzz");
        Date parse = null;
        Calendar calendar = Calendar.getInstance();
        try {
            parse = sdf.parse("03/26/2014 17:32:25 IST");
            calendar.setTime(parse);
        } catch (ParseException e) {
            e.printStackTrace();
        }

        Toast.makeText(this, calendar.getTime() + "", Toast.LENGTH_SHORT).show();
    }
}

Upvotes: 0

Neha - Systematix
Neha - Systematix

Reputation: 96

Try Below code you need to assign output into Date data type : 

SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yyyy hh:mm:ss zzz");
    Calendar cal = Calendar.getInstance();
    cal.setTimeZone(TimeZone.getDefault());
    cal.setTime(sdf.parse("03/26/2014 17:32:25 IST"));
    java.util.Date output = sdf.parse(sdf.format(cal.getTime())); 

Upvotes: 1

Related Questions