Library / SDK
ThreeTen/threetenbp avatar
ThreeTen/threetenbp

ThreeTen backport: the JSR-310 date and time API for Java SE 6 and 7

Backport of functionality based on JSR-310 to Java SE 6 and 7. This is NOT an implementation of JSR-310.

567 stars141 forksJavaBSD-3-Clause

At a glance

What is it?
threetenbp is a backport of the Java SE 8 date and time API to Java SE 6 and 7, published to Maven Central as org.threeten:threetenbp and referred to by the ThreeTen name. It is explicitly not an implementation of JSR-310, it freezes the standard at the Java SE 8u20 contents, and the README states there are no plans for further releases.
Who is it for?
ThreeTen backport suits a team still on Java SE 6 or 7 that wants the java.time API without reimplementing it, because the classes match the real Java SE 8 behaviour closely enough that code moves forward unchanged when the platform is upgraded.
Can I use it commercially?
Yes. BSD-3-Clause is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 20 days ago.
What is it written in?
Mainly Java, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

A backport, and the README is careful about the difference

ThreeTen backport exists because JSR-310 provides a new date and time library for Java SE 8, and this project is the backport to Java SE 6 and 7.

What makes this worth reading is how firmly the README refuses to oversell it. The backport is NOT an implementation of JSR-310, as that would require jumping through lots of unnecessary hoops. Instead, this is a simple backport intended to allow users to quickly use the JSR-310 API on Java SE 6 and 7.

That distinction is not pedantry. A full JSR-310 implementation would have to reimplement the whole specification, including the parts that describe behaviour the platform itself provides. A backport takes the API shape and the behaviour and stops there. The result is a library you can depend on for the common cases, not a second implementation of the standard competing with the first.

The naming guidance is in the same paragraph: the backport should be referred to using the ThreeTen name. So in code and in documentation you are using ThreeTen, not JSR-310, and the project treats that as a naming contract rather than a preference.

The provenance is also spelled out. This GitHub repository is a fork of the one originally used to create JSR-310, and that repository used the same BSD-3-Clause license as this one. Active development on JSR-310 itself is at OpenJDK.

So there are two codebases with the same licence and the same shape, one maintained inside the JDK and one maintained here for platforms the JDK no longer supports. The primary language is Java, the licence is BSD-3-Clause with the LICENSE.txt file at the root, and the homepage is threeten.org/threetenbp.

The API is frozen at Java SE 8u20, and that is the contract

The FAQ answers the question that actually determines whether this library fits your project, and the answer is precise.

This project currently maps to the contents of release Java SE 8u20.

That is a specific snapshot of the Java SE 8 date and time API, not a moving target that follows the platform. Any method, overload or behaviour added to java.time after 8u20 is not in the backport.

This matters more than it sounds. The java.time API has continued to gain methods over successive Java releases, and the difference between 8u20 and a recent Java SE 8 or Java SE 9+ release is not empty. If your code only uses the core types, LocalDate, LocalDateTime, Instant, Duration, ZonedDateTime and the like, with the operations that have existed since 8u20, the backport matches what you would get on the platform. If you rely on something added later, it will not be there.

The second FAQ entry sets the maintenance expectation just as explicitly. There are no plans for further releases, however if security issues or bugs are found, or pull requests received then a release may occur.

So the honest characterisation is that this is a maintained-in-place artefact rather than a project on a roadmap. The release history shows what that has meant in practice: v1.7.5 was tagged on 2026-10-03, v1.7.4 on 2026-07-26 and v1.7.3 on 2026-05-08, with the last push to the repository on 2026-10-03. So releases do happen, and the recent ones are recent, but they follow the condition in the FAQ rather than a schedule.

The third FAQ entry clarifies the derivation, which matters for licensing. The project is derived from the Reference Implementation previously hosted on GitHub, that project had a BSD license which has been preserved here, and thus this project is a fork of the original code before entry to OpenJDK. It is not derived from OpenJDK itself, and the distinction is load-bearing for the licensing section below.

Time zone data is a compiled file inside the jar, and updating it is a build step

The time-zone handling is the part of the library with the most operational weight, and the README describes it concretely.

The time-zone database is stored as a pre-compiled dat file that is included in the built jar. The version of the time-zone data used is stored within the dat file, near the start. That is a useful detail: you can determine which tzdb snapshot your jar carries by looking inside the file rather than by guessing from a release date.

Updating the time-zone database involves using the TzdbZoneRulesCompiler class and re-compiling the jar file. The README adds that an automated CI job should help keep the time-zone data up to date.

So the design is a snapshot, deliberately frozen into a binary artefact, with a mechanism for refreshing it. That is a trade. A frozen dat file means your zone rules do not change under you at runtime, which is exactly what you want for a build that has to be reproducible, and it means a zone rule change shipped by the IANA database does not reach you until the jar is rebuilt.

This is also the reason the library is a compiled artefact rather than something assembled from source at your build time. The dat file is a build output of the zone rules compiler, and the jar carries it.

The project builds using maven, and the top level of the repository shows a conventional single-module Maven layout: pom.xml at the root, src/ for the sources, plus README.md, RELEASE-NOTES.md, SECURITY.md, LICENSE.txt and a .github/ directory for the workflows.

The release notes are worth reading before you depend on a particular version, since they are where the tzdb version and any behavioural alignment fixes will be recorded for a library whose main ongoing task is staying aligned with a fixed snapshot of the platform API.

Contributions are accepted only when they match platform behaviour

The contribution policy is the most restrictive thing about this project, and it is stated twice in the README with the same meaning.

Pull requests and issues will only be considered so far as matching the behaviour of the real Java SE 8. Additional requested features will be rejected.

And later: pull requests and issues will only be considered so far as matching the behaviour of Java SE releases. Additional requested features will be rejected.

There is also a licence constraint on the source of contributions. Pull requests must not be copied from the JDK, because the GPL license is incompatible with the BSD license used here.

That last line is a licensing boundary rather than a technical preference, and it is easy to trip over. The JDK is GPL, this project is BSD-3-Clause, and the code in the JDK cannot be pasted in. In practice that means a contribution has to be independently written or derived from the BSD-licensed Reference Implementation.

Taken together, the policy defines what the project is. It is a compatibility surface, not an API design space. New methods, new types, new overloads and behavioural improvements are all out of scope, because the target is a snapshot of an API that already shipped. A contributor's work is essentially a bug fix or an alignment correction.

That makes the project unusually low-churn from a maintainer's perspective, and it tells you something about the ecosystem. Java SE 6 and 7 are long past end of life, so the population that still needs this library is shrinking, and the work that remains is keeping the backport faithful to a fixed point in the platform's history.

Support is routed in the conventional way. Stack Overflow for general usage questions, with the threetenbp tag. GitHub issues and pull requests for helping advance the project. And commercial support is available through a Tidelift subscription, with a dependency check badge in the README.

Getting it and releasing it, and the security reporting path

The artefact is published to Maven Central, and the README links the search for the group org.threeten and the artefact threetenbp, so the coordinates are org.threeten:threetenbp. The README points at the main home page of the project at threeten.org/threetenbp for installation instructions and more complete documentation.

So adding it to a Java SE 6 or 7 build is a normal Maven dependency declaration, and there is nothing unusual about the packaging.

The release process is documented in two forms, and the difference between them matters for anyone maintaining a fork.

The GitHub Actions path updates the version in index.md and changes.xml, checking the tzdb version, then commits and pushes, then pushes the tag.

bash
git push origin HEAD:refs/tags/release

After that, code and website are built and released by GitHub Actions. So the release tag is what drives the build, and the version metadata lives in files outside the source tree.

Releasing from a local machine requires the gpg-agent to be running, and then a single Maven invocation.

bash
mvn clean release:clean release:prepare release:perform

The gpg-agent requirement is the standard Maven release plugin behaviour for signing, and it is called out because it is the kind of thing that fails confusingly when it is not running.

Security vulnerabilities go through Tidelift. To report a security vulnerability, use the Tidelift security contact, and Tidelift will coordinate the fix and disclosure. That is the same organisation providing the commercial support subscription, which is a reasonable arrangement for a project of this size: one paid channel covers both support and coordinated disclosure.

The repository also carries a SECURITY.md file and RELEASE-NOTES.md, and the project has adopted the Microsoft Open Source Code of Conduct and a code of conduct document in the repository.

Where ThreeTen backport is the wrong tool

The first wrong-tool case is a project on Java SE 8 or later. There, java.time is in the platform, with the same API and the same behaviour, maintained by the same OpenJDK project the README points to for active JSR-310 development. Adding a backport to a modern build adds a dependency, a shaded copy of classes whose names collide with the platform's, and a version that lags. The right answer on Java SE 8 is the platform's own package.

The second case is a project that expects the API to grow. The policy is explicit that additional requested features are rejected, and that pull requests are only considered so far as they match the behaviour of the real Java SE 8. If your team plans to lean on later java.time additions, this library will not follow, and the mapping to 8u20 makes that a design decision rather than a bug to report.

The third case is a project that has already outgrown Java SE 6 and 7 but has not finished migrating. This is worth separating from the first case, because the answer differs. If you are on Java 8 but stuck with a dependency tree that still targets 6 or 7, this backport can unblock you without a full upgrade, and the identical API shape means the code you write now works unchanged when you move to the platform's java.time. That is a genuine transitional use, and a good one.

The fourth case is an application that needs current zone rules. The time-zone database is frozen into the jar at build time, so a device in a region whose rules changed after 8u20, or any application that must reflect the latest IANA release without a rebuild, is served poorly by this design. The dat file version is recorded near the start of the file, so you can detect the staleness, but detecting it is not the same as not having it.

There is one operational consequence that follows from the frozen design and is worth checking in your environment: because the library carries its own copy of the zone rules rather than deferring to the platform's, a Java SE 6 or 7 application using this backport and one using the platform's java.time can disagree about a zone rule. For most applications that difference is irrelevant. For software that spans both, such as a shared codebase compiled twice, it is a real inconsistency to think about.

On licence, BSD-3-Clause is about the most permissive grant available and imposes no copyleft obligation on a user, which makes it an unusually easy dependency for commercial use. The licensing constraint worth flagging is the contribution one: the JDK cannot be copied in, so a fork maintained by a commercial team has to write its own fixes rather than lift them from the platform source.

Editorial conclusion

ThreeTen backport suits a team still on Java SE 6 or 7 that wants the java.time API without reimplementing it, because the classes match the real Java SE 8 behaviour closely enough that code moves forward unchanged when the platform is upgraded. It does not suit anyone on Java SE 8 or later, where the built-in java.time package makes the backport redundant, and it does not suit a project that expects new API surface, because pull requests adding features are rejected by policy. Before adopting, check the artefact in Maven Central under the org.threeten group, and read the release notes rather than assuming a recent tag means the API has moved with the platform.

Frequently asked questions

What is ThreeTen backport?

threetenbp is a backport of the Java SE 8 date and time API, provided by JSR-310, to Java SE 6 and 7. The README is explicit that it is not an implementation of JSR-310, but a simple backport so users can quickly use the JSR-310 API on those older platforms.

Which Java SE 8 version does threetenbp map to?

The README states the project currently maps to the contents of release Java SE 8u20. Anything added to java.time after that snapshot is not present in the backport.

Will ThreeTen backport be updated further?

The README says there are no plans for further releases, however if security issues or bugs are found, or pull requests received then a release may occur. Recent tags include v1.7.5 from 2026-10-03, v1.7.4 from 2026-07-26 and v1.7.3 from 2026-05-08.

How do I get threetenbp?

It is published to Maven Central under the group org.threeten and the artefact threetenbp, so it is added as a normal Maven dependency. The project home page at threeten.org/threetenbp carries the installation instructions and fuller documentation.

How is the time zone database handled in threetenbp?

The time-zone database is stored as a pre-compiled dat file included in the built jar, with the version of the data recorded near the start of the file. Updating it involves using the TzdbZoneRulesCompiler class and re-compiling the jar, and an automated CI job helps keep it current.

What license is ThreeTen backport released under?

It is released under the BSD 3-Clause license, with the LICENSE.txt file at the root of the repository. Pull requests must not be copied from the JDK because the GPL license is incompatible with the BSD license used here.

Official sources

  1. License: BSD-3-Clause
  2. Project website
  3. README
  4. Releases
  5. ThreeTen/threetenbp on GitHub
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/threeten-threetenbp.svg)](https://hysenlabs.com/projects/threeten-threetenbp)

Was this useful?