1 /*
2   ==============================================================================
3 
4    This file is part of the JUCE library.
5    Copyright (c) 2017 - ROLI Ltd.
6 
7    JUCE is an open source library subject to commercial or open-source
8    licensing.
9 
10    The code included in this file is provided under the terms of the ISC license
11    http://www.isc.org/downloads/software-support-policy/isc-license. Permission
12    To use, copy, modify, and/or distribute this software for any purpose with or
13    without fee is hereby granted provided that the above copyright notice and
14    this permission notice appear in all copies.
15 
16    JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
17    EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
18    DISCLAIMED.
19 
20   ==============================================================================
21 */
22 
23 namespace juce
24 {
25 
26 //==============================================================================
27 /**
28     Holds an absolute date and time.
29 
30     Internally, the time is stored at millisecond precision.
31 
32     @see RelativeTime
33 
34     @tags{Core}
35 */
36 class JUCE_API  Time
37 {
38 public:
39     //==============================================================================
40     /** Creates a Time object.
41         This default constructor creates a time of midnight Jan 1st 1970 UTC, (which is
42         represented internally as 0ms).
43         To create a time object representing the current time, use getCurrentTime().
44         @see getCurrentTime
45     */
46     Time() = default;
47 
48     /** Creates a time based on a number of milliseconds.
49         To create a time object set to the current time, use getCurrentTime().
50 
51         @param millisecondsSinceEpoch   the number of milliseconds since the unix
52                                         'epoch' (midnight Jan 1st 1970 UTC).
53         @see getCurrentTime, currentTimeMillis
54     */
55     explicit Time (int64 millisecondsSinceEpoch) noexcept;
56 
57     /** Creates a time from a set of date components.
58 
59         @param year             the year, in 4-digit format, e.g. 2004
60         @param month            the month, in the range 0 to 11
61         @param day              the day of the month, in the range 1 to 31
62         @param hours            hours in 24-hour clock format, 0 to 23
63         @param minutes          minutes 0 to 59
64         @param seconds          seconds 0 to 59
65         @param milliseconds     milliseconds 0 to 999
66         @param useLocalTime     if true, assume input is in this machine's local timezone
67                                 if false, assume input is in UTC.
68     */
69     Time (int year,
70           int month,
71           int day,
72           int hours,
73           int minutes,
74           int seconds = 0,
75           int milliseconds = 0,
76           bool useLocalTime = true) noexcept;
77 
78     Time (const Time&) = default;
79     ~Time() = default;
80 
81     Time& operator= (const Time&) = default;
82 
83     //==============================================================================
84     /** Returns a Time object that is set to the current system time.
85 
86         This may not be monotonic, as the system time can change at any moment.
87         You should therefore not use this method for measuring time intervals.
88 
89         @see currentTimeMillis
90     */
91     static Time JUCE_CALLTYPE getCurrentTime() noexcept;
92 
93     /** Returns the time as a number of milliseconds.
94         @returns    the number of milliseconds this Time object represents, since
95                     midnight Jan 1st 1970 UTC.
96         @see getMilliseconds
97     */
toMilliseconds()98     int64 toMilliseconds() const noexcept                           { return millisSinceEpoch; }
99 
100     /** Returns the year (in this machine's local timezone).
101         A 4-digit format is used, e.g. 2004.
102     */
103     int getYear() const noexcept;
104 
105     /** Returns the number of the month (in this machine's local timezone).
106         The value returned is in the range 0 to 11.
107         @see getMonthName
108     */
109     int getMonth() const noexcept;
110 
111     /** Returns the name of the month (in this machine's local timezone).
112         @param threeLetterVersion   if true, it'll be a 3-letter abbreviation, e.g. "Jan"; if false
113                                     it'll return the long form, e.g. "January"
114         @see getMonth
115     */
116     String getMonthName (bool threeLetterVersion) const;
117 
118     /** Returns the day of the month (in this machine's local timezone).
119         The value returned is in the range 1 to 31.
120     */
121     int getDayOfMonth() const noexcept;
122 
123     /** Returns the number of the day of the week (in this machine's local timezone).
124         The value returned is in the range 0 to 6 (0 = sunday, 1 = monday, etc).
125     */
126     int getDayOfWeek() const noexcept;
127 
128     /** Returns the number of the day of the year (in this machine's local timezone).
129         The value returned is in the range 0 to 365.
130     */
131     int getDayOfYear() const noexcept;
132 
133     /** Returns the name of the weekday (in this machine's local timezone).
134         @param threeLetterVersion   if true, it'll return a 3-letter abbreviation, e.g. "Tue"; if
135                                     false, it'll return the full version, e.g. "Tuesday".
136     */
137     String getWeekdayName (bool threeLetterVersion) const;
138 
139     /** Returns the number of hours since midnight (in this machine's local timezone).
140         This is in 24-hour clock format, in the range 0 to 23.
141         @see getHoursInAmPmFormat, isAfternoon
142     */
143     int getHours() const noexcept;
144 
145     /** Returns true if the time is in the afternoon (in this machine's local timezone).
146         @returns true for "PM", false for "AM".
147         @see getHoursInAmPmFormat, getHours
148     */
149     bool isAfternoon() const noexcept;
150 
151     /** Returns the hours in 12-hour clock format (in this machine's local timezone).
152         This will return a value 1 to 12 - use isAfternoon() to find out
153         whether this is in the afternoon or morning.
154         @see getHours, isAfternoon
155     */
156     int getHoursInAmPmFormat() const noexcept;
157 
158     /** Returns the number of minutes, 0 to 59 (in this machine's local timezone). */
159     int getMinutes() const noexcept;
160 
161     /** Returns the number of seconds, 0 to 59. */
162     int getSeconds() const noexcept;
163 
164     /** Returns the number of milliseconds, 0 to 999.
165 
166         Unlike toMilliseconds(), this just returns the position within the
167         current second rather than the total number since the epoch.
168 
169         @see toMilliseconds
170     */
171     int getMilliseconds() const noexcept;
172 
173     /** Returns true if the local timezone uses a daylight saving correction. */
174     bool isDaylightSavingTime() const noexcept;
175 
176     //==============================================================================
177     /** Returns a 3-character string to indicate the local timezone. */
178     String getTimeZone() const;
179 
180     /** Returns the local timezone offset from UTC in seconds. */
181     int getUTCOffsetSeconds() const noexcept;
182 
183     /** Returns a string to indicate the offset of the local timezone from UTC.
184         @returns "+XX:XX", "-XX:XX" or "Z"
185         @param includeDividerCharacters  whether to include or omit the ":" divider in the string
186      */
187     String getUTCOffsetString (bool includeDividerCharacters) const;
188 
189     //==============================================================================
190     /** Returns a string version of this date and time, using this machine's local timezone.
191 
192         For a more powerful way of formatting the date and time, see the formatted() method.
193 
194         @param includeDate      whether to include the date in the string
195         @param includeTime      whether to include the time in the string
196         @param includeSeconds   if the time is being included, this provides an option not to include
197                                 the seconds in it
198         @param use24HourClock   if the time is being included, sets whether to use am/pm or 24
199                                 hour notation.
200         @see formatted
201     */
202     String toString (bool includeDate,
203                      bool includeTime,
204                      bool includeSeconds = true,
205                      bool use24HourClock = false) const;
206 
207     /** Converts this date/time to a string with a user-defined format.
208 
209         This uses the C strftime() function to format this time as a string. To save you
210         looking it up, these are the escape codes that strftime uses (other codes might
211         work on some platforms and not others, but these are the common ones):
212 
213         - %a  is replaced by the locale's abbreviated weekday name.
214         - %A  is replaced by the locale's full weekday name.
215         - %b  is replaced by the locale's abbreviated month name.
216         - %B  is replaced by the locale's full month name.
217         - %c  is replaced by the locale's appropriate date and time representation.
218         - %d  is replaced by the day of the month as a decimal number [01,31].
219         - %H  is replaced by the hour (24-hour clock) as a decimal number [00,23].
220         - %I  is replaced by the hour (12-hour clock) as a decimal number [01,12].
221         - %j  is replaced by the day of the year as a decimal number [001,366].
222         - %m  is replaced by the month as a decimal number [01,12].
223         - %M  is replaced by the minute as a decimal number [00,59].
224         - %p  is replaced by the locale's equivalent of either a.m. or p.m.
225         - %S  is replaced by the second as a decimal number [00,60].
226         - %U  is replaced by the week number of the year (Sunday as the first day of the week) as a decimal number [00,53].
227         - %w  is replaced by the weekday as a decimal number [0,6], with 0 representing Sunday.
228         - %W  is replaced by the week number of the year (Monday as the first day of the week) as a decimal number [00,53]. All days in a new year preceding the first Monday are considered to be in week 0.
229         - %x  is replaced by the locale's appropriate date representation.
230         - %X  is replaced by the locale's appropriate time representation.
231         - %y  is replaced by the year without century as a decimal number [00,99].
232         - %Y  is replaced by the year with century as a decimal number.
233         - %Z  is replaced by the timezone name or abbreviation, or by no bytes if no timezone information exists.
234         - %%  is replaced by %.
235 
236         @see toString
237     */
238     String formatted (const String& format) const;
239 
240     //==============================================================================
241     /** Returns a fully described string of this date and time in ISO-8601 format
242         (using the local timezone).
243 
244         @param includeDividerCharacters  whether to include or omit the "-" and ":"
245                                          dividers in the string
246     */
247     String toISO8601 (bool includeDividerCharacters) const;
248 
249     /** Parses an ISO-8601 string and returns it as a Time. */
250     static Time fromISO8601 (StringRef iso8601);
251 
252     //==============================================================================
253     /** Adds a RelativeTime to this time. */
254     Time& operator+= (RelativeTime delta) noexcept;
255     /** Subtracts a RelativeTime from this time. */
256     Time& operator-= (RelativeTime delta) noexcept;
257 
258     //==============================================================================
259     /** Tries to set the computer's clock.
260 
261         @returns    true if this succeeds, although depending on the system, the
262                     application might not have sufficient privileges to do this.
263     */
264     bool setSystemTimeToThisTime() const;
265 
266     //==============================================================================
267     /** Returns the name of a day of the week.
268 
269         @param dayNumber            the day, 0 to 6 (0 = sunday, 1 = monday, etc)
270         @param threeLetterVersion   if true, it'll return a 3-letter abbreviation, e.g. "Tue"; if
271                                     false, it'll return the full version, e.g. "Tuesday".
272     */
273     static String getWeekdayName (int dayNumber, bool threeLetterVersion);
274 
275     /** Returns the name of one of the months.
276 
277         @param monthNumber  the month, 0 to 11
278         @param threeLetterVersion   if true, it'll be a 3-letter abbreviation, e.g. "Jan"; if false
279                                     it'll return the long form, e.g. "January"
280     */
281     static String getMonthName (int monthNumber, bool threeLetterVersion);
282 
283     //==============================================================================
284     // Static methods for getting system timers directly..
285 
286     /** Returns the current system time.
287 
288         Returns the number of milliseconds since midnight Jan 1st 1970 UTC.
289 
290         Should be accurate to within a few millisecs, depending on platform,
291         hardware, etc.
292     */
293     static int64 currentTimeMillis() noexcept;
294 
295     /** Returns the number of millisecs since a fixed event (usually system startup).
296 
297         This returns a monotonically increasing value which is unaffected by changes to the
298         system clock. It should be accurate to within a few millisecs, depending on platform,
299         hardware, etc.
300 
301         Being a 32-bit return value, it will of course wrap back to 0 after 2^32 seconds of
302         uptime, so be careful to take that into account. If you need a 64-bit time, you can
303         use currentTimeMillis() instead.
304 
305         @see getApproximateMillisecondCounter
306     */
307     static uint32 getMillisecondCounter() noexcept;
308 
309     /** Returns the number of millisecs since a fixed event (usually system startup).
310 
311         This has the same function as getMillisecondCounter(), but returns a more accurate
312         value, using a higher-resolution timer if one is available.
313 
314         @see getMillisecondCounter
315     */
316     static double getMillisecondCounterHiRes() noexcept;
317 
318     /** Waits until the getMillisecondCounter() reaches a given value.
319 
320         This will make the thread sleep as efficiently as it can while it's waiting.
321     */
322     static void waitForMillisecondCounter (uint32 targetTime) noexcept;
323 
324     /** Less-accurate but faster version of getMillisecondCounter().
325 
326         This will return the last value that getMillisecondCounter() returned, so doesn't
327         need to make a system call, but is less accurate - it shouldn't be more than
328         100ms away from the correct time, though, so is still accurate enough for a
329         lot of purposes.
330 
331         @see getMillisecondCounter
332     */
333     static uint32 getApproximateMillisecondCounter() noexcept;
334 
335     //==============================================================================
336     // High-resolution timers..
337 
338     /** Returns the current high-resolution counter's tick-count.
339 
340         This is a similar idea to getMillisecondCounter(), but with a higher
341         resolution.
342 
343         @see getHighResolutionTicksPerSecond, highResolutionTicksToSeconds,
344              secondsToHighResolutionTicks
345     */
346     static int64 getHighResolutionTicks() noexcept;
347 
348     /** Returns the resolution of the high-resolution counter in ticks per second.
349 
350         @see getHighResolutionTicks, highResolutionTicksToSeconds,
351              secondsToHighResolutionTicks
352     */
353     static int64 getHighResolutionTicksPerSecond() noexcept;
354 
355     /** Converts a number of high-resolution ticks into seconds.
356 
357         @see getHighResolutionTicks, getHighResolutionTicksPerSecond,
358              secondsToHighResolutionTicks
359     */
360     static double highResolutionTicksToSeconds (int64 ticks) noexcept;
361 
362     /** Converts a number seconds into high-resolution ticks.
363 
364         @see getHighResolutionTicks, getHighResolutionTicksPerSecond,
365              highResolutionTicksToSeconds
366     */
367     static int64 secondsToHighResolutionTicks (double seconds) noexcept;
368 
369     /** Returns a Time based on the value of the __DATE__ macro when this module was compiled */
370     static Time getCompilationDate();
371 
372 private:
373     //==============================================================================
374     int64 millisSinceEpoch = 0;
375 };
376 
377 //==============================================================================
378 /** Adds a RelativeTime to a Time. */
379 JUCE_API Time operator+ (Time time, RelativeTime delta) noexcept;
380 /** Adds a RelativeTime to a Time. */
381 JUCE_API Time operator+ (RelativeTime delta, Time time) noexcept;
382 
383 /** Subtracts a RelativeTime from a Time. */
384 JUCE_API Time operator- (Time time, RelativeTime delta) noexcept;
385 /** Returns the relative time difference between two times. */
386 JUCE_API const RelativeTime operator- (Time time1, Time time2) noexcept;
387 
388 /** Compares two Time objects. */
389 JUCE_API bool operator== (Time time1, Time time2) noexcept;
390 /** Compares two Time objects. */
391 JUCE_API bool operator!= (Time time1, Time time2) noexcept;
392 /** Compares two Time objects. */
393 JUCE_API bool operator<  (Time time1, Time time2) noexcept;
394 /** Compares two Time objects. */
395 JUCE_API bool operator<= (Time time1, Time time2) noexcept;
396 /** Compares two Time objects. */
397 JUCE_API bool operator>  (Time time1, Time time2) noexcept;
398 /** Compares two Time objects. */
399 JUCE_API bool operator>= (Time time1, Time time2) noexcept;
400 
401 } // namespace juce
402