// bsls_systemtime.h                                                  -*-C++-*-
#ifndef INCLUDED_BSLS_SYSTEMTIME
#define INCLUDED_BSLS_SYSTEMTIME

#include <bsls_ident.h>
BSLS_IDENT("$Id: $")

//@PURPOSE: Provide utilities to retrieve the system time.
//
//@CLASSES:
//   bsls::SystemTime: namespace for system-time functions
//
//@SEE_ALSO: bsls_timeinterval
//
//@DESCRIPTION: This component provides a `struct`, `bsls::SystemTime`, in
// which are defined a series of static methods for retrieving the current
// system time.  This component provides access to a monotonic clock and a
// real-time (wall) clock.
//
///Reference Time Point
///--------------------
// The `bsls::TimeInterval` objects returned by functions in this component
// identify a time by providing a time interval from some fixed reference time
// point (or "epoch").  The clock types supported by `bsls_systemtime` (see
// `bsls_systemclocktype`) define a reference time point as described in the
// table below:
// ```
// bsls::SystemClockType::Enum  Reference Time Point
// ---------------------------  --------------------
// e_REALTIME                   January 1, 1970 00:00.000 UTC (POSIX epoch)
// e_MONOTONIC                  platform-dependent
// ```
// The `e_MONOTONIC` clock's reference time point is an unspecified,
// platform-dependent, value.  This means that the monotonic clock cannot be
// reliably used to determine the absolute wall clock time.  Monotonic clock
// times are frequently used to specify a fixed point in the future relative to
// the current (monotonic) clock time (e.g., for a timed-wait on a condition
// variable).  Note that the monotonic clock time may be (though certainly is
// not guaranteed to be) an arbitrary value relative to the process start time,
// meaning that `bsls::TimeInterval` values from the monotonic clock should
// *not* be shared between processes.
//
///Thread Safety
///-------------
// The functions provided by `bsls::SystemTime` are *thread-safe*.
//
///Usage
///-----
// This section illustrates intended use of this component.
//
///Example 1: Getting Current Wall Clock Time
/// - - - - - - - - - - - - - - - - - - - - -
// The following snippets of code illustrate how to use this utility component
// to obtain the system time by calling `now` and `nowRealtimeClock`.
//
// First, we call `nowRealtimeClock`, and set `t1`, to the current time
// according to the real-time clock:
// ```
// bsls::TimeInterval t1 = bsls::SystemTime::nowRealtimeClock();
//
// assert(bsls::TimeInterval() != t1);
// ```
// Next, we sleep for 1 second:
// ```
// sleep(1);
// ```
// Now, we call `now`, and supply `e_REALTIME` to indicate a real-time clock
// value should be returned, and then set `t2` to the current time according
// to the real-time clock:
// ```
// bsls::TimeInterval t2 = bsls::SystemTime::now(
//                                         bsls::SystemClockType::e_REALTIME);
//
// assert(bsls::TimeInterval() != t2);
// ```
// Finally, we verify the interval between `t1` and `t2` is close to 1 second:
// ```
// bsls::TimeInterval interval = t2 - t1;
//
// assert(bsls::TimeInterval(.8) <= interval &&
//                                  interval <= bsls::TimeInterval(2.5));
// ```

#include <bsls_assert.h>
#include <bsls_systemclocktype.h>
#include <bsls_timeinterval.h>

namespace BloombergLP {
namespace bsls {

                            // =================
                            // struct SystemTime
                            // =================

/// This `struct` provides a namespace for system-time-retrieval functions.
struct SystemTime {

  public:
    // CLASS METHODS

    /// Return the `TimeInterval` value representing the current system
    /// time according to the specified `clockType`.  The returned value is
    /// the time interval between the reference time point defined for the
    /// supplied `clockType` (see {Reference Time Point}) and the current
    /// time.
    static TimeInterval now(SystemClockType::Enum clockType);

    /// Return the `TimeInterval` value representing the current system time
    /// according to the monotonic clock.  The returned value is the time
    /// interval between the reference time point for the monotonic clock
    /// (see {Reference Time Point}) and the current time.
    static TimeInterval nowMonotonicClock();

    /// Return the `TimeInterval` value representing the current system time
    /// according to the real-time clock.  The returned value is the time
    /// interval between the reference time point for the real-time clock
    /// (see {Reference Time Point}) and the current time.
    static TimeInterval nowRealtimeClock();
};

// ============================================================================
//                           INLINE DEFINITIONS
// ============================================================================

                            // ----------------
                            // class SystemTime
                            // ----------------

// CLASS METHODS
inline
TimeInterval SystemTime::now(SystemClockType::Enum clockType)
{
    switch (clockType) {
      case SystemClockType::e_MONOTONIC: return nowMonotonicClock();  // RETURN
      case SystemClockType::e_REALTIME:  return nowRealtimeClock();   // RETURN
    }
    BSLS_ASSERT_OPT_UNREACHABLE("Invalid `clockType` parameter value");
    return TimeInterval();
}

}  // close package namespace
}  // close enterprise namespace

#endif

// ----------------------------------------------------------------------------
// Copyright 2014 Bloomberg Finance L.P.
//
// 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.
// ----------------------------- END-OF-FILE ----------------------------------
