blob: 4ee971ae548b94ae33fdee6e3808fb8f82eb7220 [file] [log] [blame]
// Copyright 2013 Google Inc. All Rights Reserved.
//
// 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.
import 'src/utils.dart';
/// Returns current time.
typedef DateTime TimeFunction();
/// Return current system time.
DateTime systemTime() => new DateTime.now();
/// Provides points in time relative to the current point in time, for example:
/// now, 2 days ago, 4 weeks from now, etc.
///
/// This class is designed with testability in mind. The current point in time
/// (or [now()]) is defined by a [TimeFunction]. By supplying your own time
/// function or by using fixed clock (see constructors), you can control
/// exactly what time a [Clock] returns and base your test expectations on
/// that. See specific constructors for how to supply time functions.
class Clock {
final TimeFunction _time;
/// Creates a clock based on the given [timeFunc].
///
/// If [timeFunc] is not provided, creates [Clock] based on system clock.
///
/// Custom [timeFunc] can be useful in unit-tests. For example, you might
/// want to control what time it is now and set date and time expectations in
/// your test cases.
const Clock([TimeFunction timeFunc = systemTime]) : _time = timeFunc;
/// Creates [Clock] that returns fixed [time] value. Useful in unit-tests.
Clock.fixed(DateTime time) : _time = (() => time);
/// Returns current time.
DateTime now() => _time();
/// Returns the point in time [Duration] amount of time ago.
DateTime agoBy(Duration duration) => now().subtract(duration);
/// Returns the point in time [Duration] amount of time from now.
DateTime fromNowBy(Duration duration) => now().add(duration);
/// Returns the point in time that's given amount of time ago. The
/// amount of time is the sum of individual parts. Parts are compatible with
/// ones defined in [Duration].
DateTime ago(
{int days: 0,
int hours: 0,
int minutes: 0,
int seconds: 0,
int milliseconds: 0,
int microseconds: 0}) =>
agoBy(new Duration(
days: days,
hours: hours,
minutes: minutes,
seconds: seconds,
milliseconds: milliseconds,
microseconds: microseconds));
/// Returns the point in time that's given amount of time from now. The
/// amount of time is the sum of individual parts. Parts are compatible with
/// ones defined in [Duration].
DateTime fromNow(
{int days: 0,
int hours: 0,
int minutes: 0,
int seconds: 0,
int milliseconds: 0,
int microseconds: 0}) =>
fromNowBy(new Duration(
days: days,
hours: hours,
minutes: minutes,
seconds: seconds,
milliseconds: milliseconds,
microseconds: microseconds));
/// Return the point in time [micros] microseconds ago.
DateTime microsAgo(int micros) => ago(microseconds: micros);
/// Return the point in time [micros] microseconds from now.
DateTime microsFromNow(int micros) => fromNow(microseconds: micros);
/// Return the point in time [millis] milliseconds ago.
DateTime millisAgo(int millis) => ago(milliseconds: millis);
/// Return the point in time [millis] milliseconds from now.
DateTime millisFromNow(int millis) => fromNow(milliseconds: millis);
/// Return the point in time [seconds] ago.
DateTime secondsAgo(int seconds) => ago(seconds: seconds);
/// Return the point in time [seconds] from now.
DateTime secondsFromNow(int seconds) => fromNow(seconds: seconds);
/// Return the point in time [minutes] ago.
DateTime minutesAgo(int minutes) => ago(minutes: minutes);
/// Return the point in time [minutes] from now.
DateTime minutesFromNow(int minutes) => fromNow(minutes: minutes);
/// Return the point in time [hours] ago.
DateTime hoursAgo(int hours) => ago(hours: hours);
/// Return the point in time [hours] from now.
DateTime hoursFromNow(int hours) => fromNow(hours: hours);
/// Return the point in time [days] ago.
DateTime daysAgo(int days) => ago(days: days);
/// Return the point in time [days] from now.
DateTime daysFromNow(int days) => fromNow(days: days);
/// Return the point in time [weeks] ago.
DateTime weeksAgo(int weeks) => ago(days: 7 * weeks);
/// Return the point in time [weeks] from now.
DateTime weeksFromNow(int weeks) => fromNow(days: 7 * weeks);
/// Return the point in time [months] ago on the same date.
DateTime monthsAgo(int months) {
var time = now();
var m = (time.month - months - 1) % 12 + 1;
var y = time.year - (months + 12 - time.month) ~/ 12;
var d = clampDayOfMonth(year: y, month: m, day: time.day);
return new DateTime(
y, m, d, time.hour, time.minute, time.second, time.millisecond);
}
/// Return the point in time [months] from now on the same date.
DateTime monthsFromNow(int months) {
var time = now();
var m = (time.month + months - 1) % 12 + 1;
var y = time.year + (months + time.month - 1) ~/ 12;
var d = clampDayOfMonth(year: y, month: m, day: time.day);
return new DateTime(
y, m, d, time.hour, time.minute, time.second, time.millisecond);
}
/// Return the point in time [years] ago on the same date.
DateTime yearsAgo(int years) {
var time = now();
var y = time.year - years;
var d = clampDayOfMonth(year: y, month: time.month, day: time.day);
return new DateTime(y, time.month, d, time.hour, time.minute, time.second,
time.millisecond);
}
/// Return the point in time [years] from now on the same date.
DateTime yearsFromNow(int years) => yearsAgo(-years);
}