TimeProvider.java

  1. /*
  2.  * *********************************************************************************************************************
  3.  *
  4.  * TheseFoolishThings: Miscellaneous utilities
  5.  * http://tidalwave.it/projects/thesefoolishthings
  6.  *
  7.  * Copyright (C) 2009 - 2023 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
  12.  * the License. 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
  17.  * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the License for the
  18.  * specific language governing permissions and limitations under the License.
  19.  *
  20.  * *********************************************************************************************************************
  21.  *
  22.  * git clone https://bitbucket.org/tidalwave/thesefoolishthings-src
  23.  * git clone https://github.com/tidalwave-it/thesefoolishthings-src
  24.  *
  25.  * *********************************************************************************************************************
  26.  */
  27. package it.tidalwave.util;

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

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

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

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

  72.     /*******************************************************************************************************************
  73.      *
  74.      * Returns the current time.
  75.      *
  76.      * @return    the current time as a {@link ZonedDateTime} in the default zone.
  77.      * @since 3.2-ALPHA-2
  78.      *
  79.      ******************************************************************************************************************/
  80.     @Nonnull
  81.     public default ZonedDateTime currentZonedDateTime()
  82.       {
  83.         return ZonedDateTime.ofInstant(currentInstant(), ZoneId.systemDefault());
  84.       }

  85.     /*******************************************************************************************************************
  86.      *
  87.      * Returns the current time.
  88.      *
  89.      * @return    the current time as a {@link LocalDateTime} in the default zone.
  90.      * @since 3.2-ALPHA-2
  91.      *
  92.      ******************************************************************************************************************/
  93.     @Nonnull
  94.     public default LocalDateTime currentLocalDateTime()
  95.       {
  96.         return LocalDateTime.ofInstant(currentInstant(), ZoneId.systemDefault());
  97.       }

  98.     /*******************************************************************************************************************
  99.      *
  100.      * Returns the default instance.
  101.      *
  102.      * @return    the default instance
  103.      * @since 3.2-ALPHA-2
  104.      *
  105.      ******************************************************************************************************************/
  106.     @Nonnull
  107.     public static TimeProvider getInstance()
  108.       {
  109.         synchronized (TimeProvider.class)
  110.           {
  111.             if (__INSTANCE.get() == null)
  112.               {
  113.                 __INSTANCE.set(new DefaultTimeProvider());
  114.               }

  115.             return __INSTANCE.get();
  116.           }
  117.       }

  118.     /*******************************************************************************************************************
  119.      *
  120.      ******************************************************************************************************************/
  121.     static class DefaultTimeProvider implements TimeProvider
  122.       {
  123.         @Override @Nonnull
  124.         public Instant currentInstant()
  125.           {
  126.             return Instant.now();
  127.           }
  128.       }
  129.   }