20

I have a string in the pattern yyyy-MM-dd hh:mm a and i can get the time zone object separately in which the above string represents the date.

I want to convert this to the below format. yyyy-MM-dd HH:mm:ss Z

How can i do this?

3
  • joda-time.sourceforge.net makes all date manipulations in java much much easier Commented Nov 17, 2010 at 11:09
  • @Emil i got to know this feature after you said :), Thanks. Commented Nov 17, 2010 at 11:41
  • 1
    FYI, the Joda-Time project is now in maintenance mode, with the team advising migration to the java.time classes. Commented Jan 22, 2017 at 21:47

6 Answers 6

26

You can use SimpleDateFormat with yyyy-MM-dd HH:mm:ss and explicitly set the TimeZone:

public static Date getSomeDate(final String str, final TimeZone tz)
    throws ParseException {
  final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm a");
  sdf.setTimeZone(tz);
  return sdf.parse(str);
}

/**
 * @param args
 * @throws IOException
 * @throws InterruptedException
 * @throws ParseException
 */
public static void main(final String[] args) throws ParseException {
  final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss Z");
  System.out.println(sdf.format(getSomeDate(
      "2010-11-17 01:12 pm", TimeZone.getTimeZone("Europe/Berlin"))));
  System.out.println(sdf.format(getSomeDate(
      "2010-11-17 01:12 pm", TimeZone.getTimeZone("America/Chicago"))));
}

Prints out:

2010-11-17 13:12:00 +0100

2010-11-17 20:12:00 +0100

Update 2010-12-01: If you want to explicitly printout a special TimeZone, set it in the SimpleDateFormat:

sdf.setTimeZone(TimeZone .getTimeZone("IST")); 
System.out.println(sdf.format(getSomeDate(
    "2010-11-17 01:12 pm", TimeZone.getTimeZone("IST"))));

Which prints 2010-11-17 13:12:00 +0530

Sign up to request clarification or add additional context in comments.

7 Comments

Thanks Mr.Michael, The date & time gets changed according to the Timezone.Note down the +100, it doesn't changes the TIMEZONE offset
@shal: Sorry, I do not understand your second sentence. Do you think something is wrong?
@ Michael, I am saying the time is getting converted properly but see the "Z" part in the date values printed "+0100" it doesn't changes.For eg if i am converting a date from GMT to IST then the "Z" part of the converted date must be "+0530".
This depends on the system the code is running. For IST it prints out 2010-11-17 07:42:00 +0000 on ideone.
FYI, the old Calendar and Date classes are now legacy. Supplanted by the java.time classes.
|
15

tl;dr

LocalDateTime.parse(                        // Parse string as value without time zone and without offset-from-UTC.
    "2017-01-23 12:34 PM" , 
    DateTimeFormatter.ofPattern( "uuuu-MM-dd hh:mm a" )
)                                           // Returns a `LocalDateTime` object.
.atZone( ZoneId.of( "America/Montreal" ) )  // Assign time zone, to determine a moment. Returns a `ZonedDateTime` object.
.toInstant()                                // Adjusts from zone to UTC.
.toString()                                 // Generate string: 2017-01-23T17:34:00Z
.replace( "T" , " " )                       // Substitute SPACE for 'T' in middle.
.replace( "Z" , " Z" )                      // Insert SPACE before 'Z'.

Avoid legacy date-time classes

The other Answers use the troublesome old date-time classes (Date, Calendar, etc.), now legacy, supplanted by the java.time classes.

LocalDateTime

I have a string in the pattern yyyy-MM-dd hh:mm a

Such an input string lacks any indication of offset-from-UTC or time zone. So we parse as a LocalDateTime.

Define a formatting pattern to match your input with a DateTimeFormatter object.

String input = "2017-01-23 12:34 PM" ;
DateTimeFormatter f = DateTimeFormatter.ofPattern( "uuuu-MM-dd hh:mm a" );
LocalDateTime ldt = LocalDateTime.parse( input , f );

ldt.toString(): 2017-01-23T12:34

Note that a LocalDateTime is not a specific moment, only a vague idea about a range of possible moments. For example, a few minutes after midnight in Paris France is still “yesterday” in Montréal Canada. So without the context of a time zone such as Europe/Paris or America/Montreal, just saying “a few minutes after midnight” has no meaning.

ZoneId

and i can get the time zone object separately in which the above string represents the date.

A time zone is represented by the ZoneId class.

Specify a proper time zone name in the format of continent/region, such as America/Montreal, Africa/Casablanca, or Pacific/Auckland. Never use the 3-4 letter abbreviation such as EST or IST as they are not true time zones, not standardized, and not even unique(!).

ZoneId z = ZoneId.of( "America/Montreal" );

ZonedDateTime

Apply the ZoneId to get a ZonedDateTime which is indeed a point on the timeline, a specific moment in history.

ZonedDateTime zdt = ldt.atZone( z );

zdt.toString(): 2017-01-23T12:34-05:00[America/Montreal]

Instant

I want to convert this to the below format. yyyy-MM-dd HH:mm:ss Z

First, know that a Z literal character is short for Zulu and means UTC. In other words, an offset-from-UTC of zero hours, +00:00.

The Instant class represents a moment on the timeline in UTC with a resolution of nanoseconds (up to nine (9) digits of a decimal fraction).

You can extract a Instant object from a ZonedDateTime.

Instant instant = zdt.toInstant();  // Extracting the same moment but in UTC.

To generate a string in standard ISO 8601 format, such as 2017-01-22T18:21:13.354Z, call toString. The standard format has no spaces, uses a T to separate the year-month-date from the hour-minute-second, and appends the Z canonically for an offset of zero.

String output = instant.toString();

instant.toString(): 2017-01-23T17:34:00Z

I strongly suggest using the standard formats whenever possible. If you insist on using spaces as in your stated desired format, either define your own formatting pattern in a DateTimeFormatter object or just do a string manipulation on the output of Instant::toString.

String output = instant.toString()
                       .replace( "T" , " " )  // Substitute SPACE for T.
                       .replace( "Z" , " Z" ); // Insert SPACE before Z.

output: 2017-01-23 17:34:00 Z

Try this code live at IdeOne.com.


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 the java.time classes.

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.

2 Comments

The tldr is missing .toInstant().
@Muhd Indeed. Fixed. Thanks!
5

Use SimpleDateFormat

String string1 = "2009-10-10 12:12:12 ";
SimpleDateFormat sdf =  new SimpleDateFormat("yyyy-MM-dd HH:mm:ss Z")
sdf.setTimeZone(tz);
Date date = sdf.parse(string1);

3 Comments

some times the getID() returns the string like this "America/Argentina/Ushuaia". So how can i use it
@Michael Konietzka @shal I hurry i missed that, updated the answer
@Michael Konietzka You are right at your place, but its not the case
1

Undoubtedly, the format which is generally used will be of a form 2014-10-05T15:23:01Z (TZ)

For that one has to use this code

SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ");
String dateInString = "2014-10-05T15:23:01Z";

 try {

     Date date = formatter.parse(dateInString.replaceAll("Z$", "+0000"));
     System.out.println(date);

 } catch (ParseException e) {
     e.printStackTrace();
 }

Its output will be Sun Oct 05 20:53:01 IST 2014

However, I am not sure why we had to replaceAll "Z" if you do not add replaceAll the program will fail.

1 Comment

Just a note on the replaceAll() comment in your answer. replace() works with string literals where as replaceAll() or replaceFirst() supports a regular expression. If you did replace("Z", "+0000"), that should give you the same result as your replaceAll("Z$", "+0000")
0

Create a new instance of SimpleDateFormat using your date pattern. Afterwards you can call it's parse method to convert date strings to a java.util.Date object.

Comments

0

Please try this for the format "yyyy-MM-dd HH:mm:ss Z", Eg: "2020-12-11 22:59:59 GMT", you can use different time zones like PST, GMT, etc.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.