Android NTP time library. Get the true current time impervious to device clock time changes

Overview

TrueTime for Android

TrueTime

Make sure to check out our counterpart too: TrueTime, an NTP library for Swift.

NTP client for Android. Calculate the date and time "now" impervious to manual changes to device clock time.

In certain applications it becomes important to get the real or "true" date and time. On most devices, if the clock has been changed manually, then a new Date() instance gives you a time impacted by local settings.

Users may do this for a variety of reasons, like being in different timezones, trying to be punctual by setting their clocks 5 – 10 minutes early, etc. Your application or service may want a date that is unaffected by these changes and reliable as a source of truth. TrueTime gives you that.

You can read more about the use case in our blog post.

In a recent conference talk, we explained how the full NTP implementation works with Rx. Check the video and slides out for implementation details.

Also, once we have this information it's valid until the next time you boot your device. This means if you enable the disk caching feature, after a single successful NTP request you can use the information on disk directly without ever making another network request. This applies even across application kills which can happen frequently if your users have a memory starved device.

Installation

See the wiki instructions.

Wiki has a lot of useful information

Take a look at the wiki sidebar which should have a lot of useful information.

License

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
Comments
  • Causes ANR and SocketTimeoutException on emulators

    Causes ANR and SocketTimeoutException on emulators

    Simply running the RxTrueTime sample2 on an Android emulator causes java.net.SocketTimeoutException Poll timed out. It's even causing ANR's inside my own project (also on emulators).

    Tried this on 2 separate environments running emulators with different Android versions, they all show the same problem.

    Everything works fine on my real devices.

    Is this expected behavior and can I ignore this or should this actually work?

    Logs:

    
    09-19 16:44:26.899 20496-21765/com.instacart.library.truetime D/TrueTimeRx: ---- resolving ntpHost : time.google.com
    09-19 16:44:26.901 20496-21768/com.instacart.library.truetime D/TrueTimeRx: ---- requestTime from: 216.239.35.8
    09-19 16:44:26.901 20496-21769/com.instacart.library.truetime D/TrueTimeRx: ---- requestTime from: 216.239.35.8
    09-19 16:44:26.901 20496-21770/com.instacart.library.truetime D/TrueTimeRx: ---- requestTime from: 216.239.35.8
    09-19 16:44:26.902 20496-21771/com.instacart.library.truetime D/TrueTimeRx: ---- requestTime from: 216.239.35.8
    09-19 16:44:26.902 20496-21772/com.instacart.library.truetime D/TrueTimeRx: ---- requestTime from: 216.239.35.8
    09-19 16:44:26.902 20496-21773/com.instacart.library.truetime D/TrueTimeRx: ---- requestTime from: 2001:4860:4806:8::
    09-19 16:44:26.903 20496-21774/com.instacart.library.truetime D/TrueTimeRx: ---- requestTime from: 2001:4860:4806:8::
    09-19 16:44:26.903 20496-21775/com.instacart.library.truetime D/TrueTimeRx: ---- requestTime from: 2001:4860:4806:8::
    09-19 16:44:26.903 20496-21776/com.instacart.library.truetime D/TrueTimeRx: ---- requestTime from: 2001:4860:4806:8::
    09-19 16:44:26.903 20496-21777/com.instacart.library.truetime D/TrueTimeRx: ---- requestTime from: 2001:4860:4806:8::
    

    Logs don't continue after that, it just loops forever and showing the SocketTimeoutException + causing the ANR.

    awaiting feedback 
    opened by EdwardvanRaak 22
  • java.net.SocketException: sendto failed: ENETUNREACH (Network is unreachable)

    java.net.SocketException: sendto failed: ENETUNREACH (Network is unreachable)

    I'm getting crashes due to this exceptions.

    this is the full stacktrace :

    Fatal Exception: io.reactivex.exceptions.UndeliverableException: java.net.SocketException: sendto failed: ENETUNREACH (Network is unreachable) at io.reactivex.plugins.RxJavaPlugins.onError(RxJavaPlugins.java:349) at io.reactivex.internal.operators.flowable.FlowableFlatMap$MergeSubscriber.innerError(FlowableFlatMap.java:604) at io.reactivex.internal.operators.flowable.FlowableFlatMap$InnerSubscriber.onError(FlowableFlatMap.java:665) at io.reactivex.internal.operators.flowable.FlowableRetryPredicate$RepeatSubscriber.onError(FlowableRetryPredicate.java:81) at io.reactivex.internal.operators.flowable.FlowableDoOnEach$DoOnEachSubscriber.onError(FlowableDoOnEach.java:110) at io.reactivex.internal.operators.flowable.FlowableSubscribeOn$SubscribeOnSubscriber.onError(FlowableSubscribeOn.java:102) at io.reactivex.internal.operators.flowable.FlowableCreate$BaseEmitter.onError(FlowableCreate.java:268) at io.reactivex.internal.operators.flowable.FlowableCreate$BufferAsyncEmitter.drain(FlowableCreate.java:510) at io.reactivex.internal.operators.flowable.FlowableCreate$BufferAsyncEmitter.onError(FlowableCreate.java:461) at com.instacart.library.truetime.TrueTimeRx$4$1$2.subscribe(TrueTimeRx.java:201) at io.reactivex.internal.operators.flowable.FlowableCreate.subscribeActual(FlowableCreate.java:72) at io.reactivex.Flowable.subscribe(Flowable.java:12986) at io.reactivex.Flowable.subscribe(Flowable.java:12932) at io.reactivex.internal.operators.flowable.FlowableSubscribeOn$SubscribeOnSubscriber.run(FlowableSubscribeOn.java:82) at io.reactivex.internal.schedulers.ScheduledRunnable.run(ScheduledRunnable.java:61) at io.reactivex.internal.schedulers.ScheduledRunnable.call(ScheduledRunnable.java:52) at java.util.concurrent.FutureTask.run(FutureTask.java:237) at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:154) at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:269) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588) at java.lang.Thread.run(Thread.java:818) Caused by java.net.SocketException: sendto failed: ENETUNREACH (Network is unreachable) at libcore.io.IoBridge.maybeThrowAfterSendto(IoBridge.java:542) at libcore.io.IoBridge.sendto(IoBridge.java:511) at java.net.PlainDatagramSocketImpl.send(PlainDatagramSocketImpl.java:184) at java.net.DatagramSocket.send(DatagramSocket.java:305) at com.instacart.library.truetime.SntpClient.requestTime(SntpClient.java:114) at com.instacart.library.truetime.TrueTime.requestTime(TrueTime.java:122) at com.instacart.library.truetime.TrueTimeRx$4$1$2.subscribe(TrueTimeRx.java:197) at io.reactivex.internal.operators.flowable.FlowableCreate.subscribeActual(FlowableCreate.java:72) at io.reactivex.Flowable.subscribe(Flowable.java:12986) at io.reactivex.Flowable.subscribe(Flowable.java:12932) at io.reactivex.internal.operators.flowable.FlowableSubscribeOn$SubscribeOnSubscriber.run(FlowableSubscribeOn.java:82) at io.reactivex.internal.schedulers.ScheduledRunnable.run(ScheduledRunnable.java:61) at io.reactivex.internal.schedulers.ScheduledRunnable.call(ScheduledRunnable.java:52) at java.util.concurrent.FutureTask.run(FutureTask.java:237) at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:154) at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:269) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588) at java.lang.Thread.run(Thread.java:818) Caused by android.system.ErrnoException: sendto failed: ENETUNREACH (Network is unreachable) at libcore.io.Posix.sendtoBytes(Posix.java) at libcore.io.Posix.sendto(Posix.java:211) at libcore.io.BlockGuardOs.sendto(BlockGuardOs.java:278) at libcore.io.IoBridge.sendto(IoBridge.java:509) at java.net.PlainDatagramSocketImpl.send(PlainDatagramSocketImpl.java:184) at java.net.DatagramSocket.send(DatagramSocket.java:305) at com.instacart.library.truetime.SntpClient.requestTime(SntpClient.java:114) at com.instacart.library.truetime.TrueTime.requestTime(TrueTime.java:122) at com.instacart.library.truetime.TrueTimeRx$4$1$2.subscribe(TrueTimeRx.java:197) at io.reactivex.internal.operators.flowable.FlowableCreate.subscribeActual(FlowableCreate.java:72) at io.reactivex.Flowable.subscribe(Flowable.java:12986) at io.reactivex.Flowable.subscribe(Flowable.java:12932) at io.reactivex.internal.operators.flowable.FlowableSubscribeOn$SubscribeOnSubscriber.run(FlowableSubscribeOn.java:82) at io.reactivex.internal.schedulers.ScheduledRunnable.run(ScheduledRunnable.java:61) at io.reactivex.internal.schedulers.ScheduledRunnable.call(ScheduledRunnable.java:52) at java.util.concurrent.FutureTask.run(FutureTask.java:237) at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:154) at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:269) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588) at java.lang.Thread.run(Thread.java:818)

    why is it happening ?

    awaiting feedback 
    opened by elirangoshen 14
  • Fatal Exception: io.reactivex.exceptions.UndeliverableException: java.io.IOException: Operation not permitted

    Fatal Exception: io.reactivex.exceptions.UndeliverableException: java.io.IOException: Operation not permitted

    Recently I started receiving the following crash:

    Fatal Exception: io.reactivex.exceptions.UndeliverableException: java.io.IOException: Operation not permitted
           at io.reactivex.plugins.RxJavaPlugins.onError(RxJavaPlugins.java:349)
           at io.reactivex.internal.operators.flowable.FlowableFlatMap$MergeSubscriber.innerError(FlowableFlatMap.java:604)
           at io.reactivex.internal.operators.flowable.FlowableFlatMap$InnerSubscriber.onError(FlowableFlatMap.java:665)
           at io.reactivex.internal.operators.flowable.FlowableRetryPredicate$RepeatSubscriber.onError(FlowableRetryPredicate.java:81)
           at io.reactivex.internal.operators.flowable.FlowableDoOnEach$DoOnEachSubscriber.onError(FlowableDoOnEach.java:110)
           at io.reactivex.internal.operators.flowable.FlowableSubscribeOn$SubscribeOnSubscriber.onError(FlowableSubscribeOn.java:102)
           at io.reactivex.internal.operators.flowable.FlowableCreate$BaseEmitter.onError(FlowableCreate.java:268)
           at io.reactivex.internal.operators.flowable.FlowableCreate$BufferAsyncEmitter.drain(FlowableCreate.java:510)
           at io.reactivex.internal.operators.flowable.FlowableCreate$BufferAsyncEmitter.onError(FlowableCreate.java:461)
           at com.instacart.library.truetime.TrueTimeRx$4$1$2.subscribe(TrueTimeRx.java:201)
           at io.reactivex.internal.operators.flowable.FlowableCreate.subscribeActual(FlowableCreate.java:72)
           at io.reactivex.Flowable.subscribe(Flowable.java:12986)
           at io.reactivex.Flowable.subscribe(Flowable.java:12932)
           at io.reactivex.internal.operators.flowable.FlowableSubscribeOn$SubscribeOnSubscriber.run(FlowableSubscribeOn.java:82)
           at io.reactivex.internal.schedulers.ScheduledRunnable.run(ScheduledRunnable.java:61)
           at io.reactivex.internal.schedulers.ScheduledRunnable.call(ScheduledRunnable.java:52)
           at java.util.concurrent.FutureTask.run(FutureTask.java:237)
           at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:272)
           at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
           at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
           at java.lang.Thread.run(Thread.java:761)
    Caused by java.io.IOException: Operation not permitted
           at java.net.PlainDatagramSocketImpl.send(PlainDatagramSocketImpl.java)
           at java.net.DatagramSocket.send(DatagramSocket.java:691)
           at com.instacart.library.truetime.SntpClient.requestTime(SntpClient.java:114)
           at com.instacart.library.truetime.TrueTime.requestTime(TrueTime.java:122)
           at com.instacart.library.truetime.TrueTimeRx$4$1$2.subscribe(TrueTimeRx.java:197)
           at io.reactivex.internal.operators.flowable.FlowableCreate.subscribeActual(FlowableCreate.java:72)
           at io.reactivex.Flowable.subscribe(Flowable.java:12986)
           at io.reactivex.Flowable.subscribe(Flowable.java:12932)
           at io.reactivex.internal.operators.flowable.FlowableSubscribeOn$SubscribeOnSubscriber.run(FlowableSubscribeOn.java:82)
           at io.reactivex.internal.schedulers.ScheduledRunnable.run(ScheduledRunnable.java:61)
           at io.reactivex.internal.schedulers.ScheduledRunnable.call(ScheduledRunnable.java:52)
           at java.util.concurrent.FutureTask.run(FutureTask.java:237)
           at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:272)
           at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
           at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
           at java.lang.Thread.run(Thread.java:761)
    

    I've recently updated the initialization to TrueTimeRx. Before this, I haven't received any crashes. Can you help me solve this?

    This is my initialization:

    private void initTime() {
        TrueTimeRx.build()
                  .initializeRx("time.google.com")
                  .subscribeOn(Schedulers.io())
                  .subscribe(date -> Timber.v("initTime(): TrueTime was initialized and we have a time: " + date),
                      Throwable::printStackTrace);
      }
    

    Method which I call in onCreate() method of my project Application class.

    awaiting feedback 
    opened by IonutNegru87 14
  • Provide customized TrueTime cache interface

    Provide customized TrueTime cache interface

    Currently, if we would like to cache the true time, we have to use SharedPreference. However, this might be a security loop if we do not encrypt the cache time as the cache time could be modified on rooted time by accessing the application sandbox. So I did some modification and provide an interface for these who would like to manage the cache of TrueTime on their own if it is deemed necessary.

    opened by TonyTangAndroid 13
  • TrueTime with Dagger @Singleton?

    TrueTime with Dagger @Singleton?

    Hi. The documentation notes "Preferable use dependency injection (like Dagger) and create a TrueTime @Singleton object".

    I'd like to initialize TrueTimeRX when my app starts, then subscribe to it later in a specific activity. Is this the correct way to create the singleton for that purpose in Dagger 2?

    @Singleton
    public class MyTrueTime {
        public final Observable trueTime;
    
        @Inject
        public MyTrueTime(String url) {
            this.trueTime = TrueTimeRx.build()
                .initializeRx(url);
        }
    }
    

    Thanks!

    opened by scottybe 11
  • TrueTimeRx subscribe only called once

    TrueTimeRx subscribe only called once

    I feel kind of embarrassed to be asking, since I imagine the solution is obvious to many.

    In my Activity's OnCreate function, I set up a subscription in the following way:

           trueTimeRxObservable.subscribe(new Subscriber<Date>() {
                @Override
                public void onNext(Date t) {
                    Log.i("truetime", "got new time!");
                }
            });
    

    However, onNext is only called once. Shouldn't onNext get called every time there's a new adjustment to the "true" time? If not, how can I get notified of these updates like the "TrueTimeUpdatedNotification" on the Swift version? Thanks!

    opened by scottybe 10
  • TrueTime caching not working

    TrueTime caching not working

    I'm initializing the library in my application onCreate(). I enabled the cache via: .withSharedPreferences(this) but the method TrueTimeRx.isInitialized() always returns false between application restarts. Also if I try to call TrueTimeRx.now() it throws an exception.

    Can anyone confirm if the cache really works? The logs do not state anything going wrong.

    wip 
    opened by IonutNegru87 10
  • Neither Rx version or Normal version is working

    Neither Rx version or Normal version is working

    Hi,

    Neither Rx version or Normal version is working. Even the Sample is not working

    Getting the same error everywhere. Even in Rx version where retry happens 100 times. Also the exception crashes the App.

    com.instacart.library.truetime.InvalidNtpServerResponseException: Server response delay too large for comfort 378
                                                                                       at com.instacart.library.truetime.SntpClient.requestTime(SntpClient.java:171)
                                                                                       at com.instacart.library.truetime.TrueTime.requestTime(TrueTime.java:89)
                                                                                       at com.instacart.library.truetime.TrueTime.initialize(TrueTime.java:85)
                                                                                       at com.instacart.library.truetime.TrueTime.initialize(TrueTime.java:49)
                                                                                       at com.instacart.library.sample.SampleActivity$InitTrueTimeAsyncTask.doInBackground(SampleActivity.java:73)
                                                                                       at com.instacart.library.sample.SampleActivity$InitTrueTimeAsyncTask.doInBackground(SampleActivity.java:65)
                                                                                       at android.os.AsyncTask$2.call(AsyncTask.java:295)
                                                                                       at java.util.concurrent.FutureTask.run(FutureTask.java:237)
                                                                                       at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:234)
                                                                                       at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
                                                                                       at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
                                                                                       at java.lang.Thread.run(Thread.java:818)
    
    opened by parthmg 10
  • Crash while initializing

    Crash while initializing

    Version 2.1

    Caused by java.lang.IndexOutOfBoundsException: Index: 0, Size: 0 at java.util.ArrayList.get(ArrayList.java:411) at com.instacart.library.truetime.TrueTimeRx$6.call(TrueTimeRx.java:191) at com.instacart.library.truetime.TrueTimeRx$6.call(TrueTimeRx.java:179) ... rx internals ...

    Device info

    opened by consp1racy 10
  • Valid once per boot even for uptimes measured in weeks or more?

    Valid once per boot even for uptimes measured in weeks or more?

    The readme says "Also, once we have this information it's valid until the next time you boot your device."

    Is this true regardless of system uptime? I have no real feel (nor data) for the drift of the system clock on a typical android device, but I worry that it could be on order of seconds/month. We need the (ongoing) best accuracy obtainable for remotely-deployed devices with uptimes of weeks to months. Would a periodic re-sync be advisable? If so, can I simply call initializeRx() again or do I need to do more to ensure it doesn't just pull from cache?

    Thanks for this awesome library... my first exposure to reactive code and it's blowing my mind (in a good way).

    Chris

    opened by CantStopMyBrain 9
  • we don't need to *also* store the boot time

    we don't need to *also* store the boot time

    boot time = sntp time - device uptime. we shouldn't have 3 flags

    https://github.com/instacart/truetime-android/blob/master/library/src/main/java/com/instacart/library/truetime/DiskCacheClient.java#L12

    opened by kaushikgopal 9
  • Add GPS time provider

    Add GPS time provider

    Hi there, I satisfied with your project, cause I was going to do that myself, but I wanted to include gps location to check if one of the either network provider or gps provider is enabled after boot time.

    Did you implemented gps provider time? If not, how can I set the time I have got from GPS provider in TrueTime?

    opened by homayoonahmadi 1
  • TrueTime init() got crash

    TrueTime init() got crash

    TrueTime initialized while in internet, then turn off internet and killed the application , now while open app without internet it get crashed

    how can I get true time in offline, if app is killed and open again, - it call true time init() offline,

    You need to call init() on TrueTime at least once.

    Thanks in advance,

    opened by Sbalanarayanan 1
  • Error : You need to call init() on TrueTime at least once.

    Error : You need to call init() on TrueTime at least once.

    hi i sometimes i got this error

    java.lang.IllegalStateException: You need to call init() on TrueTime at least once. com.instacart.library.truetime.TrueTime.now(TrueTime.java:29)

    but i already put this on my class that extend Application() class doAsync { TrueTime.build().initialize() }

    opened by glomowa 3
  • Outdated Versions of NTP Leaving Users Vulnerable - NTP v3

    Outdated Versions of NTP Leaving Users Vulnerable - NTP v3

    It looks like your still using v3 protocol that has known vulnerabilities and is subject to be using in DDos attacks. Version 4 has been around since 2010 and earlier. Is this on your radar and if so when do you plan on upgrading the version/protocol used?

    https://www.nwtime.org/outdated_versions_of_ntp_leaving_users_vulnerable/

    opened by bobpf 7
  • It is possible to get synced clock with difference of 10ms maximum?

    It is possible to get synced clock with difference of 10ms maximum?

    Hello, I want to start working with your library and I have just read your recommendation for re-sync (calling initialize method frequently) each 1 hour to get sync of 1 second. So if I want to keep sync with a difference of 10ms (maximum)- do I need to re-sync every 36000ms?!

    and BTW, after initializing the "true time clock" on two devices- what the "true time clock" difference between them? because in my test is around 30-70ms. it is a lot not?

    opened by matanmarciano 0
  • The exception could not be delivered to the consumer because it has already canceled/disposed the flow or the exception has nowhere to go to begin with [SntpClient.java line 116]

    The exception could not be delivered to the consumer because it has already canceled/disposed the flow or the exception has nowhere to go to begin with [SntpClient.java line 116]

    Fatal Exception: io.reactivex.exceptions.UndeliverableException: The exception could not be delivered to the consumer because it has already canceled/disposed the flow or the exception has nowhere to go to begin with. Further reading: https://github.com/ReactiveX/RxJava/wiki/What's-different-in-2.0#error-handling | java.io.IOException: sendto failed: EPERM (Operation not permitted) at io.reactivex.plugins.RxJavaPlugins.onError(RxJavaPlugins.java:367) at io.reactivex.internal.operators.flowable.FlowableFlatMap$MergeSubscriber.innerError(FlowableFlatMap.java:608) at io.reactivex.internal.operators.flowable.FlowableFlatMap$InnerSubscriber.onError(FlowableFlatMap.java:672) at io.reactivex.internal.subscribers.BasicFuseableSubscriber.onError(BasicFuseableSubscriber.java:101) at io.reactivex.internal.operators.flowable.FlowableToList$ToListSubscriber.onError(FlowableToList.java:79) at io.reactivex.internal.operators.flowable.FlowableFlatMap$MergeSubscriber.checkTerminate(FlowableFlatMap.java:567) at io.reactivex.internal.operators.flowable.FlowableFlatMap$MergeSubscriber.drainLoop(FlowableFlatMap.java:374) at io.reactivex.internal.operators.flowable.FlowableFlatMap$MergeSubscriber.drain(FlowableFlatMap.java:366) at io.reactivex.internal.operators.flowable.FlowableFlatMap$MergeSubscriber.innerError(FlowableFlatMap.java:606) at io.reactivex.internal.operators.flowable.FlowableFlatMap$InnerSubscriber.onError(FlowableFlatMap.java:672) at io.reactivex.internal.operators.flowable.FlowableRetryPredicate$RetrySubscriber.onError(FlowableRetryPredicate.java:84) at io.reactivex.internal.operators.flowable.FlowableDoOnEach$DoOnEachSubscriber.onError(FlowableDoOnEach.java:111) at io.reactivex.internal.operators.flowable.FlowableSubscribeOn$SubscribeOnSubscriber.onError(FlowableSubscribeOn.java:102) at io.reactivex.internal.operators.flowable.FlowableCreate$BaseEmitter.error(FlowableCreate.java:292) at io.reactivex.internal.operators.flowable.FlowableCreate$BufferAsyncEmitter.drain(FlowableCreate.java:536) at io.reactivex.internal.operators.flowable.FlowableCreate$BufferAsyncEmitter.tryOnError(FlowableCreate.java:486) at com.instacart.library.truetime.TrueTimeRx$4$1$2.subscribe(TrueTimeRx.java:214) at io.reactivex.internal.operators.flowable.FlowableCreate.subscribeActual(FlowableCreate.java:71) at io.reactivex.Flowable.subscribe(Flowable.java:14805) at io.reactivex.Flowable.subscribe(Flowable.java:14752) at io.reactivex.internal.operators.flowable.FlowableSubscribeOn$SubscribeOnSubscriber.run(FlowableSubscribeOn.java:82) at io.reactivex.internal.schedulers.ScheduledRunnable.run(ScheduledRunnable.java:66) at io.reactivex.internal.schedulers.ScheduledRunnable.call(ScheduledRunnable.java:57) at java.util.concurrent.FutureTask.run(FutureTask.java:266) at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:301) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1162) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:636) at java.lang.Thread.run(Thread.java:764)

    opened by CHRehan 1
Releases(3.5)
  • 3.5(Oct 20, 2021)

  • 3.4(Sep 5, 2018)

    • Improved caching (Provide custom caching implementation) πŸ™ @TonyTangAndroid
    • new Wiki with better instructions and information around using the library
    • use Single instead of Flowable for init call apis
    • update example to demonstrate usage better
    • remove "support-annotations" dependency
    Source code(tar.gz)
    Source code(zip)
  • 3.3(Jul 17, 2017)

    Features

    • provide api for server response delay max (millis) #57
    • provide root delay and root dispersion as api inputs (millis) #57
    • propagate InvalidNtpServerResponseException properly with violated property values #57

    Fixes

    • bump the default server response delay to 200
    Source code(tar.gz)
    Source code(zip)
  • 3.2(Jun 6, 2017)

    Features

    • upgrade to RxJava 2.x (Observables are now Flowables)

    Fixes:

    • api for providing NTP resolved IPs directly (see #42 for details)
    • fix manifest merge fail (see #44)
    • synchronize accessors (see #56)
    Source code(tar.gz)
    Source code(zip)
  • 2.2(Jan 28, 2017)

  • 2.1(Dec 23, 2016)

  • 2.0(Oct 18, 2016)

    Features:

    • Full NTP implementation #24 (this was a significant change and warranted the change of the apis)
    • Disk persistence! cache TrueTime info to disk, so we avoid network requests calls (even across app kills). This requires the boot permission as TrueTime is invalid across device boots #15
    • Add flag for logging #16

    Fixes:

    • More stringent checks with custom InvalidNtpServerResponseException thrown with reason for failure
    • the maxConcurrent option was incorrectly being used on flatMap. While limiting the number of parallel SNTP calls made, it was also basically ignoring rest of the provided NTP hosts.
    Source code(tar.gz)
    Source code(zip)
  • 1.5(Sep 2, 2016)

  • 1.3(Jul 30, 2016)

  • 1.1(Jul 20, 2016)

Owner
Instacart
Same-day Grocery Delivery
Instacart
Clock of Clocks written in Jetpack Compose framework

A Clock of Clocks made with Jetpack Compose You can download the APK Here. This project is inspired by A Clock of Clocks. Other Implementations This p

Adib Faramarzi 40 Nov 1, 2022
A custom clock view with a circular slider.

Read this in other languages: English, δΈ­ζ–‡. ClockSlider A custom clock view with a circular slider. Supported Android Versions Android 4.0 Jelly Bean(A

Chien 5 Nov 13, 2022
Tanya Gupta 1 Aug 16, 2022
A simple Cupcake Ordering App, choose flavor, pickup on a date, get order summary and send order via any other app.

Cupcake app This app contains an order flow for cupcakes with options for quantity, flavor, and pickup date. The order details get displayed on an ord

Akshat Khandelwal 0 Dec 23, 2021
Asimov-time-kt - Useful time and date related functions and extensions

asimov/time Useful time and date related functions and extensions. Installation

Nicolas Bottarini 1 Jan 7, 2022
Joda-Time library with Android specialization

Android has built-in date and time handling - why bother with a library? If you've worked with Java's Date and Calendar classes you can probably answer this question yourself, but if not, check out Joda-Time's list of benefits.

Daniel Lew 2.6k Dec 9, 2022
KotlinX multiplatform date/time library

kotlinx-datetime A multiplatform Kotlin library for working with date and time. See Using in your projects for the instructions how to setup a depende

Kotlin 1.6k Jan 5, 2023
Multiplatform Date and time library for Kotlin

Klock is a Date & Time library for Multiplatform Kotlin. It is designed to be as allocation-free as possible using Kotlin inline classes, to be consis

null 681 Dec 19, 2022
Additions for Kotlin's date & time library kotlinx-datetime

fluid-time Additions for Kotlin's date & time library kotlinx-datetime. kotlinx-datetime is very early stage and not as actively developed as other of

Marc Knaup 39 Nov 11, 2022
java.time Kotlin extension functions library.

Java Time Kotlin extension functions. Background Java Time became integrated to the JDK as of Java 8. It was a huge improvement over its Date predeces

Sami Eljabali 31 Mar 15, 2022
A material-styled android view that provisions picking of a date, time & recurrence option, all from a single user-interface.

SublimePicker A customizable view that provisions picking of a date, time & recurrence option, all from a single user-interface. You can also view 'Su

Vikram 2.3k Jan 4, 2023
Pick a date or time on Android in style

Material DateTime Picker - Select a time/date in style Material DateTime Picker tries to offer you the date and time pickers as shown in the Material

null 4.7k Dec 29, 2022
Estimated Time of Arrival Bar

Estimated Time of Arrival Bar

Tek 1 Mar 12, 2022
Asimov-flagz-kt - Feature flags library based on Togglz library

Asimov Flagz Feature flags library based on Togglz library. Installation Gradle

Nicolas Bottarini 1 Jan 8, 2022
Android Week View is an android library to display calendars (week view or day view) within the app. It supports custom styling.

Android Week View Android Week View is an android library to display calendars (week view or day view) within the app. It supports custom styling. Fea

Raquib-ul Alam (Kanak) 3.4k Jan 3, 2023
Android library for better Picker DialogFragments

DialogFragments modeled after the AOSP Clock and Calendar apps to improve UX for picking time, date, numbers, and other things.

Code-Troopers 2.7k Dec 29, 2022
An android library which provides a compact calendar view much like the one used in google calenders.

CompactCalendarView CompactCalendarView is a simple calendar view which provides scrolling between months. It's based on Java's Date and Calendar clas

SundeepK 1.5k Jan 7, 2023
android library dialog month picker

RackMonthPicker android library dialog month picker Download Download via Maven: Add the JitPack repository to your build file <repositories> <rep

Kristiawan Adi L 41 Aug 13, 2022
CustomizableCalendar is a library that allows you to create your calendar, customizing UI and behaviour

CustomizableCalendar This library allows you to create a completely customizable calendar. You can use CustomizableCalendar to create your calendar, c

MOLO17 216 Dec 6, 2022