Reputation: 1784
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
Reputation: 338730
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
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
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