Doug Molineux
Doug Molineux

Reputation: 12431

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!

Upvotes: 210

Views: 435547

Answers (9)

selami tastan
selami tastan

Reputation: 102

I think this is the efficient way.

/**
 * Customized Date and Time Formats
 * Pattern                          Output
 * dd.MM.yy                         30.06.09
 * yyyy.MM.dd G 'at' hh:mm:ss z     2009.06.30 AD at 08:29:36 PDT
 * EEE, MMM d, ''yy Tue,            Jun 30, '09
 * h:mm a                           8:29 PM
 * H:mm                             8:29
 * H:mm:ss:SSS                      8:28:36:249
 * K:mm a,z                         8:29 AM,PDT
 * yyyy.MMMMM.dd GGG hh:mm aaa      2009.June.30 AD 08:29 AM
 */


public static LocalDateTime toLocalDateTime(long timeInMs){
    return Instant.ofEpochMilli(timeInMs).atZone(ZoneId.systemDefault()).toLocalDateTime();
}

public static LocalDateTime parseTimeNumeric(String time){
    Calendar calendar = Calendar.getInstance();
    SimpleDateFormat formatter = new SimpleDateFormat("dd" + "." + "MM" + "." + "yy" + " " + "HH" + ":" + "mm" + ":" + "ss");
    try {
        calendar.setTime(formatter.parse(time));
    } catch (ParseException e) {
        return null;
    }
    return toLocalDateTime(calendar.getTimeInMillis());
}

Example

    LocalDateTime localDateTime = parseTimeNumeric("time format");

    localDateTime.getYear();
    localDateTime.getMonthValue();
    localDateTime.getDayOfMonth();
    localDateTime.getHour();
    localDateTime.getMinute();
    localDateTime.getSecond();

Upvotes: 0

Basil Bourque
Basil Bourque

Reputation: 340070

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.

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

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

You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for java.sql.* classes. Hibernate 5 & JPA 2.2 support java.time.

Where to obtain the java.time classes?

Upvotes: 26

Linh
Linh

Reputation: 61009

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

Upvotes: 6

Jigar Joshi
Jigar Joshi

Reputation: 240956

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

note: set Locale according to your environment/requirement


See Also

Upvotes: 458

Alberto Cerqueira
Alberto Cerqueira

Reputation: 1419

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;
}

Upvotes: 1

GoGoris
GoGoris

Reputation: 840

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)

Upvotes: 10

Philip
Philip

Reputation: 523

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");

Upvotes: 6

John Vint
John Vint

Reputation: 40266

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.

Upvotes: 3

Jon Skeet
Jon Skeet

Reputation: 1503300

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.

Upvotes: 14

Related Questions