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 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 * 38 * A provider of current time. It should be used by code requiring a timestamp, so it can be mocked during tests. 39 * {@code MockTimeProvider} in module "Test Utilities" is a suitable mock for performing tests. 40 * 41 * @author Fabrizio Giudici 42 * @since 3.2-ALPHA-1 (was previously InstantProvider since 1.39) 43 * 44 **************************************************************************************************************************************************************/ 45 @FunctionalInterface 46 public interface TimeProvider extends Supplier<Instant> 47 { 48 // FIXME: should be private 49 public static AtomicReference<TimeProvider> __INSTANCE = new AtomicReference<>(); 50 51 /*********************************************************************************************************************************************************** 52 * Returns the current time. 53 * 54 * @return the current time as an {@link Instant} 55 * @since 3.2-ALPHA-2 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 @Override @Nonnull 67 public default Instant get() 68 { 69 return currentInstant(); 70 } 71 72 /*********************************************************************************************************************************************************** 73 * Returns the current time. 74 * 75 * @return the current time as a {@link ZonedDateTime} in the default zone. 76 * @since 3.2-ALPHA-2 77 **********************************************************************************************************************************************************/ 78 @Nonnull 79 public default ZonedDateTime currentZonedDateTime() 80 { 81 return ZonedDateTime.ofInstant(currentInstant(), ZoneId.systemDefault()); 82 } 83 84 /*********************************************************************************************************************************************************** 85 * Returns the current time. 86 * 87 * @return the current time as a {@link LocalDateTime} in the default zone. 88 * @since 3.2-ALPHA-2 89 **********************************************************************************************************************************************************/ 90 @Nonnull 91 public default LocalDateTime currentLocalDateTime() 92 { 93 return LocalDateTime.ofInstant(currentInstant(), ZoneId.systemDefault()); 94 } 95 96 /*********************************************************************************************************************************************************** 97 * Returns the default instance. 98 * 99 * @return the default instance 100 * @since 3.2-ALPHA-2 101 **********************************************************************************************************************************************************/ 102 @Nonnull 103 public static TimeProvider getInstance() 104 { 105 synchronized (TimeProvider.class) 106 { 107 if (__INSTANCE.get() == null) 108 { 109 __INSTANCE.set(new DefaultTimeProvider()); 110 } 111 112 return __INSTANCE.get(); 113 } 114 } 115 116 /*********************************************************************************************************************************************************** 117 * 118 **********************************************************************************************************************************************************/ 119 static class DefaultTimeProvider implements TimeProvider 120 { 121 @Override @Nonnull 122 public Instant currentInstant() 123 { 124 return Instant.now(); 125 } 126 } 127 }