Using Java SE 8 Date and Time API
The following code
DateTimeFormatter fmt = DateTimeFormatter.ofPattern("MM/dd/uuuu HH:mm:ss", Locale.ENGLISH)
.withZone(ZoneId.of("Africa/Johannesburg"));
ZonedDateTime zdtSource = ZonedDateTime.parse(strSource, fmt);
does the same thing as
DateTimeFormatter fmt = DateTimeFormatter.ofPattern("MM/dd/uuuu HH:mm:ss", Locale.ENGLISH);
ZonedDateTime zdtSource = LocalDateTime.parse(strSource, fmt)
.atZone(ZoneId.of("Africa/Johannesburg"));
which means that applying a timezone with the parser is a way of asking it to parse the date-time string as a local date-time and stick the timezone to it.
Now that you have understood this concept, let's discuss the requirement that you posted.
I've got from a System as a String without Timezone to a String with
Timezone and applied time difference
Original String: "01/27/2021 14:47:29"
Target String: "2021-01-27T13:47:29.000+01:00"
Problem: The target System can not change the format. I need to apply,
that it substracts automatically the correct amount of hours,
depending on summer/winter time. So it's not a solution to just
subtract -1.
There are two things here to understand:
- It is possible to convert the given local date-time into the target date-time only when the given local date-time is from a timezone which has a timezone offset of
UTC+02:00 e.g. Africa/Johannesburg. The following diagram describes the timezone of Europe/Berlin 
- The
ZonedDateTime has been designed to adjust the date-time automatically as per summer/winter time; so, you do not need to do anything explicitly.
Enough talking; let's see some code!
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;
public class Main {
public static void main(String[] args) {
String strSource = "01/27/2021 14:47:29";
DateTimeFormatter fmtInput = DateTimeFormatter.ofPattern("MM/dd/uuuu HH:mm:ss", Locale.ENGLISH);
ZonedDateTime zdtSource = LocalDateTime.parse(strSource, fmtInput)
.atZone(ZoneId.of("Africa/Johannesburg"));
System.out.println(zdtSource);
ZonedDateTime zdtTarget = zdtSource.withZoneSameInstant(ZoneId.of("Europe/Berlin"));
// Default format
System.out.println(zdtTarget);
// Custom format
DateTimeFormatter fmtOutput = DateTimeFormatter.ofPattern("uuuu-MM-dd'T'HH:mm:ss.SSSXXX", Locale.ENGLISH);
System.out.println(zdtTarget.format(fmtOutput));
}
}
Output:
2021-01-27T14:47:29+02:00[Africa/Johannesburg]
2021-01-27T13:47:29+01:00[Europe/Berlin]
2021-01-27T13:47:29.000+01:00
Learn more about the modern date-time API from Trail: Date Time.
Using Joda-Time API
Note: Check the following notice at the Home Page of Joda-Time
Joda-Time is the de facto standard date and time library for Java
prior to Java SE 8. Users are now asked to migrate to java.time
(JSR-310).
However, just for the sake of completeness, I've written the following code using Joda-time API:
import org.joda.time.DateTime;
import org.joda.time.DateTimeZone;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;
public class Main {
public static void main(String[] args) {
String strSource = "01/27/2021 14:47:29";
DateTimeFormatter fmtInput = DateTimeFormat.forPattern("MM/dd/yyyy HH:mm:ss")
.withZone(DateTimeZone.forID("Africa/Johannesburg"));
DateTime dtSource = fmtInput.parseDateTime(strSource);
System.out.println(dtSource);
DateTime dtTarget = dtSource.withZone(DateTimeZone.forID("Europe/Berlin"));
System.out.println(dtTarget);
}
}
Output:
2021-01-27T14:47:29.000+02:00
2021-01-27T13:47:29.000+01:00