TimeProvider.java

  1. /*
  2.  * *************************************************************************************************************************************************************
  3.  *
  4.  * TheseFoolishThings: Miscellaneous utilities
  5.  * http://tidalwave.it/projects/thesefoolishthings
  6.  *
  7.  * Copyright (C) 2009 - 2025 by Tidalwave s.a.s. (http://tidalwave.it)
  8.  *
  9.  * *************************************************************************************************************************************************************
  10.  *
  11.  * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License.
  12.  * You may obtain a copy of the License at
  13.  *
  14.  *     http://www.apache.org/licenses/LICENSE-2.0
  15.  *
  16.  * 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
  17.  * CONDITIONS OF ANY KIND, either express or implied.  See the License for the specific language governing permissions and limitations under the License.
  18.  *
  19.  * *************************************************************************************************************************************************************
  20.  *
  21.  * git clone https://bitbucket.org/tidalwave/thesefoolishthings-src
  22.  * git clone https://github.com/tidalwave-it/thesefoolishthings-src
  23.  *
  24.  * *************************************************************************************************************************************************************
  25.  */
  26. package it.tidalwave.util;

  27. import javax.annotation.Nonnull;
  28. import java.time.Instant;
  29. import java.time.LocalDateTime;
  30. import java.time.ZoneId;
  31. import java.time.ZonedDateTime;
  32. import java.util.concurrent.atomic.AtomicReference;
  33. import java.util.function.Supplier;

  34. /***************************************************************************************************************************************************************
  35.  *
  36.  * A provider of current time. It should be used by code requiring a timestamp, so it can be mocked during tests.
  37.  * {@code MockTimeProvider} in module "Test Utilities" is a suitable mock for performing tests.
  38.  *
  39.  * @author  Fabrizio Giudici
  40.  * @since   3.2-ALPHA-1 (was previously InstantProvider since 1.39)
  41.  *
  42.  **************************************************************************************************************************************************************/
  43. @FunctionalInterface
  44. public interface TimeProvider extends Supplier<Instant>
  45.   {
  46.     // FIXME: should be private
  47.     public static AtomicReference<TimeProvider> __INSTANCE = new AtomicReference<>();

  48.     /***********************************************************************************************************************************************************
  49.      * Returns the current time.
  50.      *
  51.      * @return    the current time as an {@link Instant}
  52.      * @since 3.2-ALPHA-2
  53.      **********************************************************************************************************************************************************/
  54.     @Nonnull
  55.     public Instant currentInstant();

  56.     /***********************************************************************************************************************************************************
  57.      * Returns the current time. This method is provided to implement {@link Supplier}{@code <Instant>}.
  58.      *
  59.      * @return    the current time as an {@link Instant}
  60.      * @since 3.2-ALPHA-2
  61.      **********************************************************************************************************************************************************/
  62.     @Override @Nonnull
  63.     public default Instant get()
  64.       {
  65.         return currentInstant();
  66.       }

  67.     /***********************************************************************************************************************************************************
  68.      * Returns the current time.
  69.      *
  70.      * @return    the current time as a {@link ZonedDateTime} in the default zone.
  71.      * @since 3.2-ALPHA-2
  72.      **********************************************************************************************************************************************************/
  73.     @Nonnull
  74.     public default ZonedDateTime currentZonedDateTime()
  75.       {
  76.         return ZonedDateTime.ofInstant(currentInstant(), ZoneId.systemDefault());
  77.       }

  78.     /***********************************************************************************************************************************************************
  79.      * Returns the current time.
  80.      *
  81.      * @return    the current time as a {@link LocalDateTime} in the default zone.
  82.      * @since 3.2-ALPHA-2
  83.      **********************************************************************************************************************************************************/
  84.     @Nonnull
  85.     public default LocalDateTime currentLocalDateTime()
  86.       {
  87.         return LocalDateTime.ofInstant(currentInstant(), ZoneId.systemDefault());
  88.       }

  89.     /***********************************************************************************************************************************************************
  90.      * Returns the default instance.
  91.      *
  92.      * @return    the default instance
  93.      * @since 3.2-ALPHA-2
  94.      **********************************************************************************************************************************************************/
  95.     @Nonnull
  96.     public static TimeProvider getInstance()
  97.       {
  98.         synchronized (TimeProvider.class)
  99.           {
  100.             if (__INSTANCE.get() == null)
  101.               {
  102.                 __INSTANCE.set(new DefaultTimeProvider());
  103.               }

  104.             return __INSTANCE.get();
  105.           }
  106.       }

  107.     /***********************************************************************************************************************************************************
  108.      *
  109.      **********************************************************************************************************************************************************/
  110.     static class DefaultTimeProvider implements TimeProvider
  111.       {
  112.         @Override @Nonnull
  113.         public Instant currentInstant()
  114.           {
  115.             return Instant.now();
  116.           }
  117.       }
  118.   }