Joseph Freeman
Joseph Freeman

Reputation: 1784

Java String Timestamp Conversion to 12 Hour AM/PM With Correct Time

I have a string timestamp like the following, 2021-06-22T21:54:18.496Z, I am trying to convert this into a 12 hour am/pm. I've tried the following:

String myTime = "2021-06-22T21:54:18.496Z";
var zonedDateTime = ZonedDateTime.parse(myTime).format(DateTimeFormatter.ofPattern("MMMM dd, yyyy h:mm a"));
System.out.println(zonedDateTime);

The output appears correct June 22, 2021 9:54 PM but the time is incorrect. I'm thinking I need to get and set the correct time zone first before the parse but I'm not sure how to go about doing that.

Any help would be most appreciated.

Upvotes: 1

Views: 1085

Answers (2)

Basil Bourque
Basil Bourque

Reputation: 338730

tl;dr

Substitute your desired ZoneId, FormatStyle, & Locale.

Instant
.parse( "2021-06-22T21:54:18.496Z" )
.atZone(
    ZoneId.of( "Europe/Istanbul" )             // Or ZoneId.systemDefault()
)
.format(
    DateTimeFormatter
    .ofLocalizedDateTime( FormatStyle.FULL ) 
    .withLocale( Locale.FRANCE )               // Or Locale.getDefault()
)

See that code run live at IdeOne.com.

Notice the different date and time-of-day, but still representing same moment, the same point on the timeline.

mercredi 23 juin 2021 à 00:54:18 Heure d'Europe de l'Est

Details

While the Answer by N.M. is correct, I suggest a slightly different approach.

Your input string 2021-06-22T21:54:18.496Z is in standard ISO 8601 format. The T separates the date portion from the time-of-day portion. The Z on the end means an offset-from-UTC of zero hours-minutes-seconds. The Z is pronounced “Zulu”, for “Zulu time”.

The appropriate type for this specific kind of string of Instant. No need to specify a formatting pattern, as the java.time classes by default use ISO 8601 formats when parsing/generating text.

Instant instant = Instant.parse( "2021-06-22T21:54:18.496Z" ) ;

An Instant represents a moment in UTC, always in UTC, meaning an offset of zero.

Note that your input, and an Instant, use an offset-from-UTC but lack a time zone. A time zone is named history of the past, present, and future changes to the offset used by the people of a particular region. A real time zone name uses a format of Continent/Region.

If you want to adjust from an offset of zero to a particular time zone, specify a ZoneID to produce a ZonedDateTime.

ZoneId z = ZoneId.of( "Asia/Tokyo" ) ;
ZonedDateTime zdt = instant.atZone( z ) ;

You may choose to specify a format when generating text to represent the value within our ZonedDateTime object. But I suggest soft-coding, to let java.time automatically localize. Specify a Locale to determine localization issues.

Locale locale = Locale.CANADA_FRENCH ;
DateTimeFormatter f = DateTimeFormatter.ofLocalizedDateTime( FormatStyle.MEDIUM ).withLocale(locale ) ;
String output = zdt.format( f ) ;

Upvotes: 1

N.M.
N.M.

Reputation: 41

Edit: I edited the answer to show how to use your JVM's current default time zone, and a specific time zone.

public static void main(String[] args) {
    String myTime = "2021-06-22T21:54:18.496Z";
    parseFormatAndPrintWithSpecificTimeZone(myTime);
    parseFormatAndPrintUsingDefaultTimeZone(myTime);
}

private static void parseFormatAndPrintUsingDefaultTimeZone(String myTime) {
    var zonedDateTime = ZonedDateTime.parse(myTime)
            .format(DateTimeFormatter.ofPattern("MMMM dd, yyyy h:mm:ss.SSS a").withZone(
                    ZoneId.systemDefault() // Get the JVM’s current default time zone. Can change at any moment during runtime. If important, confirm with the user.x
                    ));
    System.out.println("Time using my JVM current default time zone:"+ zonedDateTime);
    
}

private static void parseFormatAndPrintWithSpecificTimeZone(String myTime) {

    var zonedDateTime = ZonedDateTime.parse(myTime)
            .format(DateTimeFormatter.ofPattern("MMMM dd, yyyy h:mm:ss.SSS a").withZone(
                    ZoneId.of("Asia/Singapore") //Specified TimeZone
                    ));
    System.out.println("Time using specific timezone (singapore in this case):"+zonedDateTime);
    
}

Upvotes: 1

Related Questions