OpenShot Audio Library | OpenShotAudio 0.4.0

Loading...
Searching...
No Matches
juce_Time.cpp
1/*
2 ==============================================================================
3
4 This file is part of the JUCE library.
5 Copyright (c) 2022 - Raw Material Software Limited
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 namespace TimeHelpers
27{
28 static std::tm millisToLocal (int64 millis) noexcept
29 {
30 #if JUCE_WINDOWS && JUCE_MINGW
31 auto now = (time_t) (millis / 1000);
32 return *localtime (&now);
33
34 #elif JUCE_WINDOWS
35 std::tm result;
36 millis /= 1000;
37
38 if (_localtime64_s (&result, &millis) != 0)
39 zerostruct (result);
40
41 return result;
42
43 #else
44 std::tm result;
45 auto now = (time_t) (millis / 1000);
46
47 if (localtime_r (&now, &result) == nullptr)
48 zerostruct (result);
49
50 return result;
51 #endif
52 }
53
54 static std::tm millisToUTC (int64 millis) noexcept
55 {
56 #if JUCE_WINDOWS && JUCE_MINGW
57 auto now = (time_t) (millis / 1000);
58 return *gmtime (&now);
59
60 #elif JUCE_WINDOWS
61 std::tm result;
62 millis /= 1000;
63
64 if (_gmtime64_s (&result, &millis) != 0)
65 zerostruct (result);
66
67 return result;
68
69 #else
70 std::tm result;
71 auto now = (time_t) (millis / 1000);
72
73 if (gmtime_r (&now, &result) == nullptr)
74 zerostruct (result);
75
76 return result;
77 #endif
78 }
79
80 static int getUTCOffsetSeconds (const int64 millis) noexcept
81 {
82 auto utc = millisToUTC (millis);
83 utc.tm_isdst = -1; // Treat this UTC time as local to find the offset
84
85 return (int) ((millis / 1000) - (int64) mktime (&utc));
86 }
87
88 static int extendedModulo (const int64 value, const int modulo) noexcept
89 {
90 return (int) (value >= 0 ? (value % modulo)
91 : (value - ((value / modulo) + 1) * modulo));
92 }
93
94 static String formatString (const String& format, const std::tm* const tm)
95 {
96 #if JUCE_ANDROID
97 using StringType = CharPointer_UTF8;
98 #elif JUCE_WINDOWS
99 using StringType = CharPointer_UTF16;
100 #else
101 using StringType = CharPointer_UTF32;
102 #endif
103
104 #ifdef JUCE_MSVC
105 if (tm->tm_year < -1900 || tm->tm_year > 8099)
106 return {}; // Visual Studio's library can only handle 0 -> 9999 AD
107 #endif
108
109 for (size_t bufferSize = 256; ; bufferSize += 256)
110 {
111 HeapBlock<StringType::CharType> buffer (bufferSize);
112
113 auto numChars =
114 #if JUCE_ANDROID
115 strftime (buffer, bufferSize - 1, format.toUTF8(), tm);
116 #elif JUCE_WINDOWS
117 wcsftime (buffer, bufferSize - 1, format.toWideCharPointer(), tm);
118 #else
119 wcsftime (buffer, bufferSize - 1, format.toUTF32(), tm);
120 #endif
121
122 if (numChars > 0 || format.isEmpty())
123 return String (StringType (buffer),
124 StringType (buffer) + (int) numChars);
125 }
126 }
127
128 //==============================================================================
129 static bool isLeapYear (int year) noexcept
130 {
131 return (year % 400 == 0) || ((year % 100 != 0) && (year % 4 == 0));
132 }
133
134 static int daysFromJan1 (int year, int month) noexcept
135 {
136 const short dayOfYear[] = { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334,
137 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335 };
138
139 return dayOfYear [(isLeapYear (year) ? 12 : 0) + month];
140 }
141
142 static int64 daysFromYear0 (int year) noexcept
143 {
144 --year;
145 return 365 * year + (year / 400) - (year / 100) + (year / 4);
146 }
147
148 static int64 daysFrom1970 (int year) noexcept
149 {
150 return daysFromYear0 (year) - daysFromYear0 (1970);
151 }
152
153 static int64 daysFrom1970 (int year, int month) noexcept
154 {
155 if (month > 11)
156 {
157 year += month / 12;
158 month %= 12;
159 }
160 else if (month < 0)
161 {
162 auto numYears = (11 - month) / 12;
163 year -= numYears;
164 month += 12 * numYears;
165 }
166
167 return daysFrom1970 (year) + daysFromJan1 (year, month);
168 }
169
170 // There's no posix function that does a UTC version of mktime,
171 // so annoyingly we need to implement this manually..
172 static int64 mktime_utc (const std::tm& t) noexcept
173 {
174 return 24 * 3600 * (daysFrom1970 (t.tm_year + 1900, t.tm_mon) + (t.tm_mday - 1))
175 + 3600 * t.tm_hour
176 + 60 * t.tm_min
177 + t.tm_sec;
178 }
179
180 static Atomic<uint32> lastMSCounterValue { (uint32) 0 };
181
182 static String getUTCOffsetString (int utcOffsetSeconds, bool includeSemiColon)
183 {
184 if (const auto seconds = utcOffsetSeconds)
185 {
186 auto minutes = seconds / 60;
187
188 return String::formatted (includeSemiColon ? "%+03d:%02d"
189 : "%+03d%02d",
190 minutes / 60,
191 abs (minutes) % 60);
192 }
193
194 return "Z";
195 }
196}
197
198//==============================================================================
199 Time::Time (int64 ms) noexcept : millisSinceEpoch (ms) {}
200
201 Time::Time (int year, int month, int day,
202 int hours, int minutes, int seconds, int milliseconds,
203 bool useLocalTime) noexcept
204{
205 std::tm t;
206 t.tm_year = year - 1900;
207 t.tm_mon = month;
208 t.tm_mday = day;
209 t.tm_hour = hours;
210 t.tm_min = minutes;
211 t.tm_sec = seconds;
212 t.tm_isdst = -1;
213
214 millisSinceEpoch = 1000 * (useLocalTime ? (int64) mktime (&t)
215 : TimeHelpers::mktime_utc (t))
216 + milliseconds;
217}
218
219//==============================================================================
220int64 Time::currentTimeMillis() noexcept
221{
222 #if JUCE_WINDOWS && ! JUCE_MINGW
223 struct _timeb t;
224 _ftime_s (&t);
225 return ((int64) t.time) * 1000 + t.millitm;
226 #else
227 struct timeval tv;
228 gettimeofday (&tv, nullptr);
229 return ((int64) tv.tv_sec) * 1000 + tv.tv_usec / 1000;
230 #endif
231}
232
233 Time JUCE_CALLTYPE Time::getCurrentTime() noexcept
234{
235 return Time (currentTimeMillis());
236}
237
238//==============================================================================
239uint32 juce_millisecondsSinceStartup() noexcept;
240
241uint32 Time::getMillisecondCounter() noexcept
242{
243 auto now = juce_millisecondsSinceStartup();
244
245 if (now < TimeHelpers::lastMSCounterValue.get())
246 {
247 // in multi-threaded apps this might be called concurrently, so
248 // make sure that our last counter value only increases and doesn't
249 // go backwards..
250 if (now < TimeHelpers::lastMSCounterValue.get() - (uint32) 1000)
251 TimeHelpers::lastMSCounterValue = now;
252 }
253 else
254 {
255 TimeHelpers::lastMSCounterValue = now;
256 }
257
258 return now;
259}
260
261uint32 Time::getApproximateMillisecondCounter() noexcept
262{
263 auto t = TimeHelpers::lastMSCounterValue.get();
264 return t == 0 ? getMillisecondCounter() : t;
265}
266
267 void Time::waitForMillisecondCounter (uint32 targetTime) noexcept
268{
269 for (;;)
270 {
271 auto now = getMillisecondCounter();
272
273 if (now >= targetTime)
274 break;
275
276 auto toWait = (int) (targetTime - now);
277
278 if (toWait > 2)
279 {
280 Thread::sleep (jmin (20, toWait >> 1));
281 }
282 else
283 {
284 // xxx should consider using mutex_pause on the mac as it apparently
285 // makes it seem less like a spinlock and avoids lowering the thread pri.
286 for (int i = 10; --i >= 0;)
287 Thread::yield();
288 }
289 }
290}
291
292//==============================================================================
293 double Time::highResolutionTicksToSeconds (const int64 ticks) noexcept
294{
295 return (double) ticks / (double) getHighResolutionTicksPerSecond();
296}
297
298int64 Time::secondsToHighResolutionTicks (const double seconds) noexcept
299{
300 return (int64) (seconds * (double) getHighResolutionTicksPerSecond());
301}
302
303//==============================================================================
304 String Time::toString (bool includeDate,
305 bool includeTime,
306 bool includeSeconds,
307 bool use24HourClock) const
308{
309 String result;
310
311 if (includeDate)
312 {
313 result << getDayOfMonth() << ' '
314 << getMonthName (true) << ' '
315 << getYear();
316
317 if (includeTime)
318 result << ' ';
319 }
320
321 if (includeTime)
322 {
323 auto mins = getMinutes();
324
325 result << (use24HourClock ? getHours() : getHoursInAmPmFormat())
326 << (mins < 10 ? ":0" : ":") << mins;
327
328 if (includeSeconds)
329 {
330 auto secs = getSeconds();
331 result << (secs < 10 ? ":0" : ":") << secs;
332 }
333
334 if (! use24HourClock)
335 result << (isAfternoon() ? "pm" : "am");
336 }
337
338 return result.trimEnd();
339}
340
341 String Time::formatted (const String& format) const
342{
343 std::tm t (TimeHelpers::millisToLocal (millisSinceEpoch));
344 return TimeHelpers::formatString (format, &t);
345}
346
347//==============================================================================
348 int Time::getYear() const noexcept { return TimeHelpers::millisToLocal (millisSinceEpoch).tm_year + 1900; }
349 int Time::getMonth() const noexcept { return TimeHelpers::millisToLocal (millisSinceEpoch).tm_mon; }
350 int Time::getDayOfYear() const noexcept { return TimeHelpers::millisToLocal (millisSinceEpoch).tm_yday; }
351 int Time::getDayOfMonth() const noexcept { return TimeHelpers::millisToLocal (millisSinceEpoch).tm_mday; }
352 int Time::getDayOfWeek() const noexcept { return TimeHelpers::millisToLocal (millisSinceEpoch).tm_wday; }
353 int Time::getHours() const noexcept { return TimeHelpers::millisToLocal (millisSinceEpoch).tm_hour; }
354 int Time::getMinutes() const noexcept { return TimeHelpers::millisToLocal (millisSinceEpoch).tm_min; }
355 int Time::getSeconds() const noexcept { return TimeHelpers::extendedModulo (millisSinceEpoch / 1000, 60); }
356 int Time::getMilliseconds() const noexcept { return TimeHelpers::extendedModulo (millisSinceEpoch, 1000); }
357
358 int Time::getHoursInAmPmFormat() const noexcept
359{
360 auto hours = getHours();
361
362 if (hours == 0) return 12;
363 if (hours <= 12) return hours;
364
365 return hours - 12;
366}
367
368 bool Time::isAfternoon() const noexcept
369{
370 return getHours() >= 12;
371}
372
373 bool Time::isDaylightSavingTime() const noexcept
374{
375 return TimeHelpers::millisToLocal (millisSinceEpoch).tm_isdst != 0;
376}
377
378 String Time::getTimeZone() const
379{
380 String zone[2];
381
382 #if JUCE_WINDOWS && (JUCE_MSVC || JUCE_CLANG)
383 _tzset();
384
385 for (int i = 0; i < 2; ++i)
386 {
387 char name[128] = { 0 };
388 size_t length;
389 _get_tzname (&length, name, sizeof (name) - 1, i);
390 zone[i] = name;
391 }
392 #else
393 tzset();
394
395 auto zonePtr = (const char**) tzname;
396 zone[0] = zonePtr[0];
397 zone[1] = zonePtr[1];
398 #endif
399
400 if (isDaylightSavingTime())
401 {
402 zone[0] = zone[1];
403
404 if (zone[0].length() > 3
405 && zone[0].containsIgnoreCase ("daylight")
406 && zone[0].contains ("GMT"))
407 zone[0] = "BST";
408 }
409
410 return zone[0].substring (0, 3);
411}
412
413 int Time::getUTCOffsetSeconds() const noexcept
414{
415 return TimeHelpers::getUTCOffsetSeconds (millisSinceEpoch);
416}
417
418 String Time::getUTCOffsetString (bool includeSemiColon) const
419{
420 return TimeHelpers::getUTCOffsetString (getUTCOffsetSeconds(), includeSemiColon);
421}
422
423 String Time::toISO8601 (bool includeDividerCharacters) const
424{
425 return String::formatted (includeDividerCharacters ? "%04d-%02d-%02dT%02d:%02d:%06.03f"
426 : "%04d%02d%02dT%02d%02d%06.03f",
427 getYear(),
428 getMonth() + 1,
429 getDayOfMonth(),
430 getHours(),
431 getMinutes(),
432 getSeconds() + getMilliseconds() / 1000.0)
433 + getUTCOffsetString (includeDividerCharacters);
434}
435
436 static int parseFixedSizeIntAndSkip (String::CharPointerType& t, int numChars, char charToSkip) noexcept
437{
438 int n = 0;
439
440 for (int i = numChars; --i >= 0;)
441 {
442 auto digit = (int) (*t - '0');
443
444 if (! isPositiveAndBelow (digit, 10))
445 return -1;
446
447 ++t;
448 n = n * 10 + digit;
449 }
450
451 if (charToSkip != 0 && *t == (juce_wchar) charToSkip)
452 ++t;
453
454 return n;
455}
456
457 Time Time::fromISO8601 (StringRef iso)
458{
459 auto t = iso.text;
460 auto year = parseFixedSizeIntAndSkip (t, 4, '-');
461
462 if (year < 0)
463 return {};
464
465 auto month = parseFixedSizeIntAndSkip (t, 2, '-');
466
467 if (month < 0)
468 return {};
469
470 auto day = parseFixedSizeIntAndSkip (t, 2, 0);
471
472 if (day < 0)
473 return {};
474
475 int hours = 0, minutes = 0, milliseconds = 0;
476
477 if (*t == 'T')
478 {
479 ++t;
480 hours = parseFixedSizeIntAndSkip (t, 2, ':');
481
482 if (hours < 0)
483 return {};
484
485 minutes = parseFixedSizeIntAndSkip (t, 2, ':');
486
487 if (minutes < 0)
488 return {};
489
490 auto seconds = parseFixedSizeIntAndSkip (t, 2, 0);
491
492 if (seconds < 0)
493 return {};
494
495 if (*t == '.' || *t == ',')
496 {
497 ++t;
498 milliseconds = parseFixedSizeIntAndSkip (t, 3, 0);
499
500 if (milliseconds < 0)
501 return {};
502 }
503
504 milliseconds += 1000 * seconds;
505 }
506
507 auto nextChar = t.getAndAdvance();
508
509 if (nextChar == '-' || nextChar == '+')
510 {
511 auto offsetHours = parseFixedSizeIntAndSkip (t, 2, ':');
512
513 if (offsetHours < 0)
514 return {};
515
516 auto offsetMinutes = parseFixedSizeIntAndSkip (t, 2, 0);
517
518 if (offsetMinutes < 0)
519 return {};
520
521 auto offsetMs = (offsetHours * 60 + offsetMinutes) * 60 * 1000;
522 milliseconds += nextChar == '-' ? offsetMs : -offsetMs; // NB: this seems backwards but is correct!
523 }
524 else if (nextChar != 0 && nextChar != 'Z')
525 {
526 return {};
527 }
528
529 return Time (year, month - 1, day, hours, minutes, 0, milliseconds, false);
530}
531
532 String Time::getMonthName (const bool threeLetterVersion) const
533{
534 return getMonthName (getMonth(), threeLetterVersion);
535}
536
537 String Time::getWeekdayName (const bool threeLetterVersion) const
538{
539 return getWeekdayName (getDayOfWeek(), threeLetterVersion);
540}
541
542 static const char* const shortMonthNames[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
543 static const char* const longMonthNames[] = { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" };
544
545 String Time::getMonthName (int monthNumber, const bool threeLetterVersion)
546{
547 monthNumber %= 12;
548
549 return TRANS (threeLetterVersion ? shortMonthNames [monthNumber]
550 : longMonthNames [monthNumber]);
551}
552
553 String Time::getWeekdayName (int day, const bool threeLetterVersion)
554{
555 static const char* const shortDayNames[] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };
556 static const char* const longDayNames[] = { "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" };
557
558 day %= 7;
559
560 return TRANS (threeLetterVersion ? shortDayNames [day]
561 : longDayNames [day]);
562}
563
564//==============================================================================
565 Time& Time::operator+= (RelativeTime delta) noexcept { millisSinceEpoch += delta.inMilliseconds(); return *this; }
566 Time& Time::operator-= (RelativeTime delta) noexcept { millisSinceEpoch -= delta.inMilliseconds(); return *this; }
567
568 Time operator+ (Time time, RelativeTime delta) noexcept { Time t (time); return t += delta; }
569Time operator- (Time time, RelativeTime delta) noexcept { Time t (time); return t -= delta; }
570Time operator+ (RelativeTime delta, Time time) noexcept { Time t (time); return t += delta; }
571
572RelativeTime operator- (Time time1, Time time2) noexcept { return RelativeTime::milliseconds (time1.toMilliseconds() - time2.toMilliseconds()); }
573
574 bool operator== (Time time1, Time time2) noexcept { return time1.toMilliseconds() == time2.toMilliseconds(); }
575 bool operator!= (Time time1, Time time2) noexcept { return time1.toMilliseconds() != time2.toMilliseconds(); }
576 bool operator< (Time time1, Time time2) noexcept { return time1.toMilliseconds() < time2.toMilliseconds(); }
577 bool operator> (Time time1, Time time2) noexcept { return time1.toMilliseconds() > time2.toMilliseconds(); }
578 bool operator<= (Time time1, Time time2) noexcept { return time1.toMilliseconds() <= time2.toMilliseconds(); }
579 bool operator>= (Time time1, Time time2) noexcept { return time1.toMilliseconds() >= time2.toMilliseconds(); }
580
581 static int getMonthNumberForCompileDate (const String& m)
582{
583 for (int i = 0; i < 12; ++i)
584 if (m.equalsIgnoreCase (shortMonthNames[i]))
585 return i;
586
587 // If you hit this because your compiler has an unusual __DATE__
588 // format, let us know so we can add support for it!
589 jassertfalse;
590 return 0;
591}
592
593 Time Time::getCompilationDate()
594{
595 StringArray dateTokens, timeTokens;
596
597 dateTokens.addTokens (__DATE__, true);
598 dateTokens.removeEmptyStrings (true);
599
600 timeTokens.addTokens (__TIME__, ":", StringRef());
601
602 return Time (dateTokens[2].getIntValue(),
603 getMonthNumberForCompileDate (dateTokens[0]),
604 dateTokens[1].getIntValue(),
605 timeTokens[0].getIntValue(),
606 timeTokens[1].getIntValue());
607}
608
609
610//==============================================================================
611//==============================================================================
612#if JUCE_UNIT_TESTS
613
614 class TimeTests final : public UnitTest
615{
616 public:
617 TimeTests()
618 : UnitTest ("Time", UnitTestCategories::time)
619 {}
620
621 void runTest() override
622 {
623 beginTest ("Time");
624
625 Time t = Time::getCurrentTime();
626 expect (t > Time());
627
628 Thread::sleep (15);
629 expect (Time::getCurrentTime() > t);
630
631 expect (t.getTimeZone().isNotEmpty());
632 expect (t.getUTCOffsetString (true) == "Z" || t.getUTCOffsetString (true).length() == 6);
633 expect (t.getUTCOffsetString (false) == "Z" || t.getUTCOffsetString (false).length() == 5);
634
635 expect (TimeHelpers::getUTCOffsetString (-(3 * 60 + 15) * 60, true) == "-03:15");
636 expect (TimeHelpers::getUTCOffsetString (-(3 * 60 + 30) * 60, true) == "-03:30");
637 expect (TimeHelpers::getUTCOffsetString (-(3 * 60 + 45) * 60, true) == "-03:45");
638
639 expect (TimeHelpers::getUTCOffsetString ((3 * 60 + 15) * 60, true) == "+03:15");
640
641 expect (Time::fromISO8601 (t.toISO8601 (true)) == t);
642 expect (Time::fromISO8601 (t.toISO8601 (false)) == t);
643
644 expect (Time::fromISO8601 ("2016-02-16") == Time (2016, 1, 16, 0, 0, 0, 0, false));
645 expect (Time::fromISO8601 ("20160216Z") == Time (2016, 1, 16, 0, 0, 0, 0, false));
646
647 expect (Time::fromISO8601 ("2016-02-16T15:03:57+00:00") == Time (2016, 1, 16, 15, 3, 57, 0, false));
648 expect (Time::fromISO8601 ("20160216T150357+0000") == Time (2016, 1, 16, 15, 3, 57, 0, false));
649
650 expect (Time::fromISO8601 ("2016-02-16T15:03:57.999+00:00") == Time (2016, 1, 16, 15, 3, 57, 999, false));
651 expect (Time::fromISO8601 ("20160216T150357.999+0000") == Time (2016, 1, 16, 15, 3, 57, 999, false));
652 expect (Time::fromISO8601 ("2016-02-16T15:03:57.999Z") == Time (2016, 1, 16, 15, 3, 57, 999, false));
653 expect (Time::fromISO8601 ("2016-02-16T15:03:57,999Z") == Time (2016, 1, 16, 15, 3, 57, 999, false));
654 expect (Time::fromISO8601 ("20160216T150357.999Z") == Time (2016, 1, 16, 15, 3, 57, 999, false));
655 expect (Time::fromISO8601 ("20160216T150357,999Z") == Time (2016, 1, 16, 15, 3, 57, 999, false));
656
657 expect (Time::fromISO8601 ("2016-02-16T15:03:57.999-02:30") == Time (2016, 1, 16, 17, 33, 57, 999, false));
658 expect (Time::fromISO8601 ("2016-02-16T15:03:57,999-02:30") == Time (2016, 1, 16, 17, 33, 57, 999, false));
659 expect (Time::fromISO8601 ("20160216T150357.999-0230") == Time (2016, 1, 16, 17, 33, 57, 999, false));
660 expect (Time::fromISO8601 ("20160216T150357,999-0230") == Time (2016, 1, 16, 17, 33, 57, 999, false));
661
662 expect (Time (1970, 0, 1, 0, 0, 0, 0, false) == Time (0));
663 expect (Time (2106, 1, 7, 6, 28, 15, 0, false) == Time (4294967295000));
664 expect (Time (2007, 10, 7, 1, 7, 20, 0, false) == Time (1194397640000));
665 expect (Time (2038, 0, 19, 3, 14, 7, 0, false) == Time (2147483647000));
666 expect (Time (2016, 2, 7, 11, 20, 8, 0, false) == Time (1457349608000));
667 expect (Time (1969, 11, 31, 23, 59, 59, 0, false) == Time (-1000));
668 expect (Time (1901, 11, 13, 20, 45, 53, 0, false) == Time (-2147483647000));
669
670 expect (Time (1982, 1, 1, 12, 0, 0, 0, true) + RelativeTime::days (365) == Time (1983, 1, 1, 12, 0, 0, 0, true));
671 expect (Time (1970, 1, 1, 12, 0, 0, 0, true) + RelativeTime::days (365) == Time (1971, 1, 1, 12, 0, 0, 0, true));
672 expect (Time (2038, 1, 1, 12, 0, 0, 0, true) + RelativeTime::days (365) == Time (2039, 1, 1, 12, 0, 0, 0, true));
673
674 expect (Time (1982, 1, 1, 12, 0, 0, 0, false) + RelativeTime::days (365) == Time (1983, 1, 1, 12, 0, 0, 0, false));
675 expect (Time (1970, 1, 1, 12, 0, 0, 0, false) + RelativeTime::days (365) == Time (1971, 1, 1, 12, 0, 0, 0, false));
676 expect (Time (2038, 1, 1, 12, 0, 0, 0, false) + RelativeTime::days (365) == Time (2039, 1, 1, 12, 0, 0, 0, false));
677 }
678};
679
680 static TimeTests timeTests;
681
682#endif
683
684} // namespace juce
juce::RelativeTime
Definition juce_RelativeTime.h:37
juce::RelativeTime::milliseconds
static RelativeTime milliseconds(int milliseconds) noexcept
Definition juce_RelativeTime.cpp:31
juce::StringArray
Definition juce_StringArray.h:35
juce::StringArray::removeEmptyStrings
void removeEmptyStrings(bool removeWhitespaceStrings=true)
Definition juce_StringArray.cpp:250
juce::StringArray::addTokens
int addTokens(StringRef stringToTokenise, bool preserveQuotedStrings)
Definition juce_StringArray.cpp:329
juce::StringRef
Definition juce_StringRef.h:62
juce::StringRef::text
String::CharPointerType text
Definition juce_StringRef.h:130
juce::String
Definition juce_String.h:53
juce::String::formatted
static String formatted(const String &formatStr, Args... args)
Definition juce_String.h:920
juce::String::trimEnd
String trimEnd() const
Definition juce_String.cpp:1687
juce::String::substring
String substring(int startIndex, int endIndex) const
Definition juce_String.cpp:1498
juce::Thread::sleep
static void JUCE_CALLTYPE sleep(int milliseconds)
juce::Thread::yield
static void JUCE_CALLTYPE yield()
juce::Time
Definition juce_Time.h:37
juce::Time::isDaylightSavingTime
bool isDaylightSavingTime() const noexcept
Definition juce_Time.cpp:373
juce::Time::getApproximateMillisecondCounter
static uint32 getApproximateMillisecondCounter() noexcept
Definition juce_Time.cpp:261
juce::Time::getTimeZone
String getTimeZone() const
Definition juce_Time.cpp:378
juce::Time::Time
Time()=default
juce::Time::getUTCOffsetString
String getUTCOffsetString(bool includeDividerCharacters) const
Definition juce_Time.cpp:418
juce::Time::getHoursInAmPmFormat
int getHoursInAmPmFormat() const noexcept
Definition juce_Time.cpp:358
juce::Time::fromISO8601
static Time fromISO8601(StringRef iso8601)
Definition juce_Time.cpp:457
juce::Time::getMilliseconds
int getMilliseconds() const noexcept
Definition juce_Time.cpp:356
juce::Time::getWeekdayName
String getWeekdayName(bool threeLetterVersion) const
Definition juce_Time.cpp:537
juce::Time::getDayOfMonth
int getDayOfMonth() const noexcept
Definition juce_Time.cpp:351
juce::Time::currentTimeMillis
static int64 currentTimeMillis() noexcept
Definition juce_Time.cpp:220
juce::Time::getUTCOffsetSeconds
int getUTCOffsetSeconds() const noexcept
Definition juce_Time.cpp:413
juce::Time::getMonth
int getMonth() const noexcept
Definition juce_Time.cpp:349
juce::Time::getCurrentTime
static Time JUCE_CALLTYPE getCurrentTime() noexcept
Definition juce_Time.cpp:233
juce::Time::toString
String toString(bool includeDate, bool includeTime, bool includeSeconds=true, bool use24HourClock=false) const
Definition juce_Time.cpp:304
juce::Time::isAfternoon
bool isAfternoon() const noexcept
Definition juce_Time.cpp:368
juce::Time::operator-=
Time & operator-=(RelativeTime delta) noexcept
Definition juce_Time.cpp:566
juce::Time::getYear
int getYear() const noexcept
Definition juce_Time.cpp:348
juce::Time::getCompilationDate
static Time getCompilationDate()
Definition juce_Time.cpp:593
juce::Time::highResolutionTicksToSeconds
static double highResolutionTicksToSeconds(int64 ticks) noexcept
Definition juce_Time.cpp:293
juce::Time::getDayOfYear
int getDayOfYear() const noexcept
Definition juce_Time.cpp:350
juce::Time::secondsToHighResolutionTicks
static int64 secondsToHighResolutionTicks(double seconds) noexcept
Definition juce_Time.cpp:298
juce::Time::getMonthName
String getMonthName(bool threeLetterVersion) const
Definition juce_Time.cpp:532
juce::Time::getMinutes
int getMinutes() const noexcept
Definition juce_Time.cpp:354
juce::Time::operator+=
Time & operator+=(RelativeTime delta) noexcept
Definition juce_Time.cpp:565
juce::Time::waitForMillisecondCounter
static void waitForMillisecondCounter(uint32 targetTime) noexcept
Definition juce_Time.cpp:267
juce::Time::formatted
String formatted(const String &format) const
Definition juce_Time.cpp:341
juce::Time::toISO8601
String toISO8601(bool includeDividerCharacters) const
Definition juce_Time.cpp:423
juce::Time::getHours
int getHours() const noexcept
Definition juce_Time.cpp:353
juce::Time::getMillisecondCounter
static uint32 getMillisecondCounter() noexcept
Definition juce_Time.cpp:241
juce::Time::getSeconds
int getSeconds() const noexcept
Definition juce_Time.cpp:355
juce::Time::getDayOfWeek
int getDayOfWeek() const noexcept
Definition juce_Time.cpp:352
juce::UnitTest
Definition juce_UnitTest.h:70