Android Format date with time zone

30,949

Solution 1

You can use Joda Time instead. Its DateTimeFormat has a ZZ format attribute which does what you want.

Link

Big advantage: unlike SimpleDateFormat, DateTimeFormatter is thread safe. Usage:

DateTimeFormatter fmt = DateTimeFormat.forPattern("yyyy-MM-dd'T'HH:mm:ssZZ")
    .withLocale(Locale.ENGLISH);

Solution 2

You can also use "ZZZZZ" instead of "Z" in your pattern (according to documentation). Something like this

    Calendar c = Calendar.getInstance();
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZZZZZ", Locale.ENGLISH);      
    Log.e(C.TAG, "formatted string: "+sdf.format(c.getTime()));

Solution 3

tl;dr

You can use the pattern, yyyy-MM-dd'T'HH:mm:ssXXX for your desired output.

java.time

The date-time API of java.util and their formatting API, SimpleDateFormat are outdated and error-prone. It is recommended to stop using them completely and switch to the modern date-time API.

Using the modern date-time API:

Building an object that holds date, time and timezone offset information and formatting the same:

import java.time.LocalDate;
import java.time.LocalTime;
import java.time.OffsetDateTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.util.Locale;

public class Main {
    public static void main(String[] args) {
        OffsetDateTime odt = OffsetDateTime.of(LocalDate.of(2013, 1, 4), LocalTime.of(15, 51, 45),
                ZoneOffset.ofHoursMinutes(5, 30));

        // Print the default format i.e. the string returned by OffsetDateTime#toString
        System.out.println(odt);

        // Custom format
        DateTimeFormatter dtf = DateTimeFormatter.ofPattern("uuuu-MM-dd'T'HH:mm:ssXXX", Locale.ENGLISH);
        System.out.println(dtf.format(odt));
    }
}

Output:

2013-01-04T15:51:45+05:30
2013-01-04T15:51:45+05:30

As you can notice, the outputs for the default format and for that using a DateTimeFormatter are same. However, there is a catch here: the implementation of OffsetDateTime#toString omits the second and the fraction of second if they are 0 i.e. if the time in the above code is LocalTime.of(15, 0, 0), the output for the default format will be 2013-01-04T15:00+05:30. If you need a string like 2013-01-04T15:00:00+05:30 for this time, you will have to use a DateTimeFormatter with the desired pattern.

Parsing and formatting:

import java.time.OffsetDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;

public class Main {
    public static void main(String[] args) {
        DateTimeFormatter dtfForInputString = DateTimeFormatter.ofPattern("uuuu-MM-dd'T'HH:mm:ssZ", Locale.ENGLISH);
        OffsetDateTime odt = OffsetDateTime.parse("2013-01-04T15:51:45+0530", dtfForInputString);

        // Print the default format i.e. the string returned by OffsetDateTime#toString
        System.out.println(odt);

        // Custom format
        DateTimeFormatter dtfCustomOutput = DateTimeFormatter.ofPattern("uuuu-MM-dd'T'HH:mm:ssXXX", Locale.ENGLISH);
        System.out.println(dtfCustomOutput.format(odt));
    }
}

Output:

2013-01-04T15:51:45+05:30
2013-01-04T15:51:45+05:30

Using the legacy API:

Building a date-time object for the given timezone offset and formatting the same:

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;
import java.util.TimeZone;

public class Main {
    public static void main(String[] args) {
        Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("GMT+05:30"));
        calendar.set(2013, 0, 4, 15, 51, 45);
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssXXX", Locale.ENGLISH);
        sdf.setTimeZone(TimeZone.getTimeZone("GMT+05:30"));
        Date date = calendar.getTime();
        System.out.println(sdf.format(date));
    }
}

Output:

2013-01-04T15:51:45+05:30

The Calendar class uses UTC (or GMT) as its default timezone and therefore, unless you specify the timezone with it, it will return the java.util.Date object for UTC.

Similarly, the SimpleDateFormat class also uses UTC as its default timezone and therefore, unless you specify the timezone with it, it will return the formatted String for the corresponding date-time in UTC.

Parsing and formatting:

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.TimeZone;

public class Main {
    public static void main(String[] args) throws ParseException {
        SimpleDateFormat sdfForInputString = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ", Locale.ENGLISH);
        Date date = sdfForInputString.parse("2013-01-04T15:51:45+0530");

        SimpleDateFormat sdfCustomOutput = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssXXX", Locale.ENGLISH);
        sdfCustomOutput.setTimeZone(TimeZone.getTimeZone("GMT+05:30"));
        System.out.println(sdfCustomOutput.format(date));
    }
}

Output:

2013-01-04T15:51:45+05:30

Solution 4

What you can do is just add the ":" manually using substring(). I have faced this earlier and this solution works.

Solution 5

Why not just do it manually with regexp?

String oldDate = "2013-01-04T15:51:45+0530";
String newDate = oldDate.replaceAll("(\\+\\d\\d)(\\d\\d)", "$1:$2");

Same result, with substring (if performance is an issue).

String oldDate = "2013-01-04T15:51:45+0530";
int length = oldDate.length();
String newDate = oldDate.substring(0, length - 2) + ':' + oldDate.substring(length - 2);
Share:
30,949
fargath
Author by

fargath

Updated on January 14, 2021

Comments

  • fargath
    fargath over 3 years

    I need to format the date into a specific string.

    I used SimpleDateFormat class to format the date using the pattern "yyyy-MM-dd'T'HH:mm:ssZ" it returns current date as
    "2013-01-04T15:51:45+0530" but I need as
    "2013-01-04T15:51:45+05:30".

    Below is the coding used,

    Calendar c = Calendar.getInstance();
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ", Locale.ENGLISH);      
    Log.e(C.TAG, "formatted string: "+sdf.format(c.getTime()));
    

    Output: formatted string: 2013-01-04T15:51:45+0530

    I need the format as 2013-01-04T15:51:45+05:30 just adding the colon in between gmt time.

    Because I'm working on Google calendar to insert an event, it accepts only the required format which I have mentioned.