[java] Convert String to Calendar Object in Java

I am new to Java, usually work with PHP.

I am trying to convert this string:

Mon Mar 14 16:02:37 GMT 2011

Into a Calendar Object so that I can easily pull the Year and Month like this:

String yearAndMonth = cal.get(Calendar.YEAR)+cal.get(Calendar.MONTH);

Would it be a bad idea to parse it manually? Using a substring method?

Any advice would help thanks!

This question is related to java date datetime calendar simpledateformat

The answer is


tl;dr

The modern approach uses the java.time classes.

YearMonth.from(
    ZonedDateTime.parse( 
        "Mon Mar 14 16:02:37 GMT 2011" , 
        DateTimeFormatter.ofPattern( "E MMM d HH:mm:ss z uuuu" )
     )
).toString()

2011-03

Avoid legacy date-time classes

The modern way is with java.time classes. The old date-time classes such as Calendar have proven to be poorly-designed, confusing, and troublesome.

Define a custom formatter to match your string input.

String input = "Mon Mar 14 16:02:37 GMT 2011";
DateTimeFormatter f = DateTimeFormatter.ofPattern( "E MMM d HH:mm:ss z uuuu" );

Parse as a ZonedDateTime.

ZonedDateTime zdt = ZonedDateTime.parse( input , f );

You are interested in the year and month. The java.time classes include YearMonth class for that purpose.

YearMonth ym = YearMonth.from( zdt );

You can interrogate for the year and month numbers if needed.

int year = ym.getYear();
int month = ym.getMonthValue();

But the toString method generates a string in standard ISO 8601 format.

String output = ym.toString();

Put this all together.

String input = "Mon Mar 14 16:02:37 GMT 2011";
DateTimeFormatter f = DateTimeFormatter.ofPattern( "E MMM d HH:mm:ss z uuuu" );
ZonedDateTime zdt = ZonedDateTime.parse( input , f );
YearMonth ym = YearMonth.from( zdt );
int year = ym.getYear();
int month = ym.getMonthValue();

Dump to console.

System.out.println( "input: " + input );
System.out.println( "zdt: " + zdt );
System.out.println( "ym: " + ym );

input: Mon Mar 14 16:02:37 GMT 2011

zdt: 2011-03-14T16:02:37Z[GMT]

ym: 2011-03

Live code

See this code running in IdeOne.com.

Conversion

If you must have a Calendar object, you can convert to a GregorianCalendar using new methods added to the old classes.

GregorianCalendar gc = GregorianCalendar.from( zdt );

About java.time

The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.

The Joda-Time project, now in maintenance mode, advises migration to java.time.

To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.

Where to obtain the java.time classes?

The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.


SimpleDateFormat is great, just note that HH is different from hh when working with hours. HH will return 24 hour based hours and hh will return 12 hour based hours.

For example, the following will return 12 hour time:

SimpleDateFormat sdf = new SimpleDateFormat("hh:mm aa");

While this will return 24 hour time:

SimpleDateFormat sdf = new SimpleDateFormat("HH:mm");

Simple method:

public Calendar stringToCalendar(String date, String pattern) throws ParseException {
    String DEFAULT_LOCALE_NAME = "pt";
    String DEFAULT_COUNTRY = "BR";
    Locale DEFAULT_LOCALE = new Locale(DEFAULT_LOCALE_NAME, DEFAULT_COUNTRY);
    SimpleDateFormat format = new SimpleDateFormat(pattern, LocaleUtils.DEFAULT_LOCALE);
    Date d = format.parse(date);
    Calendar c = getCalendar();
    c.setTime(d);
    return c;
}

Well, I think it would be a bad idea to replicate the code which is already present in classes like SimpleDateFormat.

On the other hand, personally I'd suggest avoiding Calendar and Date entirely if you can, and using Joda Time instead, as a far better designed date and time API. For example, you need to be aware that SimpleDateFormat is not thread-safe, so you either need thread-locals, synchronization, or a new instance each time you use it. Joda parsers and formatters are thread-safe.


Parse a time with timezone, Z in pattern is for time zone

String aTime = "2017-10-25T11:39:00+09:00";
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ", Locale.getDefault());
try {
    Calendar cal = Calendar.getInstance();
    cal.setTime(sdf.parse(aTime));
    Log.i(TAG, "time = " + cal.getTimeInMillis()); 
} catch (ParseException e) {
    e.printStackTrace();
}

Output: it will return the UTC time

1508899140000

enter image description here

If we don't set the time zone in pattern like yyyy-MM-dd'T'HH:mm:ss. SimpleDateFormat will use the time zone which have set in Setting


Yes it would be bad practice to parse it yourself. Take a look at SimpleDateFormat, it will turn the String into a Date and you can set the Date into a Calendar instance.


No new Calendar needs to be created, SimpleDateFormat already uses a Calendar underneath.

SimpleDateFormat sdf = new SimpleDateFormat("EEE MMM dd HH:mm:ss z yyyy", Locale.EN_US);
Date date = sdf.parse("Mon Mar 14 16:02:37 GMT 2011"));// all done
Calendar cal = sdf.getCalendar();

(I can't comment yet, that's why I created a new answer)


Examples related to java

Under what circumstances can I call findViewById with an Options Menu / Action Bar item? How much should a function trust another function How to implement a simple scenario the OO way Two constructors How do I get some variable from another class in Java? this in equals method How to split a string in two and store it in a field How to do perspective fixing? String index out of range: 4 My eclipse won't open, i download the bundle pack it keeps saying error log

Examples related to date

How do I format {{$timestamp}} as MM/DD/YYYY in Postman? iOS Swift - Get the Current Local Time and Date Timestamp Typescript Date Type? how to convert current date to YYYY-MM-DD format with angular 2 SQL Server date format yyyymmdd Date to milliseconds and back to date in Swift Check if date is a valid one change the date format in laravel view page Moment js get first and last day of current month How can I convert a date into an integer?

Examples related to datetime

Comparing two joda DateTime instances How to format DateTime in Flutter , How to get current time in flutter? How do I convert 2018-04-10T04:00:00.000Z string to DateTime? How to get current local date and time in Kotlin Converting unix time into date-time via excel Convert python datetime to timestamp in milliseconds SQL Server date format yyyymmdd Laravel Carbon subtract days from current date Check if date is a valid one Why is ZoneOffset.UTC != ZoneId.of("UTC")?

Examples related to calendar

Moment.js get day name from date HTML Input Type Date, Open Calendar by default Check if a given time lies between two times regardless of date Creating java date object from year,month,day How to set time to 24 hour format in Calendar How to get Month Name from Calendar? Get first date of current month in java Specify the date format in XMLGregorianCalendar Getting last day of the month in a given string date How to change TIMEZONE for a java.util.Calendar/Date

Examples related to simpledateformat

How to convert an Instant to a date format? Get Date Object In UTC format in Java How to format a java.sql.Timestamp(yyyy-MM-dd HH:mm:ss.S) to a date(yyyy-MM-dd HH:mm:ss) How to convert date to string and to date again? Java Convert GMT/UTC to Local time doesn't work as expected Java SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'") gives timezone as IST SimpleDateFormat parse loses timezone java.text.ParseException: Unparseable date Java format yyyy-MM-dd'T'HH:mm:ss.SSSz to yyyy-mm-dd HH:mm:ss SimpleDateFormat returns 24-hour date: how to get 12-hour date?