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

Overview

ThreeTen backport project

JSR-310 provides a new date and time library for Java SE 8. This project is the backport to Java SE 6 and 7.

See the main home page of the project.

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. The backport should be referred to using the "ThreeTen" name.

Active development on JSR-310 is at OpenJDK:

This GitHub repository is a fork of that originally used to create JSR-310. That repository used the same BSD 3-clause license as this repository.

Issues about the backport should be reported here at GitHub. 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.

Building

This project builds using maven.

Time-zone data

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). Updating the time-zone database involves using the TzdbZoneRulesCompiler class and re-compiling the jar file. An automated CI job should help keep the time-zone data up to date.

FAQs

  1. What version of Java SE 8 does this project map to? This project currently maps to the contents of release Java SE 8u20.

  2. Will the backport be kept up to date? There are no plans for further releases. However if security issues or bugs are found, or pull requests received then a release may occur.

  3. Is this project derived from OpenJDK? No. This project is derived from the Reference Implementation previously hosted on GitHub. That project had a BSD license, which has been preserved here. Thus, this project is a fork of the original code before entry to OpenJDK.

Releases

Available in the Maven Central repository

Tidelift dependency check

Support

Please use Stack Overflow for general usage questions. GitHub issues and pull requests should be used when you want to help advance the project. Commercial support is available via the Tidelift subscription.

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

Pull requests must not be copied from the JDK, because the GPL license is incompatible with the BSD license used here.

To report a security vulnerability, please use the Tidelift security contact. Tidelift will coordinate the fix and disclosure.

Release process

  • Update version (index.md, changes.xml - checking tzdb version)
  • Commit and push
  • Run mvn clean release:clean release:prepare release:perform on Java 11
  • Website will be built and released by GitHub Actions
Comments
  • Date formatting fails on some Android devices

    Date formatting fails on some Android devices

    I haven't been able to reproduce this myself, but I am getting reports from the wild that sometimes LocalDate.format() is returning an invalid result on some Android devices. (Using https://github.com/JakeWharton/ThreeTenABP.)

    Here's what happens, as confirmed by the log call in this method.

    • On entry to this method, month is 2016-08.
    • startOfMonth is correctly set to 2016-08-01.
    • monthString gets set to 0000-00-00 which is wrong.
    private Observable<Void> ensureDataForMonthExistsInternal(YearMonth month) {
        final LocalDate startOfMonth = month.atDay(1);
        final String    monthString  = startOfMonth.format(DateTimeFormatter.ISO_LOCAL_DATE);
        Timber.i("Calling ensureDataForMonthExists with month %s, as date %s, formatted %s", month, startOfMonth, monthString);
    

    So far the issue seems to affect only Motorola devices running Android 6.0.

    Does threetenbp actually use possibly-broken system APIs for date formatting? Or is it completely self-contained? Intuitively, my expectation is that using DateTimeFormatter.ISO_LOCAL_DATE should not require the locale or any other information to be read from the system.

    This was originally reported as https://github.com/JakeWharton/ThreeTenABP/issues/33.

    Discussion 
    opened by GrahamBorland 18
  • Add insight into dual initialization errors

    Add insight into dual initialization errors

    Complex applications making use of a custom initializer occasionally run into issues where the implicit static initialization has been called before the explicit one has had a chance to run. Of course the solution is to ensure that the custom initializer is set up before anything else happens in the process, but in large codebases accomplishing this is sometimes more complex than it should be, and references to ThreeTenBP that trigger ZoneRulesProvider can sometimes slip through earlier in the startup sequence. When that happens, an "Already initialized" crash happens at the intentional explicit setInitializer call, but it is difficult to find the source of the implicit initialization. I propose on any initializer set, implicit or explicit, keep track of the stack trace so that a potential future "Already initialized" error can include the stack trace of the earlier call.

    My proposal is to update AtomicReference<ZoneRulesInitializer> INITIALIZER to store both a ZoneRulesInitializer as well as a StackTraceElement[]. For completeness, maybe also replace AtomicBoolean INITIALIZED with an AtomicReference<StackTraceElement[]>, to keep track of both setInitializer and initialize calls as both can later cause issues. When the IllegalStateExceptions are thrown, add a new exception as its cause with the stack trace set to the appropriate saved one. It might even be best to include both in the case of duplicate initialization, where the IllegalStateException would be caused by the duplicate initialization exception which would be caused by the set initializer stack trace (if it exists).

    Thoughts? This is something I can put into code form if it seems like the appropriate approach to this problem.

    Discussion 
    opened by mmallozzi 10
  • org.threeten.bp.zone.ZoneRulesException: Unknown time-zone ID: Asia/Hanoi

    org.threeten.bp.zone.ZoneRulesException: Unknown time-zone ID: Asia/Hanoi

    Originally reported here: https://github.com/JakeWharton/ThreeTenABP/issues/41

    Version:

    1.0.3

    Exception:

    org.threeten.bp.zone.ZoneRulesException: Unknown time-zone ID: Asia/Hanoi
        at org.threeten.bp.zone.ZoneRulesProvider.getProvider(ZoneRulesProvider.java:178)
        at org.threeten.bp.zone.ZoneRulesProvider.getRules(ZoneRulesProvider.java:133)
        at org.threeten.bp.ZoneRegion.ofId(ZoneRegion.java:143)
        at org.threeten.bp.ZoneId.of(ZoneId.java:357)
        at org.threeten.bp.ZoneId.of(ZoneId.java:285)
        at org.threeten.bp.ZoneId.systemDefault(ZoneId.java:244)
        at<>.(DateAgoFormatter.java:45)
        at <>.(ThreadCardViewCreator.java:533)
        at <>.(ThreadCardViewCreator.java:324)
        at <>.(ThreadCardViewCreator.java:283)
        at <>.(ThreadCardViewCreator.java:71)
        at <>.(Card.java:30)
        at <>.(BaseFeedAdapter.java:91)
        at android.widget.HeaderViewListAdapter.getView(HeaderViewListAdapter.java)
        at android.widget.AbsListView.obtainView(AbsListView.java)
        at android.widget.ListView.makeAndAddView(ListView.java)
        at android.widget.ListView.fillDown(ListView.java)
        at android.widget.ListView.fillFromTop(ListView.java)
        at android.widget.ListView.layoutChildren(ListView.java)
        at android.widget.AbsListView.onLayout(AbsListView.java)
        at android.view.View.layout(View.java)
        at android.view.ViewGroup.layout(ViewGroup.java)
        at android.widget.FrameLayout.layoutChildren(FrameLayout.java)
        at android.widget.FrameLayout.onLayout(FrameLayout.java)
        at android.view.View.layout(View.java)
        at android.view.ViewGroup.layout(ViewGroup.java)
        at android.widget.FrameLayout.layoutChildren(FrameLayout.java)
        at android.widget.FrameLayout.onLayout(FrameLayout.java)
        at android.view.View.layout(View.java)
        at android.view.ViewGroup.layout(ViewGroup.java)
        at android.support.v4.widget.SwipeRefreshLayout.onLayout(SwipeRefreshLayout.java:598)
        at android.view.View.layout(View.java)
        at android.view.ViewGroup.layout(ViewGroup.java)
        at android.widget.FrameLayout.layoutChildren(FrameLayout.java)
        at android.widget.FrameLayout.onLayout(FrameLayout.java)
        at android.view.View.layout(View.java)
        at android.view.ViewGroup.layout(ViewGroup.java)
        at android.support.design.widget.HeaderScrollingViewBehavior.layoutChild(HeaderScrollingViewBehavior.java:122)
        at android.support.design.widget.ViewOffsetBehavior.onLayoutChild(ViewOffsetBehavior.java:42)
        at android.support.design.widget.AppBarLayout$ScrollingViewBehavior.onLayoutChild(AppBarLayout.java:1192)
        at android.support.design.widget.CoordinatorLayout.onLayout(CoordinatorLayout.java:814)
        at android.view.View.layout(View.java)
        at android.view.ViewGroup.layout(ViewGroup.java)
        at android.support.v4.widget.DrawerLayout.onLayout(DrawerLayout.java:1191)
        at android.view.View.layout(View.java)
        at android.view.ViewGroup.layout(ViewGroup.java)
        at android.widget.FrameLayout.layoutChildren(FrameLayout.java)
        at android.widget.FrameLayout.onLayout(FrameLayout.java)
        at android.view.View.layout(View.java)
        at android.view.ViewGroup.layout(ViewGroup.java)
        at android.widget.FrameLayout.layoutChildren(FrameLayout.java)
        at android.widget.FrameLayout.onLayout(FrameLayout.java)
        at android.view.View.layout(View.java)
        at android.view.ViewGroup.layout(ViewGroup.java)
        at android.widget.FrameLayout.layoutChildren(FrameLayout.java)
        at android.widget.FrameLayout.onLayout(FrameLayout.java)
        at android.view.View.layout(View.java)
        at android.view.ViewGroup.layout(ViewGroup.java)
        at android.widget.LinearLayout.setChildFrame(LinearLayout.java)
        at android.widget.LinearLayout.layoutVertical(LinearLayout.java)
        at android.widget.LinearLayout.onLayout(LinearLayout.java)
        at android.view.View.layout(View.java)
        at android.view.ViewGroup.layout(ViewGroup.java)
        at android.widget.FrameLayout.layoutChildren(FrameLayout.java)
        at android.widget.FrameLayout.onLayout(FrameLayout.java)
        at android.view.View.layout(View.java)
        at android.view.ViewGroup.layout(ViewGroup.java)
        at android.view.ViewRootImpl.performLayout(ViewRootImpl.java)
        at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java)
        at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java)
        at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java)
        at android.view.Choreographer$CallbackRecord.run(Choreographer.java)
        at android.view.Choreographer.doCallbacks(Choreographer.java)
        at android.view.Choreographer.doFrame(Choreographer.java)
        at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java)
        at android.os.Handler.handleCallback(Handler.java)
        at android.os.Handler.dispatchMessage(Handler.java)
        at android.os.Looper.loop(Looper.java)
        at android.app.ActivityThread.main(ActivityThread.java)
        at java.lang.reflect.Method.invoke(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:372)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java)
    
    WontFix NotABug 
    opened by jaredsburrows 10
  • Backport bugs from OpenJDK

    Backport bugs from OpenJDK

    This branch contains test cases for three bugs reported at OpenJDK. I've written new tests but I can't really write the code that fixes them as I would be using knowledge of GPL code to do so. Looking for someone to take on this issue.

    Bug 
    opened by jodastephen 10
  • incorrect result of dayOfWeek.getDisplayName(TextStyle.NARROW, Locale.getDefault())

    incorrect result of dayOfWeek.getDisplayName(TextStyle.NARROW, Locale.getDefault())

    Thanks your library help to develop, but I find an exception when I used "LocalDate.now().dayOfWeek.getDisplayName(TextStyle.NARROW or STANDALONG, Locale.getDefault())". My Location and device region is China, System language is Chinese. For example, today is Wednesday, the correct result should be “三” (third) instead of "星" and other day's result is "星" which should be "一、二、三...". When I set locale to US, the result is "W", it's right.

    Bug Fixed 
    opened by VinsonGuo 9
  • Make zone rules initialization configurable and pluggable

    Make zone rules initialization configurable and pluggable

    Preserves the default behavior of obtaining a ZoneRulesProvider instance from ServiceLoader, but adds the ability to substitute in different initialization code that will be executed in the static block of ZoneRulesProvider the first time that time zone rules are needed.

    A more flexible replacement for https://github.com/ThreeTen/threetenbp/pull/64.

    RFE Fixed 
    opened by mmallozzi 9
  • no-tzdb should exclude ServiceLoader code from ZoneRulesProvider

    no-tzdb should exclude ServiceLoader code from ZoneRulesProvider

    When the timezone DB isn't included in the JAR, the code to look for it and load it with ServiceLoader should be removed from the static initializer block of ZoneRulesProvider. Apparently ServiceLoader is extremely slow on Android even if there are no implementations loaded (since no-tzdb already handles removing the META-INF entry), and it's not needed when the code isn't bundled with a tzdb.

    I was trying to figure out some Maven incantation to exclude this version of the class and include an alternate version that removes the static initializer block, but I've never used Maven before so I'm lost :)

    RFE Fixed 
    opened by mmallozzi 9
  • How to get a unique value out of LocalDate instance?

    How to get a unique value out of LocalDate instance?

    I need to differentiate between LocalDate instances by a long/int value. This is useful in this case, for example: https://developer.android.com/reference/android/support/v7/widget/RecyclerView.Adapter.html#getItemId(int)

    I was told that hashCode isn't good enough: https://github.com/ThreeTen/threetenbp/issues/81

    What can I do instead?

    Discussion 
    opened by AndroidDeveloperLB 8
  • Backport of fix for bug 8033662

    Backport of fix for bug 8033662

    Hi,

    Was the fix for https://bugs.openjdk.java.net/browse/JDK-8033662 backported to threetenbp? I seem to experience this bug with threetenbp 0.9.

    Thanks, Viktor

    Bug Fixed 
    opened by phraktle 8
  • Allow custom DateTimeTextProvider to be set as default

    Allow custom DateTimeTextProvider to be set as default

    This can solve #69 Dependent libraries can use DateTimeTextProvider.setInstance() to set their implementation of DateTimeTextProvider as default. As a side effect, if default instance is not set explicitly, only one instance of SimpleDateTimeTextProvider will be created.

    RFE Fixed 
    opened by pamalyshev 6
  • Consider TzdbZoneRulesProvider InputStream factory/ctor?

    Consider TzdbZoneRulesProvider InputStream factory/ctor?

    For the Android support, and in addition to the work towards #29, I need to load the TZDB.dat from an alternative location. Right now I have to duplicate the entirety of TzdbZoneRulesProvider in my own class but inside of the org.threeten.bp.zone package for access to Ser (and its transitive dependencies). It would be of great convenience if TzdbZoneRulesProvider had either a static factory or constructor overload that accepted an InputStream for reading of its data.

    RFE Fixed 
    opened by JakeWharton 6
  • Caused by org.threeten.bp.zone.ZoneRulesException: Unknown time-zone ID: Europe/Kyiv

    Caused by org.threeten.bp.zone.ZoneRulesException: Unknown time-zone ID: Europe/Kyiv

    org.threeten.bp.zone.ZoneRulesException: Unknown time-zone ID: Europe/Kyiv at android.app.ActivityThread.handleReceiver(ActivityThread.java:4233) at android.app.ActivityThread.access$1800(ActivityThread.java:274) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2109) at android.os.Handler.dispatchMessage(Handler.java:106) at android.os.Looper.loop(Looper.java:233) at android.app.ActivityThread.main(ActivityThread.java:8063) at java.lang.reflect.Method.invoke(Method.java) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:631) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:978)

    Caused by org.threeten.bp.zone.ZoneRulesException: Unknown time-zone ID: Europe/Kyiv at org.threeten.bp.zone.ZoneRulesProvider.getProvider(ZoneRulesProvider.java:167) at org.threeten.bp.zone.ZoneRulesProvider.getRules(ZoneRulesProvider.java:122) at org.threeten.bp.ZoneRegion.ofId(ZoneRegion.java:143) at org.threeten.bp.ZoneId.of(ZoneId.java:358) at org.threeten.bp.ZoneId.of(ZoneId.java:286) at org.threeten.bp.ZoneId.systemDefault(ZoneId.java:245) at org.threeten.bp.Clock.systemDefaultZone(Clock.java:137) at org.threeten.bp.LocalDateTime.now(LocalDateTime.java:152)

    Discussion 
    opened by nAkhmedov 3
  • DateTimeFormatter doesn't follow locale when using QQQQ pattern

    DateTimeFormatter doesn't follow locale when using QQQQ pattern

    This code using 1.6.1 version of threetenbp:

     org.threeten.bp.LocalDate
            .of(2020, 1, 1)
            .format(org.threeten.bp.format.DateTimeFormatter.ofPattern("QQQQ", Locale.FRANCE))
    

    outputs: 1st quarter

    And then the same code using Java 11 implementation it outputs the correct format:

        java.time.LocalDate
            .of(2020, 1, 1)
            .format(java.time.format.DateTimeFormatter.ofPattern("QQQQ", Locale.FRANCE))
    

    outputs: 1er trimestre

    The outputs should be also localized with threetenbp.

    RFE 
    opened by xatok 1
  • DateTimeFormatter for HijrahChronology

    DateTimeFormatter for HijrahChronology

    DateTimeFormatter giving different results;

    val formatter = DateTimeFormatter.ofPattern("MMMM - yyyy").withChronology(HijrahChronology.INSTANCE); val now = HijrahChronology.INSTANCE.date(LocalDate.of(2022, 8, 29)); println(formatter.format(now))

    The result is February 1444; Actually it should be Safar 1444;

    I tested code like above with java.time.DateTimeFormatter and it worked as expected.

    RFE 
    opened by Khudoyshukur 1
  • Incorrect DayOfWeek Translation for Chinese Variations

    Incorrect DayOfWeek Translation for Chinese Variations

    Similar to the issue raised in #97, the fix given only works if the user's device is in zh-CH. However, when a user is using a variation of Chinese like zh-TW or zh-HK the incorrect DayOfWeek translation for SHORT reappears, displaying "星" instead of "一、二、三...".

    RFE 
    opened by jfong99 1
  • Backport stutter typo fix

    Backport stutter typo fix

    https://github.com/AdoptOpenJDK/openjdk-jdk/commit/08eb67b941ee4f9a490fc17535bc0c9209b91071#diff-c638e872b60894dedf26ea7893bf9e54d191d8fa2036a741d93c38b708c7ad52

    Bug 
    opened by gabrieljones 1
Releases(v1.6.5)
Owner
ThreeTen
Supporting projects for JSR-310 dates and times in Java
ThreeTen
Joda-Time is the widely used replacement for the Java date and time classes prior to Java SE 8.

Joda-Time Joda-Time provides a quality replacement for the Java date and time classes. The design allows for multiple calendar systems, while still pr

Joda.org 4.9k Dec 27, 2022
A Java library for parsing and building iCalendar data models

iCal4j - iCalendar parser and object model Table of Contents Introduction - What is iCal4j? Setup - Download and installation of iCal4j System require

iCal4j 637 Jan 5, 2023
This is a picker view for android , support linkage effect, timepicker and optionspicker

This is a picker view for android , support linkage effect, timepicker and optionspicker

Bigkoo 13.2k Jan 3, 2023
Backport of Java 8's lambda expressions to Java 7, 6 and 5

Retrolambda: Use Lambdas on Java 7 Just as there was Retroweaver et al. for running Java 5 code with generics on Java 1.4, Retrolambda lets you run Ja

Esko Luontola 3.5k Dec 30, 2022
Lightweight dependency injection for Java and Android (JSR-330)

About Feather Feather is an ultra-lightweight dependency injection (JSR-330) library for Java and Android. Dependency injection frameworks are often p

Zsolt Herpai 341 Nov 29, 2022
Evgeniy Khyst 54 Dec 28, 2022
Presti 5 Nov 19, 2022
An API Library that provides the functionality to access, manage and store device topologies found in JSON files using Java and Maven Framework

Topology API ?? About An API library which provides the functionality to access, manage and store device topologies. ?? Description Read a topology fr

Abdelrahman Hamdy 2 Aug 4, 2022
Blazed Café is a library for BlazeOS that enables and improves Java functionality for the IgniteBook platform.

By: Seanpm2001, Et; Al. Top README.md Read this article in a different language Sorted by: A-Z Sorting options unavailable ( af Afrikaans Afrikaans |

Sean P. Myrick V19.1.7.2 2 Sep 5, 2022
Provides some Apple Wallet functionality, like adding passes, removing passes and checking passises for existing.

react-native-wallet-manager Provides some Apple Wallet's functionality, like adding passes, removing passes and checking passises for existing. Instal

dev.family 50 Nov 12, 2022
TopologyAPI provides the functionality to access, manage and store device topologies.

TopologyAPI Providing the functionality to access, manage and store device topologies, given different json files each includes one topology, storing

Islam Walid 3 Mar 31, 2022
Core ORMLite functionality that provides a lite Java ORM in conjunction with ormlite-jdbc or ormlite-android

ORMLite Core This package provides the core functionality for the JDBC and Android packages. Users that are connecting to SQL databases via JDBC shoul

Gray 547 Dec 25, 2022
Sparkling Water provides H2O functionality inside Spark cluster

Sparkling Water Sparkling Water integrates H2O's fast scalable machine learning engine with Spark. It provides: Utilities to publish Spark data struct

H2O.ai 939 Jan 2, 2023
Hibernate's core Object/Relational Mapping functionality

Hibernate ORM is a library providing Object/Relational Mapping (ORM) support to applications, libraries, and frameworks. It also provides an implement

Hibernate 5.2k Jan 9, 2023
An experimental mod that converts some block entities to blockstates. This is done for performance & functionality reasons.

BetterBlockStates An experimental mod that converts some block entities to blockstates. This is done for performance & functionality reasons. Current

Fx Morin 10 Sep 17, 2022
Nagram is a third-party Telegram client based on Nekogram with not many but useful modifications

?? Nagram is a third-party Telegram client based on Nekogram with not many but useful modifications. Official site: https://nextalone.xyz Teleg

NextAlone 189 Dec 29, 2022
Pass variables into methods based off name, not position.

Named Arguments are a feature that many languages lack. Some call it Feature Envy. The Problem You have a menu() method that prints out a 5 option men

Xavier D 3 Jul 1, 2022