Update

I understood from you that you are using the API as follows:

apiClient.getJSON().setOffsetDateTimeFormat(DateTimeFormatter); 

and you do not have a parameter to pass timezone information. In this case, you can use DateTimeFormatter#withZone as shown below:

import java.time.OffsetDateTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.util.Locale;

public class Main {
    public static void main(String[] args) {
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("uuuuMMddHHmmss", Locale.ENGLISH)
                                        .withZone(ZoneOffset.UTC);

        OffsetDateTime odt = OffsetDateTime.parse("20210817132649", formatter);

        System.out.println(odt);
    }
}

Output:

2021-08-17T13:26:49Z

ONLINE DEMO

i.e. now, your call will be:

DateTimeFormatter formatter = DateTimeFormatter.ofPattern("uuuuMMddHHmmss", Locale.ENGLISH)
                                .withZone(ZoneOffset.UTC);

apiClient.getJSON().setOffsetDateTimeFormat(formatter); 

Original answer

Your date-time string does not have a timezone offset. Parse it into a LocalDateTime and then apply the offset to it.

Demo:

import java.time.LocalDateTime;
import java.time.OffsetDateTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.util.Locale;

public class Main {
    public static void main(String[] args) {
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("uuuuMMddHHmmss", Locale.ENGLISH);
        
        OffsetDateTime odt = LocalDateTime.parse("20210817132649", formatter)
                                .atOffset(ZoneOffset.UTC);
        
        System.out.println(odt);
    }
}

Output:

2021-08-17T13:26:49Z

ONLINE DEMO

The Z in the output is the timezone designator for zero-timezone offset. It stands for Zulu and specifies the Etc/UTC timezone (which has the timezone offset of +00:00 hours). You can specify a different timezone offset (e.g. ZoneOffset.of("+05:30")) as per your requirement.

In case you have ZoneId available

If you have ZoneId available, you should parse the given date-time string into a LocalDateTime and then apply the ZoneId to it to get a ZonedDateTime from which you can always obtain an OffsetDateTime. The best thing about a ZonedDateTime is that it has been designed to adjust the timezone offset automatically whereas an OffsetDateTime is used to represent a fixed timezone offset.

Demo:

import java.time.LocalDateTime;
import java.time.OffsetDateTime;
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) {
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("uuuuMMddHHmmss", Locale.ENGLISH);

        ZonedDateTime zdt = LocalDateTime.parse("20210817132649", formatter)
                                .atZone(ZoneId.of("Etc/UTC"));

        OffsetDateTime odt = zdt.toOffsetDateTime();

        System.out.println(odt);
    }
}

Output:

2021-08-17T13:26:49Z

ONLINE DEMO

You can specify a different ZoneId(e.g. ZoneId.of("Asia/Kolkata")) as per your requirement.

Learn more about the modern Date-Time API* from Trail: Date Time.


* If you are working for an Android project and your Android API level is still not compliant with Java-8, check Java 8+ APIs available through desugaring. Note that Android 8.0 Oreo already provides support for java.time.

Answer from Arvind Kumar Avinash on Stack Overflow
🌐
Oracle
docs.oracle.com › javase › 8 › docs › api › java › time › format › DateTimeFormatter.html
DateTimeFormatter (Java Platform SE 8 )
4 days ago - A pattern is used to create a Formatter using the ofPattern(String) and ofPattern(String, Locale) methods. For example, "d MMM uuuu" will format 2011-12-03 as '3 Dec 2011'. A formatter created from a pattern can be used as many times as necessary, it is immutable and is thread-safe.
🌐
Java Tips
javatips.net › api › java.time.format.datetimeformatter.ofpattern
Java Examples for java.time.format.DateTimeFormatter.ofPattern
@Test public void subtract_minutes_from_date_in_java8() { LocalDateTime newYearsDay = LocalDateTime.of(2013, Month.JANUARY, 1, 0, 0); LocalDateTime newYearsEve = newYearsDay.minusMinutes(1); java.time.format.DateTimeFormatter formatter = java.time.format.DateTimeFormatter.ofPattern("MM/dd/yyyy HH:mm:ss S"); logger.info(newYearsDay.format(formatter)); logger.info(newYearsEve.format(formatter)); assertTrue(newYearsEve.isBefore(newYearsDay)); }
Discussions

java - How to parse DateTime in format yyyyMMddHHmmss to OffsetDateTime using DateFormatter - Stack Overflow
I have an API for JSON parsing which requires a DateTimeFormatter instance in order to parse date time strings to OffsetDateTime. However I always get an exception Unable to obtain ZoneOffset from More on stackoverflow.com
🌐 stackoverflow.com
Is it possible to format dates in format yyyyMMddHHmmssSSS and yyyyMMddHHmmss with a single DateTimeFormatter?
Please ensure that: Your code is properly formatted as code block - see the sidebar (About on mobile) for instructions You include any and all error messages in full You ask clear questions You demonstrate effort in solving your question/problem - plain posting your assignments is forbidden (and such posts will be removed) as is asking for or giving solutions. Trying to solve problems on your own is a very important skill. Also, see Learn to help yourself in the sidebar If any of the above points is not met, your post can and will be removed without further warning. Code is to be formatted as code block (old reddit: empty line before the code, each code line indented by 4 spaces, new reddit: https://i.imgur.com/EJ7tqek.png ) or linked via an external code hoster, like pastebin.com, github gist, github, bitbucket, gitlab, etc. Please, do not use triple backticks (```) as they will only render properly on new reddit, not on old reddit. Code blocks look like this: public class HelloWorld { public static void main(String[] args) { System.out.println("Hello World!"); } } You do not need to repost unless your post has been removed by a moderator. Just use the edit function of reddit to make sure your post complies with the above. If your post has remained in violation of these rules for a prolonged period of time (at least an hour), a moderator may remove it at their discretion. In this case, they will comment with an explanation on why it has been removed, and you will be required to resubmit the entire post following the proper procedures. To potential helpers Please, do not help if any of the above points are not met, rather report the post. We are trying to improve the quality of posts here. In helping people who can't be bothered to comply with the above points, you are doing the community a disservice. I am a bot, and this action was performed automatically. Please contact the moderators of this subreddit if you have any questions or concerns. More on reddit.com
🌐 r/javahelp
10
1
December 1, 2023
java - Parsing a date using DateTimeFormatter ofPattern - Stack Overflow
I've tried different variations in the ofPattern, such as trying to escape the T by surrounding it with single quotes (as done above), and doing the same with the . and I've tried escaping both at the same time. ... Appreciate any help with this. ... DateTimeFormatter f = DateTimeFormatter... More on stackoverflow.com
🌐 stackoverflow.com
Convert date regardless of incoming pattern - Mirth Community
with (JavaImporter(java.time.ZonedDateTime, java.time.ZoneId, java.time.format.DateTimeFormatter)) { msg.MSH['MSH.7'] = ZonedDateTime.now(ZoneId.of('America/Los_Angeles')).format(DateTimeFormatter.ofPattern('yyyyMMddHHmmssSSS')); } This should respect daylight savings, too, if your Java is ... More on forums.mirthproject.io
🌐 forums.mirthproject.io
September 14, 2018
🌐
How to do in Java
howtodoinjava.com › home › java date time › java datetimeformatter (with examples)
Java DateTimeFormatter (with Examples)
June 11, 2024 - DateTimeFormatter customFormatter = DateTimeFormatter.ofLocalizedDateTime( FormatStyle.LONG ); We can supply a custom pattern built with pattern characters such as ‘uuuu-MMM-dd‘ and use ofPattern() method to create a new instance.
Top answer
1 of 3
4

Update

I understood from you that you are using the API as follows:

apiClient.getJSON().setOffsetDateTimeFormat(DateTimeFormatter); 

and you do not have a parameter to pass timezone information. In this case, you can use DateTimeFormatter#withZone as shown below:

import java.time.OffsetDateTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.util.Locale;

public class Main {
    public static void main(String[] args) {
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("uuuuMMddHHmmss", Locale.ENGLISH)
                                        .withZone(ZoneOffset.UTC);

        OffsetDateTime odt = OffsetDateTime.parse("20210817132649", formatter);

        System.out.println(odt);
    }
}

Output:

2021-08-17T13:26:49Z

ONLINE DEMO

i.e. now, your call will be:

DateTimeFormatter formatter = DateTimeFormatter.ofPattern("uuuuMMddHHmmss", Locale.ENGLISH)
                                .withZone(ZoneOffset.UTC);

apiClient.getJSON().setOffsetDateTimeFormat(formatter); 

Original answer

Your date-time string does not have a timezone offset. Parse it into a LocalDateTime and then apply the offset to it.

Demo:

import java.time.LocalDateTime;
import java.time.OffsetDateTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.util.Locale;

public class Main {
    public static void main(String[] args) {
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("uuuuMMddHHmmss", Locale.ENGLISH);
        
        OffsetDateTime odt = LocalDateTime.parse("20210817132649", formatter)
                                .atOffset(ZoneOffset.UTC);
        
        System.out.println(odt);
    }
}

Output:

2021-08-17T13:26:49Z

ONLINE DEMO

The Z in the output is the timezone designator for zero-timezone offset. It stands for Zulu and specifies the Etc/UTC timezone (which has the timezone offset of +00:00 hours). You can specify a different timezone offset (e.g. ZoneOffset.of("+05:30")) as per your requirement.

In case you have ZoneId available

If you have ZoneId available, you should parse the given date-time string into a LocalDateTime and then apply the ZoneId to it to get a ZonedDateTime from which you can always obtain an OffsetDateTime. The best thing about a ZonedDateTime is that it has been designed to adjust the timezone offset automatically whereas an OffsetDateTime is used to represent a fixed timezone offset.

Demo:

import java.time.LocalDateTime;
import java.time.OffsetDateTime;
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) {
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("uuuuMMddHHmmss", Locale.ENGLISH);

        ZonedDateTime zdt = LocalDateTime.parse("20210817132649", formatter)
                                .atZone(ZoneId.of("Etc/UTC"));

        OffsetDateTime odt = zdt.toOffsetDateTime();

        System.out.println(odt);
    }
}

Output:

2021-08-17T13:26:49Z

ONLINE DEMO

You can specify a different ZoneId(e.g. ZoneId.of("Asia/Kolkata")) as per your requirement.

Learn more about the modern Date-Time API* from Trail: Date Time.


* If you are working for an Android project and your Android API level is still not compliant with Java-8, check Java 8+ APIs available through desugaring. Note that Android 8.0 Oreo already provides support for java.time.

2 of 3
2

Well, the string you passed in does not contain zone information, while an OffsetDateTime requires zone information.

So you'll have to set a value for it.

You could use the DateTimeFormatterBuilder class, which then can be instructed to use some default value if a field is missing from the parsed information:

DateTimeFormatter formatter = new DateTimeFormatterBuilder()
    .parseDefaulting(ChronoField.OFFSET_SECONDS, 0)
    .appendPattern("yyyyMMddHHmmss")
    .toFormatter(Locale.ROOT);

You could also directly set an implied zone to the DateTimeFormatter:

DateTimeFormatter.ofPattern("yyyyMMddHHmmss").withZone(ZoneOffset.UTC);
🌐
w3resource
w3resource.com › java-exercises › datetime › java-datetime-exercise-45.php
Java - Print yyyy-MM-dd, HH:mm:ss in various format
May 19, 2025 - import java.text.SimpleDateFormat; import java.time.LocalDate; import java.time.LocalDateTime; import java.time.LocalTime; import java.time.OffsetDateTime; import java.time.ZonedDateTime; import java.time.OffsetTime; import java.time.format.DateTimeFormatter; import java.util.Date; public class Main { public static void main(String[] args) { String result; //yyyy-MM-dd LocalDate localDate = LocalDate.now(); DateTimeFormatter formatterLocalDate = DateTimeFormatter.ofPattern("yyyy-MM-dd"); result = formatterLocalDate.format(localDate); System.out.println("\nyyyy-MM-dd: " + result); // HH:mm:ss L
🌐
Oracle
docs.oracle.com › en › java › javase › 17 › docs › api › java.base › java › time › format › DateTimeFormatter.html
DateTimeFormatter (Java SE 17 & JDK 17)
January 20, 2026 - A pattern is used to create a Formatter using the ofPattern(String) and ofPattern(String, Locale) methods. For example, "d MMM uuuu" will format 2011-12-03 as '3 Dec 2011'. A formatter created from a pattern can be used as many times as necessary, it is immutable and is thread-safe.
🌐
Reddit
reddit.com › r/javahelp › is it possible to format dates in format yyyymmddhhmmsssss and yyyymmddhhmmss with a single datetimeformatter?
r/javahelp on Reddit: Is it possible to format dates in format yyyyMMddHHmmssSSS and yyyyMMddHHmmss with a single DateTimeFormatter?
December 1, 2023 -

I receive dates in 2 formats (yyyyMMddHHmmssSSS and yyyyMMddHHmmss) from a system and I have to parse them based on the format. I tried different ways however, they are failing. Following is what I tried.

  1. DateTimeFormatter formatter = DateTimeFormatter.ofPattern("[yyyyMMddHHmmss][SSS]")

  2. DateTimeFormatter formatter = new DateTimeFormatterBuilder()
    .appendPattern("yyyyMMddHHmmss")
    .optionalStart()
    .appendPattern("SSS")
    .optionalEnd()
    .toFormatter();
    Both these formatters can parse 20220114123456 but not 20220114123456000.
    The easy way would be 2 create 2 different formatters and based on the length of the input, use the appropriate formatter. I am looking for a better solution. Is it possible to do it using a single DateTimeFormatter ?
    It can be done with SDF, but since it's not thread-safe, we don't use it in our project anymore.

🌐
Bug Database
bugs.java.com › bugdatabase › view_bug
Bug ID: JDK-8138676 Failed to format a datetime using a specific format
---------- BEGIN SOURCE ---------- import java.time.format.DateTimeFormatter; import java.time.LocalDateTime; public class TestLocalDataTimeFormat { public static void main(String[] args) { LocalDateTime now = LocalDateTime.now(); DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMddHHmmssSSS"); String date = formatter.format(now); System.out.println("date to parse: "+now); LocalDateTime.parse(date, formatter); // throws an exception } } ---------- END SOURCE ---------- CUSTOMER SUBMITTED WORKAROUND : use the following format (mind the '.'): "yyyyMMddHHmmss.SSS" LocalDateTime.parse("20150910121314987", DateTimeFormatter.ofPattern("yyyyMMddHHmmss.SSS")) or alternatively use jodatime library
Find elsewhere
🌐
Quora
quora.com › How-do-you-get-a-yyyy-mm-dd-format-in-Java
How to get a yyyy-mm-dd format in Java - Quora
DateTimeFormatter myFormatObj = DateTimeFormatter.ofPattern("E, MMMM dd, yyyy ' at' HH:mm:ss 'IST'");
🌐
OpenJDK
bugs.openjdk.org › browse › JDK-8038486
[JDK-8038486] DateTimeFormatter requires a PERIOD ...
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM : This code works: String input = "20111203123456"; DateTimeFormatter formatter = DateTimeFormatter.ofPattern( "yyyyMMddHHmmss"); LocalDateTime localDateTime = LocalDateTime.parse( input, formatter ); Rendering: 2011-12-03T12:34:56 But when adding the ...
🌐
Baeldung
baeldung.com › home › java › java dates › guide to datetimeformatter
Guide to DateTimeFormatter | Baeldung
March 26, 2025 - Suppose we want to present a java.time.LocalDate object using a regular European format like 31.12.2018. To do this, we could call the factory method DateTimeFormatter.ofPattern(“dd.MM.yyyy”).
🌐
ConcretePage
concretepage.com › java › java-8 › java-datetimeformatter
Java DateTimeFormatter
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MMM-dd HH:mm:ss"); LocalDateTime ldt = LocalDateTime.parse("2018-Dec-20 08:25:30", dtf); System.out.println(ldt); Output ...
🌐
myCompiler
mycompiler.io › view › FtOesSGa35u
DateTimeFormatter optional (Java) - myCompiler
import java.time.*; import ... DateTimeFormatter.ofPattern("yyyyMMddHHmm"))); System.out.println(LocalDateTime.parse("19690716113343", DateTimeFormatter.ofPattern("yyyyMMddHHmmss"))); // optional seconds System.out.println(LocalDateTime.parse("19690716 1132", DateTimeFormatte...
🌐
Java67
java67.com › 2019 › 01 › 10-examples-of-format-and-parse-dates-in-java.html
10 Examples to DateTimeFormatter in Java 8 to Parse, Format LocalDate and LocalTime | Java67
June 16, 2016 - DateTimeFormatter americanDateFormat = DateTimeFormatter.ofPattern("MM-dd-yyyy"); String americanDate = now.format(americanDateFormat); System.out.println("USA date format : " + americanDate); Output USA date format: 06-16-2016 The bottom line is as long as you understand the Date and Time formatting instruction, you can define any pattern to formate date.
🌐
OpenJDK
bugs.openjdk.org › browse › JDK-8213027
[JDK-8213027] DateTimeFormatter fails on parsing " ...
ACTUAL - An exception is thrown: java.time.format.DateTimeParseException: Text '20180215062445678 Europe/Vienna' could not be parsed at index 0 ---------- BEGIN SOURCE ---------- @Test void itShouldNotFail() { ZonedDateTime.parse("20180215062445678 Europe/Vienna", DateTimeFormatter.ofPattern("yyyyMMddHHmmssSSS z")); } ---------- END SOURCE ---------- CUSTOMER SUBMITTED WORKAROUND : Joda time works fine with this pattern.
🌐
Mirth Community
forums.mirthproject.io › home › mirth connect › support
Convert date regardless of incoming pattern - Mirth Community
September 14, 2018 - with (JavaImporter(java.time.ZonedDateTime, java.time.ZoneId, java.time.format.DateTimeFormatter)) { msg.MSH['MSH.7'] = ZonedDateTime.now(ZoneId.of('America/Los_Angeles')).format(DateTimeFormatter.ofPattern('yyyyMMddHHmmssSSS')); } This should respect daylight savings, too, if your Java is up to date.
🌐
Java2s
java2s.com › example › java-api › java › time › format › datetimeformatter › ofpattern-1-27.html
Example usage for java.time.format DateTimeFormatter ofPattern
String existingDate = clashingThursdayRule.getBooking().getDate(); String newDate = LocalDate.parse(existingDate, DateTimeFormatter.ofPattern("yyyy-MM-dd")).minusWeeks(1) .format(DateTimeFormatter.ofPattern("yyyy-MM-dd")); clashingThursdayRule.getBooking().setDate(newDate); // ACT doTestCreateRuleClashesOrNotWithExistingRule(clashingThursdayRule, true); }
🌐
Mkyong
mkyong.com › home › java8 › java 8 – how to format localdatetime
Java 8 - How to format LocalDateTime - Mkyong.com
November 9, 2016 - package com.mkyong.time; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; public class TestDate1 { public static void main(String[] args) { //Get current date time LocalDateTime now = LocalDateTime.now(); System.out.println("Before : " + now); DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); String formatDateTime = now.format(formatter); System.out.println("After : " + formatDateTime); } }
🌐
Stack Overflow
stackoverflow.com › questions › tagged › datetimeformatter
Newest 'datetimeformatter' Questions - Page 2 - Stack Overflow
Java version: 1.8.0_202 see code below: DateTimeFormatter yy = DateTimeFormatter.ofPattern("yy"); DateTimeFormatter yyy = new DateTimeFormatterBuilder() .appendValueReduced(... java · datetimeformatter · Guo · 1,823 asked Jan 10, 2024 at 2:46 · 1 vote · 2 answers ·