I have date which is in the format of(example) Date = 2023-01-09T23:51:44.595Z and I have utcOffset String utcOffset = "UTC 6"
I want output as 2023-01-10T05:51:44.595Z in Date format.
How to achieve this??
I should add UTC offset to existing date.
Tried this:
public static void main(String[] args) throws ParseException {
String rawDate = "2023-01-09T23:51:44.595Z";
String utcOffset = "UTC 6";
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", Locale.ROOT);
Date date = (Date) formatter.parse(rawDate);
SimpleDateFormat formatter1 = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", Locale.ROOT);
String v = formatter1.format(date);
System.out.println("Original raw date::::::::::" v);
System.out.println("utcOffset::::::::::" utcOffset);
Date triggerTime = date;
String onlyHoursAndMin = StringUtils.strip(utcOffset, "UTC ");
String[] split = onlyHoursAndMin.split(":");
int hours = Integer.parseInt("0");
int minutes = Integer.parseInt("0");
if (split.length == 2) {
hours = Integer.parseInt(split[0]);
minutes = Integer.parseInt(split[1]);
} else if (split.length == 1) {
hours = Integer.parseInt(split[0]);
minutes = Integer.parseInt("0");
}
TimeZone timeZone = TimeZone.getTimeZone("UTC");
Calendar calendar = Calendar.getInstance(timeZone);
calendar.setTime(triggerTime);
calendar.add(Calendar.HOUR_OF_DAY, hours);
calendar.add(Calendar.MINUTE, minutes);
Date s = calendar.getTime();
SimpleDateFormat utcFormatter1 = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", Locale.ROOT);
String newDate = utcFormatter1.format(s);
System.out.println("Date in string format::::::::::::::" newDate);
SimpleDateFormat format1 = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", Locale.ROOT);
SimpleDateFormat format2 = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", Locale.ROOT);
Date aaa = format1.parse(newDate);
String bbb = format2.format(aaa);
System.out.println(":::::::::::::" aaa);
System.out.println("Date in correct format::::::::::::::" format2.format(aaa));
}
but finale Date format is Tue Jan 10 05:51:44 IST 2023 which is not expected.
and when build I am getting below error as well: Forbidden method invocation: java.util.Calendar#getInstance(java.util.TimeZone) [Uses default locale or time zone]
CodePudding user response:
I would suggest to move away from the legacy API (java.util.Date, java.util.Calendar, etc.), it is cumbersome and error prone. Since java 8 the modern date-time API, java.time, is available. With it the task would be quite trivial.
String date = "2023-01-09T23:51:44.595Z";
OffsetDateTime oldDateTime = OffsetDateTime.parse(date);
System.out.println("old - " oldDateTime);
ZoneOffset offset = ZoneOffset.ofHours(6);
OffsetDateTime newDateTime = oldDateTime.withOffsetSameInstant(offset);
System.out.println("new - " newDateTime);
Prints time - 2023-01-10T05:51:44.595 06:00
.
Note that it ends with 06:00
, not Z
. Z
at the end of a date-time string means Zulu
, which indicates that the time is in UTC - What is the Z ending on date strings like 2014-01-01T00:00:00.588Z. Since resulting time is UTC 6 hours, a date sting 2023-01-10T05:51:44.595Z
would be incorrect.
CodePudding user response:
java.time
The java.util
date-time API and their corresponding parsing/formatting type, SimpleDateFormat
are outdated and error-prone. In March 2014, the modern Date-Time API was released as part of the Java 8 standard library which supplanted the legacy date-time API and since then it is strongly recommended to switch to java.time
, the modern date-time API.
Solution using java.time
java.time
API is based on ISO 8601 and therefore you do not need aDateTimeFormatter
to parse a date-time string which is already in ISO 8601 format e.g. your date-time string,2023-01-09T23:51:44.595Z
which can be directly parsed into anOffsetDateTime
.- Your offset string is not in the ISO 8601 standard format. The standard format is
/-HH:mm:ss
orZ
which refers to00:00
offset. In most cases, you will see/-HH:mm
e.g.06:00
. You can choose any basic string manipulation technique to get the hours and minutes from your string and create aZoneOffset
instance using them. I have used one which I have found easy to do.
The rest of the code is straightforward.
Demo:
import java.time.OffsetDateTime;
import java.time.ZoneOffset;
class Main {
public static void main(String[] args) {
String strDateTime = "2023-01-09T23:51:44.595Z";
String utcOffset = "UTC 6";
int offsetHour = Integer.parseInt(utcOffset.replaceAll("[^0-9 -]", ""));
ZoneOffset zoneOffset = ZoneOffset.ofHours(offsetHour);
OffsetDateTime odtGiven = OffsetDateTime.parse(strDateTime);
OffsetDateTime odtDesired = odtGiven.withOffsetSameLocal(zoneOffset)
.withOffsetSameInstant(zoneOffset.UTC);
System.out.println(odtDesired);
}
}
Output:
2023-01-09T17:51:44.595Z
Note that 2023-01-10T05:51:44.595Z
does not make sense without am/pm marker as you mean 05:51:44.595 pm
. You can use a DateTimeFormatter
to format it in your desired way.
Learn more about the modern Date-Time API from Trail: Date Time.