| // Copyright 2018 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 '../clock.dart'; |
| import 'stopwatch.dart'; |
| import 'utils.dart'; |
| |
| /// A provider for the "current time" and points relative to the current time. |
| /// |
| /// This class is designed with testability in mind. The current point in time |
| /// (or [now()]) is defined by a function that returns a [DateTime]. By |
| /// supplying your own time function or using [Clock.fixed], you can control |
| /// exactly what time a [Clock] returns and base your test expectations on that. |
| /// |
| /// Most users should use the top-level [clock] field, which provides access to |
| /// a default implementation of [Clock] which can be overridden using |
| /// [withClock]. |
| class Clock { |
| /// The function that's called to determine this clock's notion of the current |
| /// time. |
| final DateTime Function() _time; |
| |
| /// Creates a clock based on the given [currentTime], or on the system clock |
| /// by default. |
| // ignore: deprecated_member_use_from_same_package |
| const Clock([DateTime Function() currentTime = systemTime]) |
| : _time = currentTime; |
| |
| /// Creates [Clock] that always considers the current time to be [time]. |
| 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 the individual parts. |
| DateTime ago( |
| {int days = 0, |
| int hours = 0, |
| int minutes = 0, |
| int seconds = 0, |
| int milliseconds = 0, |
| int microseconds = 0}) => |
| agoBy(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 the individual parts. |
| DateTime fromNow( |
| {int days = 0, |
| int hours = 0, |
| int minutes = 0, |
| int seconds = 0, |
| int milliseconds = 0, |
| int microseconds = 0}) => |
| fromNowBy(Duration( |
| days: days, |
| hours: hours, |
| minutes: minutes, |
| seconds: seconds, |
| milliseconds: milliseconds, |
| microseconds: microseconds)); |
| |
| /// Return the point in time [microseconds] ago. |
| DateTime microsAgo(int microseconds) => ago(microseconds: microseconds); |
| |
| /// Return the point in time [microseconds] from now. |
| DateTime microsFromNow(int microseconds) => |
| fromNow(microseconds: microseconds); |
| |
| /// Return the point in time [milliseconds] ago. |
| DateTime millisAgo(int milliseconds) => ago(milliseconds: milliseconds); |
| |
| /// Return the point in time [milliseconds] from now. |
| DateTime millisFromNow(int milliseconds) => |
| fromNow(milliseconds: milliseconds); |
| |
| /// 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. |
| /// |
| /// If the current day of the month isn't valid in the new month, the nearest |
| /// valid day in the new month will be used. |
| DateTime monthsAgo(int months) { |
| var time = now(); |
| var month = (time.month - months - 1) % 12 + 1; |
| var year = time.year - (months + 12 - time.month) ~/ 12; |
| var day = clampDayOfMonth(year: year, month: month, day: time.day); |
| return DateTime(year, month, day, time.hour, time.minute, time.second, |
| time.millisecond); |
| } |
| |
| /// Return the point in time [months] from now on the same date. |
| /// |
| /// If the current day of the month isn't valid in the new month, the nearest |
| /// valid day in the new month will be used. |
| DateTime monthsFromNow(int months) { |
| var time = now(); |
| var month = (time.month + months - 1) % 12 + 1; |
| var year = time.year + (months + time.month - 1) ~/ 12; |
| var day = clampDayOfMonth(year: year, month: month, day: time.day); |
| return DateTime(year, month, day, time.hour, time.minute, time.second, |
| time.millisecond); |
| } |
| |
| /// Return the point in time [years] ago on the same date. |
| /// |
| /// If the current day of the month isn't valid in the new year, the nearest |
| /// valid day in the original month will be used. |
| DateTime yearsAgo(int years) { |
| var time = now(); |
| var year = time.year - years; |
| var day = clampDayOfMonth(year: year, month: time.month, day: time.day); |
| return DateTime(year, time.month, day, time.hour, time.minute, time.second, |
| time.millisecond); |
| } |
| |
| /// Return the point in time [years] from now on the same date. |
| /// |
| /// If the current day of the month isn't valid in the new year, the nearest |
| /// valid day in the original month will be used. |
| DateTime yearsFromNow(int years) => yearsAgo(-years); |
| |
| /// Returns a new stopwatch that uses the current time as reported by `this`. |
| Stopwatch stopwatch() => ClockStopwatch(this); |
| |
| /// Returns a new stopwatch that uses the current time as reported by `this`. |
| @Deprecated('Use stopwatch() instead.') |
| Stopwatch getStopwatch() => stopwatch(); |
| } |