2021-02-14 18:01:12 +01:00
/*
* Copyright ( c ) 2021 , Ben Wiederhake < BenWiederhake . GitHub @ gmx . de >
*
2021-04-22 01:24:48 -07:00
* SPDX - License - Identifier : BSD - 2 - Clause
2021-02-14 18:01:12 +01:00
*/
2025-10-02 08:58:48 -05:00
# include <LibTest/Macros.h>
2021-04-24 23:53:23 -06:00
# include <LibTest/TestCase.h>
2021-02-14 18:01:12 +01:00
# include <AK/Time.h>
2025-06-21 17:18:45 +02:00
# ifdef AK_OS_WINDOWS
# include <time.h>
# define gmtime_r(time, tm) gmtime_s(tm, time)
# endif
2024-07-16 23:47:22 -06:00
using AK : : Duration ;
2025-05-19 16:16:18 -07:00
# if (defined(__TIMESIZE) && __TIMESIZE < 64) || defined(AK_OS_WINDOWS) // NOTE: See AK/Time.h, on Windows we hardcode to long's for timeval
2023-09-03 21:30:36 +03:00
# define TIME_T_IS_32BIT
# endif
2023-03-13 16:30:34 +01:00
# define EXPECT_DURATION(t, s, ns) \
2021-02-14 18:01:12 +01:00
do { \
auto ts = ( t ) . to_timespec ( ) ; \
EXPECT_EQ ( ts . tv_sec , ( s ) ) ; \
EXPECT_EQ ( ts . tv_nsec , ( ns ) ) ; \
} while ( 0 )
TEST_CASE ( is_sane )
{
2023-03-13 16:30:34 +01:00
auto t0 = Duration : : from_seconds ( 0 ) ;
auto t2 = Duration : : from_seconds ( 2 ) ;
auto t5 = Duration : : from_seconds ( 5 ) ;
auto tn3 = Duration : : from_seconds ( - 3 ) ;
2021-02-14 18:01:12 +01:00
EXPECT ( t0 = = t0 ) ;
EXPECT ( t2 = = t2 ) ;
EXPECT ( t5 = = t5 ) ;
EXPECT ( t0 ! = t2 ) ;
EXPECT ( t2 ! = tn3 ) ;
EXPECT ( t2 ! = t5 ) ;
2023-03-13 16:30:34 +01:00
EXPECT_DURATION ( t0 , 0 , 0 ) ;
EXPECT_DURATION ( t2 , 2 , 0 ) ;
EXPECT_DURATION ( t5 , 5 , 0 ) ;
EXPECT_DURATION ( t2 + t5 , 7 , 0 ) ;
EXPECT_DURATION ( tn3 + t2 , - 1 , 0 ) ;
EXPECT_DURATION ( tn3 + t5 , 2 , 0 ) ;
2021-02-14 18:01:12 +01:00
}
TEST_CASE ( limits )
{
2023-03-13 16:30:34 +01:00
EXPECT_DURATION ( Duration : : min ( ) , ( i64 ) - 0x8000'0000'0000'0000 , 0 ) ;
EXPECT_DURATION ( Duration : : max ( ) , 0x7fff'ffff'ffff'ffff , 999'999'999 ) ;
2021-02-14 18:01:12 +01:00
}
TEST_CASE ( seconds_parsing )
{
2023-03-13 16:30:34 +01:00
EXPECT_DURATION ( Duration : : from_seconds ( 0 ) , 0 , 0 ) ;
EXPECT_DURATION ( Duration : : from_seconds ( 42 ) , 42 , 0 ) ;
EXPECT_DURATION ( Duration : : from_seconds ( - 1 ) , - 1 , 0 ) ;
2021-02-14 18:01:12 +01:00
// "6.4.4.1.5: The type of an integer constant is the first of the corresponding list in which its value can be represented."
// In the case of "0x8000'0000", the list is "int, unsigned int, …", and unsigned int (u32) matches.
// Then the unary minus: On unsigned 32-bit integers, -0x8000'0000 == 0x8000'0000, which only then is made signed again.
// So we would pass a medium-large *positive* number to 'from_seconds', which is not what we want to test here.
// That's why this is the only place that needs an "LL" suffix.
2023-03-13 16:30:34 +01:00
EXPECT_DURATION ( Duration : : from_seconds ( - 0x8000'0000LL ) , - 0x8000'0000LL , 0 ) ;
EXPECT_DURATION ( Duration : : from_seconds ( - 0x8000'0000'0000'0000 ) , ( i64 ) - 0x8000'0000'0000'0000 , 0 ) ;
EXPECT_DURATION ( Duration : : from_seconds ( 0x7fff'ffff'ffff'ffff ) , 0x7fff'ffff'ffff'ffff , 0 ) ;
2021-02-14 18:01:12 +01:00
}
TEST_CASE ( timespec_parsing )
{
2023-03-13 16:30:34 +01:00
EXPECT_DURATION ( Duration : : from_timespec ( timespec { 2 , 4 } ) , 2 , 4 ) ;
EXPECT_DURATION ( Duration : : from_timespec ( timespec { 1234 , 5678 } ) , 1234 , 5678 ) ;
EXPECT_DURATION ( Duration : : from_timespec ( timespec { 0 , 1'000'000'000 } ) , 1 , 0 ) ;
EXPECT_DURATION ( Duration : : from_timespec ( timespec { 8 , 2'000'000'000 } ) , 10 , 0 ) ;
EXPECT_DURATION ( Duration : : from_timespec ( timespec { 0 , 2'147'483'647 } ) , 2 , 147'483'647 ) ;
EXPECT_DURATION ( Duration : : from_timespec ( timespec { 1 , - 1 } ) , 0 , 999'999'999 ) ;
EXPECT_DURATION ( Duration : : from_timespec ( timespec { 0 , - 1 } ) , - 1 , 999'999'999 ) ;
EXPECT_DURATION ( Duration : : from_timespec ( timespec { - 1 , 0 } ) , - 1 , 0 ) ;
EXPECT_DURATION ( Duration : : from_timespec ( timespec { - 1 , 1'000'000'001 } ) , 0 , 1 ) ;
EXPECT_DURATION ( Duration : : from_timespec ( timespec { - 2 , 2'000'000'003 } ) , 0 , 3 ) ;
EXPECT_DURATION ( Duration : : from_timespec ( timespec { - 2 , 1'999'999'999 } ) , - 1 , 999'999'999 ) ;
2023-09-03 21:30:36 +03:00
# ifndef TIME_T_IS_32BIT
2023-03-13 16:30:34 +01:00
EXPECT_DURATION ( Duration : : from_timespec ( timespec { 0x7fff'ffff'ffff'fffe , 999'999'998 } ) , 0x7fff'ffff'ffff'fffe , 999'999'998 ) ;
EXPECT_DURATION ( Duration : : from_timespec ( timespec { 0x7fff'ffff'ffff'fffe , 1'999'999'998 } ) , 0x7fff'ffff'ffff'ffff , 999'999'998 ) ;
EXPECT_DURATION ( Duration : : from_timespec ( timespec { 0x7fff'ffff'ffff'fffe , 1'999'999'999 } ) , 0x7fff'ffff'ffff'ffff , 999'999'999 ) ;
EXPECT_DURATION ( Duration : : from_timespec ( timespec { 0x7fff'ffff'ffff'fffe , 2'000'000'000 } ) , 0x7fff'ffff'ffff'ffff , 999'999'999 ) ;
EXPECT_DURATION ( Duration : : from_timespec ( timespec { - 0x7fff'ffff'ffff'fffe , - 1 } ) , - 0x7fff'ffff'ffff'ffff , 999'999'999 ) ;
EXPECT_DURATION ( Duration : : from_timespec ( timespec { - 0x7fff'ffff'ffff'fffe , - 999'999'999 } ) , - 0x7fff'ffff'ffff'ffff , 1 ) ;
EXPECT_DURATION ( Duration : : from_timespec ( timespec { - 0x7fff'ffff'ffff'fffe , - 1'999'999'999 } ) , ( i64 ) - 0x8000'0000'0000'0000 , 1 ) ;
EXPECT_DURATION ( Duration : : from_timespec ( timespec { - 0x7fff'ffff'ffff'fffe , - 2'000'000'000 } ) , ( i64 ) - 0x8000'0000'0000'0000 , 0 ) ;
EXPECT_DURATION ( Duration : : from_timespec ( timespec { - 0x7fff'ffff'ffff'fffe , - 2'000'000'001 } ) , ( i64 ) - 0x8000'0000'0000'0000 , 0 ) ;
2023-09-03 21:30:36 +03:00
# endif
2021-02-14 18:01:12 +01:00
}
TEST_CASE ( timeval_parsing )
{
2023-03-13 16:30:34 +01:00
EXPECT_DURATION ( Duration : : from_timeval ( timeval { 2 , 4 } ) , 2 , 4'000 ) ;
EXPECT_DURATION ( Duration : : from_timeval ( timeval { 1234 , 5'678 } ) , 1234 , 5'678'000 ) ;
EXPECT_DURATION ( Duration : : from_timeval ( timeval { - 123 , - 45'678 } ) , - 124 , 954'322'000 ) ;
EXPECT_DURATION ( Duration : : from_timeval ( timeval { 0 , 1'000'000 } ) , 1 , 0 ) ;
EXPECT_DURATION ( Duration : : from_timeval ( timeval { 0 , 1'000'000'000 } ) , 1'000 , 0 ) ;
EXPECT_DURATION ( Duration : : from_timeval ( timeval { 8 , 2'000'000 } ) , 10 , 0 ) ;
EXPECT_DURATION ( Duration : : from_timeval ( timeval { 0 , 2'147'483'647 } ) , 2'147 , 483'647'000 ) ;
EXPECT_DURATION ( Duration : : from_timeval ( timeval { 1 , - 1 } ) , 0 , 999'999'000 ) ;
EXPECT_DURATION ( Duration : : from_timeval ( timeval { 0 , - 1 } ) , - 1 , 999'999'000 ) ;
EXPECT_DURATION ( Duration : : from_timeval ( timeval { - 1 , 0 } ) , - 1 , 0 ) ;
EXPECT_DURATION ( Duration : : from_timeval ( timeval { - 1 , 1'000'001 } ) , 0 , 1'000 ) ;
EXPECT_DURATION ( Duration : : from_timeval ( timeval { - 2 , 2'000'003 } ) , 0 , 3'000 ) ;
EXPECT_DURATION ( Duration : : from_timeval ( timeval { - 2 , 1'999'999 } ) , - 1 , 999'999'000 ) ;
2023-09-03 21:30:36 +03:00
# ifndef TIME_T_IS_32BIT
2023-03-13 16:30:34 +01:00
EXPECT_DURATION ( Duration : : from_timeval ( timeval { 0x7fff'ffff'ffff'fffe , 999'998 } ) , 0x7fff'ffff'ffff'fffe , 999'998'000 ) ;
EXPECT_DURATION ( Duration : : from_timeval ( timeval { 0x7fff'ffff'ffff'fffe , 1'999'998 } ) , 0x7fff'ffff'ffff'ffff , 999'998'000 ) ;
EXPECT_DURATION ( Duration : : from_timeval ( timeval { 0x7fff'ffff'ffff'fffe , 1'999'999 } ) , 0x7fff'ffff'ffff'ffff , 999'999'000 ) ;
EXPECT_DURATION ( Duration : : from_timeval ( timeval { 0x7fff'ffff'ffff'fffe , 2'000'000 } ) , 0x7fff'ffff'ffff'ffff , 999'999'999 ) ;
EXPECT_DURATION ( Duration : : from_timeval ( timeval { - 0x7fff'ffff'ffff'fffe , - 1 } ) , - 0x7fff'ffff'ffff'ffff , 999'999'000 ) ;
EXPECT_DURATION ( Duration : : from_timeval ( timeval { - 0x7fff'ffff'ffff'fffe , - 999'999 } ) , - 0x7fff'ffff'ffff'ffff , 1'000 ) ;
EXPECT_DURATION ( Duration : : from_timeval ( timeval { - 0x7fff'ffff'ffff'fffe , - 1'999'999 } ) , ( i64 ) - 0x8000'0000'0000'0000 , 1'000 ) ;
EXPECT_DURATION ( Duration : : from_timeval ( timeval { - 0x7fff'ffff'ffff'fffe , - 2'000'000 } ) , ( i64 ) - 0x8000'0000'0000'0000 , 0 ) ;
EXPECT_DURATION ( Duration : : from_timeval ( timeval { - 0x7fff'ffff'ffff'fffe , - 2'000'001 } ) , ( i64 ) - 0x8000'0000'0000'0000 , 0 ) ;
2023-09-03 21:30:36 +03:00
# endif
2021-02-14 18:01:12 +01:00
}
2023-03-13 16:30:34 +01:00
# define DURATION(s, ns) \
Duration : : from_timespec ( timespec { ( s ) , ( ns ) } )
2021-02-14 18:01:12 +01:00
TEST_CASE ( addition )
{
2023-03-13 16:30:34 +01:00
# define EXPECT_ADDITION(s1, ns1, s2, ns2, sr, nsr) \
do { \
EXPECT_DURATION ( DURATION ( s1 , ns1 ) + DURATION ( s2 , ns2 ) , sr , nsr ) ; \
EXPECT_DURATION ( DURATION ( s2 , ns2 ) + DURATION ( s1 , ns1 ) , sr , nsr ) ; \
auto t = DURATION ( s1 , ns1 ) ; \
t + = DURATION ( s2 , ns2 ) ; \
EXPECT_DURATION ( t , sr , nsr ) ; \
2021-03-07 23:34:13 -07:00
} while ( 0 )
2021-02-14 18:01:12 +01:00
EXPECT_ADDITION ( 11 , 123'456'789 , 22 , 900'000'000 , 34 , 23'456'789 ) ;
2023-09-03 21:30:36 +03:00
# ifndef TIME_T_IS_32BIT
2021-02-14 18:01:12 +01:00
EXPECT_ADDITION ( 0 , 0 , 9223372036854775807LL , 999'999'998 , 0x7fff'ffff'ffff'ffff , 999'999'998 ) ;
EXPECT_ADDITION ( 0 , 1 , 9223372036854775807LL , 999'999'998 , 0x7fff'ffff'ffff'ffff , 999'999'999 ) ;
EXPECT_ADDITION ( 0 , 2 , 9223372036854775807LL , 999'999'998 , 0x7fff'ffff'ffff'ffff , 999'999'999 ) ;
EXPECT_ADDITION ( 0x80 , 40 , 0x7fff'ffff'ffff'ff7f , 999'999'958 , 0x7fff'ffff'ffff'ffff , 999'999'998 ) ;
EXPECT_ADDITION ( 0x80 , 41 , 0x7fff'ffff'ffff'ff7f , 999'999'958 , 0x7fff'ffff'ffff'ffff , 999'999'999 ) ;
EXPECT_ADDITION ( 0x80 , 42 , 0x7fff'ffff'ffff'ff7f , 999'999'958 , 0x7fff'ffff'ffff'ffff , 999'999'999 ) ;
2023-09-03 21:30:36 +03:00
# endif
2021-02-14 18:01:12 +01:00
EXPECT_ADDITION ( - 2 , 5 , - 3 , 7 , - 5 , 12 ) ;
EXPECT_ADDITION ( - 2 , 999'999'995 , - 3 , 999'999'997 , - 4 , 999'999'992 ) ;
2023-09-03 21:30:36 +03:00
# ifndef TIME_T_IS_32BIT
2021-02-14 18:01:12 +01:00
EXPECT_ADDITION ( - 0x7fff'ffff'ffff'ffff , 999'999'995 , - 1 , 6 , - 0x7fff'ffff'ffff'ffff , 1 ) ;
EXPECT_ADDITION ( - 0x7fff'ffff'ffff'ffff , 999'999'995 , - 2 , 6 , ( i64 ) - 0x8000'0000'0000'0000 , 1 ) ;
EXPECT_ADDITION ( - 0x7fff'ffff'ffff'ffff , 999'999'995 , - 2 , 5 , ( i64 ) - 0x8000'0000'0000'0000 , 0 ) ;
EXPECT_ADDITION ( - 0x7fff'ffff'ffff'ffff , 999'999'995 , - 2 , 4 , ( i64 ) - 0x8000'0000'0000'0000 , 0 ) ;
EXPECT_ADDITION ( ( i64 ) - 0x8000'0000'0000'0000 , 999'999'995 , 0x7fff'ffff'ffff'ffff , 4 , - 1 , 999'999'999 ) ;
EXPECT_ADDITION ( ( i64 ) - 0x8000'0000'0000'0000 , 999'999'995 , 0x7fff'ffff'ffff'ffff , 5 , 0 , 0 ) ;
EXPECT_ADDITION ( ( i64 ) - 0x8000'0000'0000'0000 , 999'999'995 , 0x7fff'ffff'ffff'ffff , 6 , 0 , 1 ) ;
2023-09-03 21:30:36 +03:00
# endif
2021-02-14 18:01:12 +01:00
# undef EXPECT_ADDITION
}
TEST_CASE ( subtraction )
{
2023-03-13 16:30:34 +01:00
# define EXPECT_SUBTRACTION(s1, ns1, s2, ns2, sr, nsr) \
do { \
EXPECT_DURATION ( DURATION ( s1 , ns1 ) - DURATION ( s2 , ns2 ) , sr , nsr ) ; \
auto t = DURATION ( s1 , ns1 ) ; \
t - = DURATION ( s2 , ns2 ) ; \
EXPECT_DURATION ( t , sr , nsr ) ; \
2021-03-07 23:34:13 -07:00
} while ( 0 )
2021-02-14 18:01:12 +01:00
EXPECT_SUBTRACTION ( 5 , 0 , 3 , 0 , 2 , 0 ) ;
EXPECT_SUBTRACTION ( 0 , 0 , 0 , 0 , 0 , 0 ) ;
EXPECT_SUBTRACTION ( 0 , 5 , 0 , 3 , 0 , 2 ) ;
2023-09-03 21:30:36 +03:00
# ifndef TIME_T_IS_32BIT
2021-02-14 18:01:12 +01:00
EXPECT_SUBTRACTION ( 0x7fff'ffff'ffff'ffff , 999'999'999 , 8 , 123 , 0x7fff'ffff'ffff'fff7 , 999'999'876 ) ;
2023-09-03 21:30:36 +03:00
# endif
2021-02-14 18:01:12 +01:00
EXPECT_SUBTRACTION ( 1 , 0 , 0 , 999'999'999 , 0 , 1 ) ;
2023-09-03 21:30:36 +03:00
# ifndef TIME_T_IS_32BIT
2021-02-14 18:01:12 +01:00
EXPECT_SUBTRACTION ( 0x7fff'ffff'ffff'ffff , 0 , 1 , 999'999'999 , 0x7fff'ffff'ffff'fffd , 1 ) ;
2023-09-03 21:30:36 +03:00
# endif
2021-02-14 18:01:12 +01:00
EXPECT_SUBTRACTION ( 3 , 0 , 5 , 0 , - 2 , 0 ) ;
EXPECT_SUBTRACTION ( 0 , 3 , 0 , 5 , - 1 , 999'999'998 ) ;
2023-09-03 21:30:36 +03:00
# ifndef TIME_T_IS_32BIT
2021-02-14 18:01:12 +01:00
EXPECT_SUBTRACTION ( 0 , 0 , 0x7fff'ffff'ffff'ffff , 999'999'999 , ( i64 ) - 0x8000'0000'0000'0000 , 1 ) ;
EXPECT_SUBTRACTION ( 0 , 0 , ( i64 ) - 0x8000'0000'0000'0000 , 0 , 0x7fff'ffff'ffff'ffff , 999'999'999 ) ;
EXPECT_SUBTRACTION ( - 1 , 999'999'999 , ( i64 ) - 0x8000'0000'0000'0000 , 0 , 0x7fff'ffff'ffff'ffff , 999'999'999 ) ;
EXPECT_SUBTRACTION ( - 1 , 999'999'998 , ( i64 ) - 0x8000'0000'0000'0000 , 0 , 0x7fff'ffff'ffff'ffff , 999'999'998 ) ;
2023-09-03 21:30:36 +03:00
# endif
2021-02-14 18:01:12 +01:00
EXPECT_SUBTRACTION ( 123 , 456 , 123 , 455 , 0 , 1 ) ;
EXPECT_SUBTRACTION ( 123 , 456 , 123 , 456 , 0 , 0 ) ;
EXPECT_SUBTRACTION ( 123 , 456 , 123 , 457 , - 1 , 999'999'999 ) ;
EXPECT_SUBTRACTION ( 124 , 456 , 123 , 455 , 1 , 1 ) ;
EXPECT_SUBTRACTION ( 124 , 456 , 123 , 456 , 1 , 0 ) ;
EXPECT_SUBTRACTION ( 124 , 456 , 123 , 457 , 0 , 999'999'999 ) ;
2023-09-03 21:30:36 +03:00
# ifndef TIME_T_IS_32BIT
2021-02-14 18:01:12 +01:00
EXPECT_SUBTRACTION ( - 0x7fff'ffff'ffff'ffff , 999'999'995 , 1 , 999'999'994 , ( i64 ) - 0x8000'0000'0000'0000 , 1 ) ;
EXPECT_SUBTRACTION ( - 0x7fff'ffff'ffff'ffff , 999'999'995 , 1 , 999'999'995 , ( i64 ) - 0x8000'0000'0000'0000 , 0 ) ;
EXPECT_SUBTRACTION ( - 0x7fff'ffff'ffff'ffff , 999'999'995 , 1 , 999'999'996 , ( i64 ) - 0x8000'0000'0000'0000 , 0 ) ;
2023-09-03 21:30:36 +03:00
# endif
2021-02-14 18:01:12 +01:00
}
2021-03-07 23:34:13 -07:00
TEST_CASE ( rounding )
{
2023-03-13 16:30:34 +01:00
EXPECT_EQ ( DURATION ( 2 , 800'800'800 ) . to_seconds ( ) , 3 ) ;
EXPECT_EQ ( DURATION ( 2 , 800'800'800 ) . to_milliseconds ( ) , 2'801 ) ;
EXPECT_EQ ( DURATION ( 2 , 800'800'800 ) . to_microseconds ( ) , 2'800'801 ) ;
EXPECT_EQ ( DURATION ( 2 , 800'800'800 ) . to_nanoseconds ( ) , 2'800'800'800 ) ;
EXPECT_EQ ( DURATION ( - 2 , 800'800'800 ) . to_seconds ( ) , - 2 ) ;
EXPECT_EQ ( DURATION ( - 2 , 800'800'800 ) . to_milliseconds ( ) , - 1'200 ) ;
EXPECT_EQ ( DURATION ( - 2 , 800'800'800 ) . to_microseconds ( ) , - 1'199'200 ) ;
EXPECT_EQ ( DURATION ( - 2 , 800'800'800 ) . to_nanoseconds ( ) , - 1'199'199'200 ) ;
EXPECT_EQ ( DURATION ( 0 , 0 ) . to_seconds ( ) , 0 ) ;
EXPECT_EQ ( DURATION ( 0 , 0 ) . to_milliseconds ( ) , 0 ) ;
EXPECT_EQ ( DURATION ( 0 , 0 ) . to_microseconds ( ) , 0 ) ;
EXPECT_EQ ( DURATION ( 0 , 0 ) . to_nanoseconds ( ) , 0 ) ;
EXPECT_EQ ( DURATION ( 0 , 1 ) . to_seconds ( ) , 1 ) ;
EXPECT_EQ ( DURATION ( 0 , 1 ) . to_milliseconds ( ) , 1 ) ;
EXPECT_EQ ( DURATION ( 0 , 1 ) . to_microseconds ( ) , 1 ) ;
EXPECT_EQ ( DURATION ( 0 , 1 ) . to_nanoseconds ( ) , 1 ) ;
EXPECT_EQ ( DURATION ( 0 , - 1 ) . to_seconds ( ) , - 1 ) ;
EXPECT_EQ ( DURATION ( 0 , - 1 ) . to_milliseconds ( ) , - 1 ) ;
EXPECT_EQ ( DURATION ( 0 , - 1 ) . to_microseconds ( ) , - 1 ) ;
EXPECT_EQ ( DURATION ( 0 , - 1 ) . to_nanoseconds ( ) , - 1 ) ;
2023-09-03 21:30:36 +03:00
# ifndef TIME_T_IS_32BIT
2023-03-13 16:30:34 +01:00
EXPECT_EQ ( DURATION ( - 9223372037 , 145'224'191 ) . to_nanoseconds ( ) , ( i64 ) - 0x8000'0000'0000'0000 ) ;
EXPECT_EQ ( DURATION ( - 9223372037 , 145'224'192 ) . to_nanoseconds ( ) , ( i64 ) - 0x8000'0000'0000'0000 ) ;
EXPECT_EQ ( DURATION ( - 9223372037 , 145'224'193 ) . to_nanoseconds ( ) , - 0x7fff'ffff'ffff'ffff ) ;
EXPECT_EQ ( DURATION ( 9223372036 , 854'775'806 ) . to_nanoseconds ( ) , 0x7fff'ffff'ffff'fffe ) ;
EXPECT_EQ ( DURATION ( 9223372036 , 854'775'807 ) . to_nanoseconds ( ) , 0x7fff'ffff'ffff'ffff ) ;
EXPECT_EQ ( DURATION ( 9223372036 , 854'775'808 ) . to_nanoseconds ( ) , 0x7fff'ffff'ffff'ffff ) ;
2023-09-03 21:30:36 +03:00
# endif
2021-03-07 23:34:13 -07:00
}
2021-02-27 23:54:10 +01:00
TEST_CASE ( truncation )
{
2021-03-11 22:12:04 +01:00
// Sanity
2023-03-13 16:30:34 +01:00
EXPECT_EQ ( DURATION ( 2 , 0 ) . to_truncated_seconds ( ) , 2 ) ;
EXPECT_EQ ( DURATION ( - 2 , 0 ) . to_truncated_seconds ( ) , - 2 ) ;
EXPECT_EQ ( DURATION ( 2 , 800'800'800 ) . to_truncated_seconds ( ) , 2 ) ;
EXPECT_EQ ( DURATION ( 2 , 800'800'800 ) . to_truncated_milliseconds ( ) , 2'800 ) ;
EXPECT_EQ ( DURATION ( 2 , 800'800'800 ) . to_truncated_microseconds ( ) , 2'800'800 ) ;
EXPECT_EQ ( DURATION ( - 2 , - 800'800'800 ) . to_truncated_seconds ( ) , - 2 ) ;
EXPECT_EQ ( DURATION ( - 2 , - 800'800'800 ) . to_truncated_milliseconds ( ) , - 2'800 ) ;
EXPECT_EQ ( DURATION ( - 2 , - 800'800'800 ) . to_truncated_microseconds ( ) , - 2'800'800 ) ;
2021-02-27 23:54:10 +01:00
2021-03-11 22:12:04 +01:00
// Overflow, seconds
2023-03-13 16:30:34 +01:00
EXPECT_EQ ( Duration : : min ( ) . to_truncated_seconds ( ) , ( i64 ) - 0x8000'0000'0000'0000 ) ;
EXPECT_EQ ( Duration : : max ( ) . to_truncated_seconds ( ) , 0x7fff'ffff'ffff'ffff ) ;
2021-03-11 22:12:04 +01:00
2023-09-03 21:30:36 +03:00
# ifndef TIME_T_IS_32BIT
2021-03-11 22:12:04 +01:00
// Overflow, milliseconds
2023-03-13 16:30:34 +01:00
EXPECT_EQ ( DURATION ( - 9223372036854776 , 191'000'000 ) . to_truncated_milliseconds ( ) , ( i64 ) - 0x8000'0000'0000'0000 ) ;
EXPECT_EQ ( DURATION ( - 9223372036854776 , 192'000'000 ) . to_truncated_milliseconds ( ) , ( i64 ) - 0x8000'0000'0000'0000 ) ;
EXPECT_EQ ( DURATION ( - 9223372036854776 , 192'000'001 ) . to_truncated_milliseconds ( ) , - 0x7fff'ffff'ffff'ffff ) ;
EXPECT_EQ ( DURATION ( - 9223372036854776 , 193'000'000 ) . to_truncated_milliseconds ( ) , - 0x7fff'ffff'ffff'ffff ) ;
EXPECT_EQ ( DURATION ( 9223372036854775 , 806'000'000 ) . to_truncated_milliseconds ( ) , 0x7fff'ffff'ffff'fffe ) ;
EXPECT_EQ ( DURATION ( 9223372036854775 , 806'999'999 ) . to_truncated_milliseconds ( ) , 0x7fff'ffff'ffff'fffe ) ;
EXPECT_EQ ( DURATION ( 9223372036854775 , 807'000'000 ) . to_truncated_milliseconds ( ) , 0x7fff'ffff'ffff'ffff ) ;
EXPECT_EQ ( DURATION ( 9223372036854775 , 808'000'000 ) . to_truncated_milliseconds ( ) , 0x7fff'ffff'ffff'ffff ) ;
2021-03-11 22:12:04 +01:00
// Overflow, microseconds
2023-03-13 16:30:34 +01:00
EXPECT_EQ ( DURATION ( - 9223372036855 , 224'191'000 ) . to_truncated_microseconds ( ) , ( i64 ) - 0x8000'0000'0000'0000 ) ;
EXPECT_EQ ( DURATION ( - 9223372036855 , 224'192'000 ) . to_truncated_microseconds ( ) , ( i64 ) - 0x8000'0000'0000'0000 ) ;
EXPECT_EQ ( DURATION ( - 9223372036855 , 224'192'001 ) . to_truncated_microseconds ( ) , ( i64 ) - 0x7fff'ffff'ffff'ffff ) ;
EXPECT_EQ ( DURATION ( - 9223372036855 , 224'193'000 ) . to_truncated_microseconds ( ) , ( i64 ) - 0x7fff'ffff'ffff'ffff ) ;
EXPECT_EQ ( DURATION ( 9223372036854 , 775'806'000 ) . to_truncated_microseconds ( ) , 0x7fff'ffff'ffff'fffe ) ;
EXPECT_EQ ( DURATION ( 9223372036854 , 775'806'999 ) . to_truncated_microseconds ( ) , 0x7fff'ffff'ffff'fffe ) ;
EXPECT_EQ ( DURATION ( 9223372036854 , 775'807'000 ) . to_truncated_microseconds ( ) , 0x7fff'ffff'ffff'ffff ) ;
EXPECT_EQ ( DURATION ( 9223372036854 , 775'808'000 ) . to_truncated_microseconds ( ) , 0x7fff'ffff'ffff'ffff ) ;
2023-09-03 21:30:36 +03:00
# endif
2021-02-27 23:54:10 +01:00
}
2021-08-14 16:49:53 -07:00
TEST_CASE ( is_negative )
{
2023-03-13 16:30:34 +01:00
auto small = Duration : : from_nanoseconds ( 10 ) ;
auto large = Duration : : from_nanoseconds ( 15 ) ;
2021-08-14 16:49:53 -07:00
auto result = small - large ;
EXPECT_EQ ( result . to_nanoseconds ( ) , - 5 ) ;
EXPECT ( result . is_negative ( ) ) ;
result = large - small ;
EXPECT_EQ ( result . to_nanoseconds ( ) , 5 ) ;
EXPECT ( ! result . is_negative ( ) ) ;
}
2023-01-01 16:55:58 +01:00
struct YearAndDays {
int year ;
2023-01-01 20:07:27 +01:00
i64 days ;
2023-01-01 16:55:58 +01:00
} ;
TEST_CASE ( years_to_days_since_epoch_points )
{
2023-01-01 20:07:27 +01:00
Array < YearAndDays , 24 > test_data = { {
2023-01-01 16:55:58 +01:00
{ 1969 , - 365 } ,
{ 1970 , 0 } ,
{ 1971 , 365 } ,
{ 1900 , - 25567 } ,
{ 2023 , 19358 } ,
{ 1800 , - 62091 } ,
{ 2100 , 47482 } ,
{ 0 , - 719528 } ,
{ - 1 , - 719893 } ,
{ - 2 , - 720258 } ,
{ - 3 , - 720623 } ,
{ - 4 , - 720989 } ,
{ - 5 , - 721354 } ,
{ - 6 , - 721719 } ,
{ 4000 , 741442 } ,
{ - 10000 , - 4371953 } ,
{ 10000 , 2932897 } ,
{ - 1000000 , - 365962028 } ,
{ 1000000 , 364522972 } ,
{ - 5877640 , - 2147483456 } ,
{ 5881474 , 2147444740 } ,
// Very important year: https://github.com/SerenityOS/serenity/pull/16760#issuecomment-1369054745
{ - 999999 , - 365961662 } ,
2023-01-01 20:07:27 +01:00
// The following two values haven't been verified by any other algorithm, but are very close to "year * 365.2425", and prove that there is no UB due to signed overflow:
{ 2147483647 , 784351576412 } ,
{ - 2147483648 , - 784353015833 } ,
2023-01-01 16:55:58 +01:00
} } ;
for ( auto entry : test_data ) {
int year = entry . year ;
2023-01-01 20:07:27 +01:00
i64 expected_days = entry . days ;
i64 actual_days = years_to_days_since_epoch ( year ) ;
2023-01-01 16:55:58 +01:00
EXPECT_EQ ( actual_days , expected_days ) ;
}
}
BENCHMARK_CASE ( years_to_days_since_epoch_benchmark )
{
2023-01-01 17:08:05 +01:00
// This benchmark takes consistently "0ms" on Linux, and "0ms" on Serenity.
2023-01-01 16:55:58 +01:00
for ( size_t i = 0 ; i < 100 ; + + i ) {
2023-01-01 20:07:27 +01:00
i64 actual_days = years_to_days_since_epoch ( - 5877640 ) ;
2023-01-01 16:55:58 +01:00
( void ) actual_days ;
EXPECT_EQ ( actual_days , - 2147483456 ) ;
}
}
2023-05-24 22:05:47 +02:00
TEST_CASE ( days_since_epoch )
{
EXPECT_EQ ( days_since_epoch ( 1970 , 1 , 1 ) , 0 ) ;
EXPECT_EQ ( days_since_epoch ( 1970 , 1 , 2 ) , 1 ) ;
EXPECT_EQ ( days_since_epoch ( 1970 , 2 , 1 ) , 31 ) ;
EXPECT_EQ ( days_since_epoch ( 1970 , 2 , 27 ) , 57 ) ;
EXPECT_EQ ( days_since_epoch ( 1970 , 2 , 28 ) , 58 ) ;
EXPECT_EQ ( days_since_epoch ( 1970 , 2 , 29 ) , 59 ) ; // doesn't really exist
EXPECT_EQ ( days_since_epoch ( 1970 , 3 , 1 ) , 59 ) ;
EXPECT_EQ ( days_since_epoch ( 1971 , 1 , 1 ) , 365 ) ;
EXPECT_EQ ( days_since_epoch ( 1972 , 1 , 1 ) , 730 ) ;
EXPECT_EQ ( days_since_epoch ( 1972 , 2 , 1 ) , 761 ) ;
EXPECT_EQ ( days_since_epoch ( 1972 , 2 , 27 ) , 787 ) ;
EXPECT_EQ ( days_since_epoch ( 1972 , 2 , 28 ) , 788 ) ;
EXPECT_EQ ( days_since_epoch ( 1972 , 2 , 29 ) , 789 ) ;
EXPECT_EQ ( days_since_epoch ( 1972 , 3 , 1 ) , 790 ) ;
// At least shouldn't crash:
EXPECT_EQ ( days_since_epoch ( 1971 , 1 , 0 ) , 364 ) ;
2023-05-24 22:19:17 +02:00
EXPECT_EQ ( days_since_epoch ( 1971 , 0 , 1 ) , 365 ) ;
EXPECT_EQ ( days_since_epoch ( 1971 , 0 , 0 ) , 365 ) ;
EXPECT_EQ ( days_since_epoch ( 1971 , 13 , 3 ) , 365 ) ;
2023-05-24 22:05:47 +02:00
// I can't easily verify that these values are perfectly exact and correct, but they're close enough.
// Also, for these "years" the most important thing is to avoid crashing (i.e. signed overflow UB).
// Observe that these are very close to the naive guess of 365.2425 days per year.
EXPECT_EQ ( days_since_epoch ( 0 , 1 , 1 ) , - 719528 ) ;
EXPECT_EQ ( days_since_epoch ( - 1'000'000 , 1 , 1 ) , - 365962028 ) ;
EXPECT_EQ ( days_since_epoch ( - 2'147'483'648 , 1 , 1 ) , - 784353015833 ) ; // Guess: 784353015832
EXPECT_EQ ( days_since_epoch ( 1'000'000 , 1 , 1 ) , 364522972 ) ;
EXPECT_EQ ( days_since_epoch ( 2'147'483'647 , 1 , 1 ) , 784351576412 ) ; // Guess: 784351576411
EXPECT_EQ ( days_since_epoch ( 2'147'483'647 , 12 , 31 ) , 784351576776 ) ; // Guess: 784351576777
EXPECT_EQ ( days_since_epoch ( 2'147'483'647 , 12 , 255 ) , 784351577000 ) ;
2025-11-13 14:05:19 +01:00
// FIXME: shouldn't crash: EXPECT_EQ(days_since_epoch(2'147'483'647, 255, 255), 784351577000);
2023-05-24 22:05:47 +02:00
// FIXME: Restrict interface to only take sensible types, and ensure callers pass only sensible values for that type.
}
2023-01-01 17:08:05 +01:00
TEST_CASE ( div_floor_by )
{
EXPECT_EQ ( AK : : Detail : : floor_div_by < 4 > ( - 5 ) , - 2 ) ;
EXPECT_EQ ( AK : : Detail : : floor_div_by < 4 > ( - 4 ) , - 1 ) ;
EXPECT_EQ ( AK : : Detail : : floor_div_by < 4 > ( - 3 ) , - 1 ) ;
EXPECT_EQ ( AK : : Detail : : floor_div_by < 4 > ( - 2 ) , - 1 ) ;
EXPECT_EQ ( AK : : Detail : : floor_div_by < 4 > ( - 1 ) , - 1 ) ;
EXPECT_EQ ( AK : : Detail : : floor_div_by < 4 > ( + 0 ) , + 0 ) ;
EXPECT_EQ ( AK : : Detail : : floor_div_by < 4 > ( + 1 ) , + 0 ) ;
EXPECT_EQ ( AK : : Detail : : floor_div_by < 4 > ( + 2 ) , + 0 ) ;
EXPECT_EQ ( AK : : Detail : : floor_div_by < 4 > ( + 3 ) , + 0 ) ;
EXPECT_EQ ( AK : : Detail : : floor_div_by < 4 > ( + 4 ) , + 1 ) ;
EXPECT_EQ ( AK : : Detail : : floor_div_by < 4 > ( + 5 ) , + 1 ) ;
EXPECT_EQ ( AK : : Detail : : floor_div_by < 4 > ( + 6 ) , + 1 ) ;
EXPECT_EQ ( AK : : Detail : : floor_div_by < 4 > ( + 7 ) , + 1 ) ;
EXPECT_EQ ( AK : : Detail : : floor_div_by < 4 > ( + 8 ) , + 2 ) ;
}
TEST_CASE ( mod_zeros_in_range )
{
EXPECT_EQ ( AK : : Detail : : mod_zeros_in_range < 4 > ( 0 , 0 ) , 0 ) ;
EXPECT_EQ ( AK : : Detail : : mod_zeros_in_range < 4 > ( 0 , 1 ) , 1 ) ;
EXPECT_EQ ( AK : : Detail : : mod_zeros_in_range < 4 > ( 0 , 2 ) , 1 ) ;
EXPECT_EQ ( AK : : Detail : : mod_zeros_in_range < 4 > ( 0 , 3 ) , 1 ) ;
EXPECT_EQ ( AK : : Detail : : mod_zeros_in_range < 4 > ( 0 , 4 ) , 1 ) ;
EXPECT_EQ ( AK : : Detail : : mod_zeros_in_range < 4 > ( 0 , 5 ) , 2 ) ;
EXPECT_EQ ( AK : : Detail : : mod_zeros_in_range < 4 > ( 0 , 6 ) , 2 ) ;
EXPECT_EQ ( AK : : Detail : : mod_zeros_in_range < 4 > ( 1 , 1 ) , 0 ) ;
EXPECT_EQ ( AK : : Detail : : mod_zeros_in_range < 4 > ( 1 , 2 ) , 0 ) ;
EXPECT_EQ ( AK : : Detail : : mod_zeros_in_range < 4 > ( 1 , 3 ) , 0 ) ;
EXPECT_EQ ( AK : : Detail : : mod_zeros_in_range < 4 > ( 1 , 4 ) , 0 ) ;
EXPECT_EQ ( AK : : Detail : : mod_zeros_in_range < 4 > ( 1 , 5 ) , 1 ) ;
EXPECT_EQ ( AK : : Detail : : mod_zeros_in_range < 4 > ( 1 , 6 ) , 1 ) ;
EXPECT_EQ ( AK : : Detail : : mod_zeros_in_range < 4 > ( 2 , 2 ) , 0 ) ;
EXPECT_EQ ( AK : : Detail : : mod_zeros_in_range < 4 > ( 2 , 3 ) , 0 ) ;
EXPECT_EQ ( AK : : Detail : : mod_zeros_in_range < 4 > ( 2 , 4 ) , 0 ) ;
EXPECT_EQ ( AK : : Detail : : mod_zeros_in_range < 4 > ( 2 , 5 ) , 1 ) ;
EXPECT_EQ ( AK : : Detail : : mod_zeros_in_range < 4 > ( 2 , 6 ) , 1 ) ;
EXPECT_EQ ( AK : : Detail : : mod_zeros_in_range < 4 > ( 3 , 3 ) , 0 ) ;
EXPECT_EQ ( AK : : Detail : : mod_zeros_in_range < 4 > ( 3 , 4 ) , 0 ) ;
EXPECT_EQ ( AK : : Detail : : mod_zeros_in_range < 4 > ( 3 , 5 ) , 1 ) ;
EXPECT_EQ ( AK : : Detail : : mod_zeros_in_range < 4 > ( 3 , 6 ) , 1 ) ;
EXPECT_EQ ( AK : : Detail : : mod_zeros_in_range < 4 > ( 4 , 4 ) , 0 ) ;
EXPECT_EQ ( AK : : Detail : : mod_zeros_in_range < 4 > ( 4 , 5 ) , 1 ) ;
EXPECT_EQ ( AK : : Detail : : mod_zeros_in_range < 4 > ( 4 , 6 ) , 1 ) ;
EXPECT_EQ ( AK : : Detail : : mod_zeros_in_range < 4 > ( 5 , 5 ) , 0 ) ;
EXPECT_EQ ( AK : : Detail : : mod_zeros_in_range < 4 > ( 5 , 6 ) , 0 ) ;
EXPECT_EQ ( AK : : Detail : : mod_zeros_in_range < 4 > ( 6 , 6 ) , 0 ) ;
EXPECT_EQ ( AK : : Detail : : mod_zeros_in_range < 4 > ( - 5 , 3 ) , 2 ) ;
EXPECT_EQ ( AK : : Detail : : mod_zeros_in_range < 4 > ( - 4 , 3 ) , 2 ) ;
EXPECT_EQ ( AK : : Detail : : mod_zeros_in_range < 4 > ( - 3 , 3 ) , 1 ) ;
EXPECT_EQ ( AK : : Detail : : mod_zeros_in_range < 4 > ( - 2 , 3 ) , 1 ) ;
EXPECT_EQ ( AK : : Detail : : mod_zeros_in_range < 4 > ( - 1 , 3 ) , 1 ) ;
EXPECT_EQ ( AK : : Detail : : mod_zeros_in_range < 4 > ( - 0 , 3 ) , 1 ) ;
EXPECT_EQ ( AK : : Detail : : mod_zeros_in_range < 4 > ( + 1 , 3 ) , 0 ) ;
}
2023-01-01 16:55:58 +01:00
TEST_CASE ( years_to_days_since_epoch_span )
{
auto test_data_start_year = 1900 ;
// Data was pre-computed with a slow, but known-correct implementation.
// clang-format off
auto test_data = Array {
- 25567 , - 25202 , - 24837 , - 24472 , - 24107 , - 23741 , - 23376 , - 23011 ,
- 22646 , - 22280 , - 21915 , - 21550 , - 21185 , - 20819 , - 20454 , - 20089 ,
- 19724 , - 19358 , - 18993 , - 18628 , - 18263 , - 17897 , - 17532 , - 17167 ,
- 16802 , - 16436 , - 16071 , - 15706 , - 15341 , - 14975 , - 14610 , - 14245 ,
- 13880 , - 13514 , - 13149 , - 12784 , - 12419 , - 12053 , - 11688 , - 11323 ,
- 10958 , - 10592 , - 10227 , - 9862 , - 9497 , - 9131 , - 8766 , - 8401 , - 8036 ,
- 7670 , - 7305 , - 6940 , - 6575 , - 6209 , - 5844 , - 5479 , - 5114 , - 4748 , - 4383 ,
- 4018 , - 3653 , - 3287 , - 2922 , - 2557 , - 2192 , - 1826 , - 1461 , - 1096 , - 731 ,
- 365 , 0 , 365 , 730 , 1096 , 1461 , 1826 , 2191 , 2557 , 2922 , 3287 , 3652 ,
4018 , 4383 , 4748 , 5113 , 5479 , 5844 , 6209 , 6574 , 6940 , 7305 , 7670 ,
8035 , 8401 , 8766 , 9131 , 9496 , 9862 , 10227 , 10592 , 10957 , 11323 , 11688 ,
12053 , 12418 , 12784 , 13149 , 13514 , 13879 , 14245 , 14610 , 14975 , 15340 ,
15706 , 16071 , 16436 , 16801 , 17167 , 17532 , 17897 , 18262 , 18628 , 18993 ,
19358 , 19723 , 20089 , 20454 , 20819 , 21184 , 21550 , 21915 , 22280 , 22645 ,
23011 , 23376 , 23741 , 24106 , 24472 , 24837 , 25202 , 25567 , 25933 , 26298 ,
26663 , 27028 , 27394 , 27759 , 28124 , 28489 , 28855 , 29220 , 29585 , 29950 ,
30316 , 30681 , 31046 , 31411 , 31777 , 32142 , 32507 , 32872 , 33238 , 33603 ,
33968 , 34333 , 34699 , 35064 , 35429 , 35794 , 36160 , 36525 , 36890 , 37255 ,
37621 , 37986 , 38351 , 38716 , 39082 , 39447 , 39812 , 40177 , 40543 , 40908 ,
41273 , 41638 , 42004 , 42369 , 42734 , 43099 , 43465 , 43830 , 44195 , 44560 ,
44926 , 45291 , 45656 , 46021 , 46387 , 46752 , 47117 , 47482 , 47847 , 48212 ,
48577 , 48942 , 49308 , 49673 , 50038 , 50403 , 50769 , 51134 , 51499 , 51864 ,
52230 , 52595 , 52960 , 53325 , 53691 , 54056 , 54421 , 54786 , 55152 , 55517 ,
55882 , 56247 , 56613 , 56978 , 57343 , 57708 , 58074 , 58439 , 58804 , 59169 ,
59535 , 59900 , 60265 , 60630 , 60996 , 61361 , 61726 , 62091 , 62457 , 62822 ,
63187 , 63552 , 63918 , 64283 , 64648 , 65013 , 65379 , 65744 , 66109 , 66474 ,
66840 , 67205 , 67570 , 67935 , 68301 , 68666 , 69031 , 69396 , 69762 , 70127 ,
70492 , 70857 , 71223 , 71588 , 71953 , 72318 , 72684 , 73049 , 73414 , 73779 ,
74145 , 74510 , 74875 , 75240 , 75606 , 75971 , 76336 , 76701 , 77067 , 77432 ,
77797 , 78162 , 78528 , 78893 , 79258 , 79623 , 79989 , 80354 , 80719 , 81084 ,
81450 , 81815 , 82180 , 82545 , 82911 , 83276 , 83641 , 84006 , 84371 , 84736 ,
85101 , 85466 , 85832 , 86197 , 86562 , 86927 , 87293 , 87658 , 88023 , 88388 ,
88754 , 89119 , 89484 , 89849 , 90215 , 90580 , 90945 , 91310 , 91676 , 92041 ,
92406 , 92771 , 93137 , 93502 , 93867 , 94232 , 94598 , 94963 , 95328 , 95693 ,
96059 , 96424 , 96789 , 97154 , 97520 , 97885 , 98250 , 98615 , 98981 , 99346 ,
99711 , 100076 , 100442 , 100807 , 101172 , 101537 , 101903 , 102268 , 102633 ,
102998 , 103364 , 103729 , 104094 , 104459 , 104825 , 105190 , 105555 ,
105920 , 106286 , 106651 , 107016 , 107381 , 107747 , 108112 , 108477 ,
108842 , 109208 , 109573 , 109938 , 110303 , 110669 , 111034 , 111399 ,
111764 , 112130 , 112495 , 112860 , 113225 , 113591 , 113956 , 114321 ,
114686 , 115052 , 115417 , 115782 , 116147 , 116513 , 116878 , 117243 ,
117608 , 117974 , 118339 , 118704 , 119069 , 119435 , 119800 , 120165 ,
120530 , 120895 , 121260 , 121625 , 121990 , 122356 , 122721 , 123086 ,
123451 , 123817 , 124182 , 124547 , 124912 , 125278 , 125643 , 126008 ,
126373 , 126739 , 127104 , 127469 , 127834 , 128200 , 128565 , 128930 ,
129295 , 129661 , 130026 , 130391 , 130756 , 131122 , 131487 , 131852 ,
132217 , 132583 , 132948 , 133313 , 133678 , 134044 , 134409 , 134774 ,
135139 , 135505 , 135870 , 136235 , 136600 , 136966 , 137331 , 137696 ,
138061 , 138427 , 138792 , 139157 , 139522 , 139888 , 140253 , 140618 ,
140983 , 141349 , 141714 , 142079 , 142444 , 142810 , 143175 , 143540 ,
143905 , 144271 , 144636 , 145001 , 145366 , 145732 , 146097 , 146462 ,
146827 , 147193 , 147558 , 147923 , 148288 , 148654 , 149019 , 149384 ,
149749 , 150115 , 150480 , 150845 , 151210 , 151576 , 151941 , 152306 ,
152671 , 153037 , 153402 , 153767 , 154132 , 154498 , 154863 , 155228 ,
155593 , 155959 , 156324 , 156689 , 157054 , 157420 , 157785 , 158150 ,
158515 , 158881 , 159246 , 159611 , 159976 , 160342 , 160707 , 161072 ,
161437 , 161803 , 162168 , 162533 , 162898 , 163264 , 163629 , 163994 ,
164359 , 164725 , 165090 , 165455 , 165820 , 166186 , 166551 , 166916 ,
167281 , 167647 , 168012 , 168377 , 168742 , 169108 , 169473 , 169838 ,
170203 , 170569 , 170934 , 171299 , 171664 , 172030 , 172395 , 172760 ,
173125 , 173491 , 173856 , 174221 , 174586 , 174952 , 175317 , 175682 ,
176047 , 176413 , 176778 , 177143 , 177508 , 177874 , 178239 , 178604 ,
178969 , 179335 , 179700 , 180065 , 180430 , 180796 , 181161 , 181526 ,
181891 , 182257 , 182622 , 182987 , 183352 , 183718 , 184083 , 184448 ,
184813 , 185179 , 185544 , 185909 , 186274 , 186640 , 187005 , 187370 ,
187735 , 188101 , 188466 , 188831 , 189196 , 189562 , 189927 , 190292 ,
190657 , 191023 , 191388 , 191753 , 192118 , 192484 , 192849 , 193214 ,
193579 , 193944 , 194309 , 194674 , 195039 , 195405 ,
} ;
// clang-format on
for ( size_t offset = 0 ; offset < test_data . size ( ) ; + + offset ) {
int year = offset + test_data_start_year ;
2023-01-01 20:07:27 +01:00
i64 expected_days = test_data [ offset ] ;
i64 actual_days = years_to_days_since_epoch ( year ) ;
2023-01-01 16:55:58 +01:00
EXPECT_EQ ( actual_days , expected_days ) ;
}
}
2023-01-02 00:27:05 -07:00
TEST_CASE ( user_defined_literals )
{
using namespace AK : : TimeLiterals ;
2023-03-13 16:30:34 +01:00
static_assert ( Duration : : from_nanoseconds ( 123 ) = = 123 _ns , " Factory is same as UDL " ) ;
2023-01-02 00:27:05 -07:00
static_assert ( 100 _ms > 10 _ms , " LT UDL " ) ;
static_assert ( 1000 _ns = = 1 _us , " EQ UDL " ) ;
static_assert ( 1 _sec > 1 _ms , " GT UDL " ) ;
static_assert ( 100 _ms > = 100'000 _us , " GE UDL (eq) " ) ;
static_assert ( 100 _ms > = 99'999 _us , " GE UDL (gt) " ) ;
static_assert ( 100 _ms < = 100'000 _us , " LE UDL (eq) " ) ;
static_assert ( 100 _ms < = 100'001 _us , " LE UDL (lt) " ) ;
static_assert ( 1 _sec ! = 2 _sec , " NE UDL " ) ;
}
2023-05-24 22:05:47 +02:00
2025-08-11 09:07:27 +02:00
TEST_CASE ( from_iso8601_week )
{
// 1970-W01
EXPECT_DURATION ( UnixDateTime : : from_iso8601_week ( 1970 , 1 ) . offset_to_epoch ( ) , - 259'200 , 0 ) ;
// First and last weeks of yearEXPECT_DURATION(UnixDateTime::from_iso8601_week(2000, 1).offset_to_epoch(), 946857600, 0);
EXPECT_DURATION ( UnixDateTime : : from_iso8601_week ( 2000 , 2 ) . offset_to_epoch ( ) , 947462400 , 0 ) ;
EXPECT_DURATION ( UnixDateTime : : from_iso8601_week ( 2000 , 51 ) . offset_to_epoch ( ) , 977097600 , 0 ) ;
EXPECT_DURATION ( UnixDateTime : : from_iso8601_week ( 2000 , 52 ) . offset_to_epoch ( ) , 977702400 , 0 ) ;
EXPECT_DURATION ( UnixDateTime : : from_iso8601_week ( 2001 , 1 ) . offset_to_epoch ( ) , 978307200 , 0 ) ;
EXPECT_DURATION ( UnixDateTime : : from_iso8601_week ( 2001 , 2 ) . offset_to_epoch ( ) , 978912000 , 0 ) ;
EXPECT_DURATION ( UnixDateTime : : from_iso8601_week ( 2001 , 51 ) . offset_to_epoch ( ) , 1008547200 , 0 ) ;
EXPECT_DURATION ( UnixDateTime : : from_iso8601_week ( 2001 , 52 ) . offset_to_epoch ( ) , 1009152000 , 0 ) ;
EXPECT_DURATION ( UnixDateTime : : from_iso8601_week ( 2002 , 1 ) . offset_to_epoch ( ) , 1009756800 , 0 ) ;
EXPECT_DURATION ( UnixDateTime : : from_iso8601_week ( 2002 , 2 ) . offset_to_epoch ( ) , 1010361600 , 0 ) ;
EXPECT_DURATION ( UnixDateTime : : from_iso8601_week ( 2002 , 51 ) . offset_to_epoch ( ) , 1039996800 , 0 ) ;
EXPECT_DURATION ( UnixDateTime : : from_iso8601_week ( 2002 , 52 ) . offset_to_epoch ( ) , 1040601600 , 0 ) ;
EXPECT_DURATION ( UnixDateTime : : from_iso8601_week ( 2003 , 1 ) . offset_to_epoch ( ) , 1041206400 , 0 ) ;
EXPECT_DURATION ( UnixDateTime : : from_iso8601_week ( 2003 , 2 ) . offset_to_epoch ( ) , 1041811200 , 0 ) ;
EXPECT_DURATION ( UnixDateTime : : from_iso8601_week ( 2003 , 51 ) . offset_to_epoch ( ) , 1071446400 , 0 ) ;
EXPECT_DURATION ( UnixDateTime : : from_iso8601_week ( 2003 , 52 ) . offset_to_epoch ( ) , 1072051200 , 0 ) ;
EXPECT_DURATION ( UnixDateTime : : from_iso8601_week ( 2004 , 1 ) . offset_to_epoch ( ) , 1072656000 , 0 ) ;
EXPECT_DURATION ( UnixDateTime : : from_iso8601_week ( 2004 , 2 ) . offset_to_epoch ( ) , 1073260800 , 0 ) ;
EXPECT_DURATION ( UnixDateTime : : from_iso8601_week ( 2004 , 51 ) . offset_to_epoch ( ) , 1102896000 , 0 ) ;
EXPECT_DURATION ( UnixDateTime : : from_iso8601_week ( 2004 , 52 ) . offset_to_epoch ( ) , 1103500800 , 0 ) ;
EXPECT_DURATION ( UnixDateTime : : from_iso8601_week ( 2004 , 53 ) . offset_to_epoch ( ) , 1104105600 , 0 ) ;
EXPECT_DURATION ( UnixDateTime : : from_iso8601_week ( 2005 , 1 ) . offset_to_epoch ( ) , 1104710400 , 0 ) ;
EXPECT_DURATION ( UnixDateTime : : from_iso8601_week ( 2005 , 2 ) . offset_to_epoch ( ) , 1105315200 , 0 ) ;
EXPECT_DURATION ( UnixDateTime : : from_iso8601_week ( 2005 , 51 ) . offset_to_epoch ( ) , 1134950400 , 0 ) ;
EXPECT_DURATION ( UnixDateTime : : from_iso8601_week ( 2005 , 52 ) . offset_to_epoch ( ) , 1135555200 , 0 ) ;
EXPECT_DURATION ( UnixDateTime : : from_iso8601_week ( 2006 , 1 ) . offset_to_epoch ( ) , 1136160000 , 0 ) ;
EXPECT_DURATION ( UnixDateTime : : from_iso8601_week ( 2006 , 2 ) . offset_to_epoch ( ) , 1136764800 , 0 ) ;
EXPECT_DURATION ( UnixDateTime : : from_iso8601_week ( 2006 , 51 ) . offset_to_epoch ( ) , 1166400000 , 0 ) ;
EXPECT_DURATION ( UnixDateTime : : from_iso8601_week ( 2006 , 52 ) . offset_to_epoch ( ) , 1167004800 , 0 ) ;
EXPECT_DURATION ( UnixDateTime : : from_iso8601_week ( 2007 , 1 ) . offset_to_epoch ( ) , 1167609600 , 0 ) ;
EXPECT_DURATION ( UnixDateTime : : from_iso8601_week ( 2007 , 2 ) . offset_to_epoch ( ) , 1168214400 , 0 ) ;
EXPECT_DURATION ( UnixDateTime : : from_iso8601_week ( 2007 , 51 ) . offset_to_epoch ( ) , 1197849600 , 0 ) ;
EXPECT_DURATION ( UnixDateTime : : from_iso8601_week ( 2007 , 52 ) . offset_to_epoch ( ) , 1198454400 , 0 ) ;
EXPECT_DURATION ( UnixDateTime : : from_iso8601_week ( 2008 , 1 ) . offset_to_epoch ( ) , 1199059200 , 0 ) ;
EXPECT_DURATION ( UnixDateTime : : from_iso8601_week ( 2008 , 2 ) . offset_to_epoch ( ) , 1199664000 , 0 ) ;
EXPECT_DURATION ( UnixDateTime : : from_iso8601_week ( 2008 , 51 ) . offset_to_epoch ( ) , 1229299200 , 0 ) ;
EXPECT_DURATION ( UnixDateTime : : from_iso8601_week ( 2008 , 52 ) . offset_to_epoch ( ) , 1229904000 , 0 ) ;
EXPECT_DURATION ( UnixDateTime : : from_iso8601_week ( 2009 , 1 ) . offset_to_epoch ( ) , 1230508800 , 0 ) ;
EXPECT_DURATION ( UnixDateTime : : from_iso8601_week ( 2009 , 2 ) . offset_to_epoch ( ) , 1231113600 , 0 ) ;
EXPECT_DURATION ( UnixDateTime : : from_iso8601_week ( 2009 , 51 ) . offset_to_epoch ( ) , 1260748800 , 0 ) ;
EXPECT_DURATION ( UnixDateTime : : from_iso8601_week ( 2009 , 52 ) . offset_to_epoch ( ) , 1261353600 , 0 ) ;
EXPECT_DURATION ( UnixDateTime : : from_iso8601_week ( 2009 , 53 ) . offset_to_epoch ( ) , 1261958400 , 0 ) ;
// Some random weeks
EXPECT_DURATION ( UnixDateTime : : from_iso8601_week ( 2064 , 25 ) . offset_to_epoch ( ) , 2980800000 , 0 ) ;
EXPECT_DURATION ( UnixDateTime : : from_iso8601_week ( 1976 , 20 ) . offset_to_epoch ( ) , 200534400 , 0 ) ;
EXPECT_DURATION ( UnixDateTime : : from_iso8601_week ( 2036 , 6 ) . offset_to_epoch ( ) , 2085696000 , 0 ) ;
EXPECT_DURATION ( UnixDateTime : : from_iso8601_week ( 2022 , 9 ) . offset_to_epoch ( ) , 1646006400 , 0 ) ;
EXPECT_DURATION ( UnixDateTime : : from_iso8601_week ( 2049 , 19 ) . offset_to_epoch ( ) , 2504217600 , 0 ) ;
EXPECT_DURATION ( UnixDateTime : : from_iso8601_week ( 2069 , 9 ) . offset_to_epoch ( ) , 3128976000 , 0 ) ;
EXPECT_DURATION ( UnixDateTime : : from_iso8601_week ( 2015 , 46 ) . offset_to_epoch ( ) , 1447027200 , 0 ) ;
EXPECT_DURATION ( UnixDateTime : : from_iso8601_week ( 2056 , 42 ) . offset_to_epoch ( ) , 2738880000 , 0 ) ;
EXPECT_DURATION ( UnixDateTime : : from_iso8601_week ( 2018 , 23 ) . offset_to_epoch ( ) , 1528070400 , 0 ) ;
EXPECT_DURATION ( UnixDateTime : : from_iso8601_week ( 2047 , 2 ) . offset_to_epoch ( ) , 2430432000 , 0 ) ;
EXPECT_DURATION ( UnixDateTime : : from_iso8601_week ( 2033 , 41 ) . offset_to_epoch ( ) , 2012515200 , 0 ) ;
EXPECT_DURATION ( UnixDateTime : : from_iso8601_week ( 2021 , 52 ) . offset_to_epoch ( ) , 1640563200 , 0 ) ;
EXPECT_DURATION ( UnixDateTime : : from_iso8601_week ( 1987 , 8 ) . offset_to_epoch ( ) , 540432000 , 0 ) ;
EXPECT_DURATION ( UnixDateTime : : from_iso8601_week ( 1982 , 13 ) . offset_to_epoch ( ) , 386208000 , 0 ) ;
EXPECT_DURATION ( UnixDateTime : : from_iso8601_week ( 1979 , 36 ) . offset_to_epoch ( ) , 305164800 , 0 ) ;
EXPECT_DURATION ( UnixDateTime : : from_iso8601_week ( 2057 , 43 ) . offset_to_epoch ( ) , 2770934400 , 0 ) ;
EXPECT_DURATION ( UnixDateTime : : from_iso8601_week ( 1988 , 35 ) . offset_to_epoch ( ) , 588816000 , 0 ) ;
EXPECT_DURATION ( UnixDateTime : : from_iso8601_week ( 2060 , 50 ) . offset_to_epoch ( ) , 2869516800 , 0 ) ;
EXPECT_DURATION ( UnixDateTime : : from_iso8601_week ( 2013 , 14 ) . offset_to_epoch ( ) , 1364774400 , 0 ) ;
EXPECT_DURATION ( UnixDateTime : : from_iso8601_week ( 2005 , 52 ) . offset_to_epoch ( ) , 1135555200 , 0 ) ;
}
2023-05-24 22:05:47 +02:00
TEST_CASE ( from_unix_time_parts_common_values )
{
// Non-negative "common" values.
EXPECT_DURATION ( UnixDateTime : : from_unix_time_parts ( 1970 , 1 , 1 , 0 , 0 , 0 , 0 ) . offset_to_epoch ( ) , 0 , 0 ) ;
EXPECT_DURATION ( UnixDateTime : : from_unix_time_parts ( 1970 , 1 , 1 , 0 , 0 , 0 , 1 ) . offset_to_epoch ( ) , 0 , 1'000'000 ) ;
EXPECT_DURATION ( UnixDateTime : : from_unix_time_parts ( 1970 , 1 , 1 , 0 , 0 , 0 , 999 ) . offset_to_epoch ( ) , 0 , 999'000'000 ) ;
EXPECT_DURATION ( UnixDateTime : : from_unix_time_parts ( 1970 , 1 , 1 , 0 , 0 , 1 , 2 ) . offset_to_epoch ( ) , 1 , 2'000'000 ) ;
EXPECT_DURATION ( UnixDateTime : : from_unix_time_parts ( 1970 , 1 , 1 , 0 , 0 , 59 , 0 ) . offset_to_epoch ( ) , 59 , 0 ) ;
EXPECT_DURATION ( UnixDateTime : : from_unix_time_parts ( 1970 , 1 , 1 , 0 , 1 , 0 , 0 ) . offset_to_epoch ( ) , 60 , 0 ) ;
EXPECT_DURATION ( UnixDateTime : : from_unix_time_parts ( 1970 , 1 , 1 , 0 , 59 , 0 , 0 ) . offset_to_epoch ( ) , 3540 , 0 ) ;
EXPECT_DURATION ( UnixDateTime : : from_unix_time_parts ( 1970 , 1 , 1 , 1 , 0 , 0 , 0 ) . offset_to_epoch ( ) , 3600 , 0 ) ;
EXPECT_DURATION ( UnixDateTime : : from_unix_time_parts ( 1970 , 1 , 1 , 23 , 0 , 0 , 0 ) . offset_to_epoch ( ) , 82800 , 0 ) ;
EXPECT_DURATION ( UnixDateTime : : from_unix_time_parts ( 1970 , 1 , 2 , 0 , 0 , 0 , 0 ) . offset_to_epoch ( ) , 86400 , 0 ) ;
EXPECT_DURATION ( UnixDateTime : : from_unix_time_parts ( 1970 , 2 , 1 , 0 , 0 , 0 , 0 ) . offset_to_epoch ( ) , 2678400 , 0 ) ;
EXPECT_DURATION ( UnixDateTime : : from_unix_time_parts ( 1970 , 2 , 27 , 0 , 0 , 0 , 0 ) . offset_to_epoch ( ) , 4924800 , 0 ) ;
EXPECT_DURATION ( UnixDateTime : : from_unix_time_parts ( 1970 , 2 , 28 , 0 , 0 , 0 , 0 ) . offset_to_epoch ( ) , 5011200 , 0 ) ;
// Note that this day does *not* exist:
EXPECT_DURATION ( UnixDateTime : : from_unix_time_parts ( 1970 , 2 , 29 , 0 , 0 , 0 , 0 ) . offset_to_epoch ( ) , 5097600 , 0 ) ;
EXPECT_DURATION ( UnixDateTime : : from_unix_time_parts ( 1970 , 3 , 0 , 0 , 0 , 0 , 0 ) . offset_to_epoch ( ) , 5011200 , 0 ) ;
EXPECT_DURATION ( UnixDateTime : : from_unix_time_parts ( 1970 , 3 , 1 , 0 , 0 , 0 , 0 ) . offset_to_epoch ( ) , 5097600 , 0 ) ;
EXPECT_DURATION ( UnixDateTime : : from_unix_time_parts ( 1970 , 3 , 2 , 0 , 0 , 0 , 0 ) . offset_to_epoch ( ) , 5184000 , 0 ) ;
EXPECT_DURATION ( UnixDateTime : : from_unix_time_parts ( 1971 , 1 , 1 , 0 , 0 , 0 , 0 ) . offset_to_epoch ( ) , 31536000 , 0 ) ;
EXPECT_DURATION ( UnixDateTime : : from_unix_time_parts ( 1972 , 1 , 1 , 0 , 0 , 0 , 0 ) . offset_to_epoch ( ) , 63072000 , 0 ) ;
EXPECT_DURATION ( UnixDateTime : : from_unix_time_parts ( 1972 , 2 , 1 , 0 , 0 , 0 , 0 ) . offset_to_epoch ( ) , 65750400 , 0 ) ;
EXPECT_DURATION ( UnixDateTime : : from_unix_time_parts ( 1972 , 2 , 27 , 0 , 0 , 0 , 0 ) . offset_to_epoch ( ) , 67996800 , 0 ) ;
EXPECT_DURATION ( UnixDateTime : : from_unix_time_parts ( 1972 , 2 , 28 , 0 , 0 , 0 , 0 ) . offset_to_epoch ( ) , 68083200 , 0 ) ;
EXPECT_DURATION ( UnixDateTime : : from_unix_time_parts ( 1972 , 2 , 29 , 0 , 0 , 0 , 0 ) . offset_to_epoch ( ) , 68169600 , 0 ) ;
EXPECT_DURATION ( UnixDateTime : : from_unix_time_parts ( 1972 , 3 , 1 , 0 , 0 , 0 , 0 ) . offset_to_epoch ( ) , 68256000 , 0 ) ;
EXPECT_DURATION ( UnixDateTime : : from_unix_time_parts ( 2023 , 5 , 24 , 18 , 44 , 40 , 0 ) . offset_to_epoch ( ) , 1684953880 , 0 ) ;
}
TEST_CASE ( from_unix_time_parts_negative )
{
// Negative "common" values. These aren't really that well-defined, but we must make sure we don't crash.
EXPECT_DURATION ( UnixDateTime : : from_unix_time_parts ( 1970 , 1 , 0 , 23 , 0 , 0 , 0 ) . offset_to_epoch ( ) , - 3600 , 0 ) ;
EXPECT_DURATION ( UnixDateTime : : from_unix_time_parts ( 1970 , 1 , 0 , 24 , 0 , 0 , 0 ) . offset_to_epoch ( ) , 0 , 0 ) ;
2023-05-24 22:19:17 +02:00
EXPECT_DURATION ( UnixDateTime : : from_unix_time_parts ( 1970 , 0 , 31 , 0 , 0 , 0 , 0 ) . offset_to_epoch ( ) , 0 , 0 ) ;
2023-05-24 22:05:47 +02:00
EXPECT_DURATION ( UnixDateTime : : from_unix_time_parts ( 1970 , 11 , 30 , 0 , 0 , 0 , 0 ) . offset_to_epoch ( ) , 28771200 , 0 ) ;
EXPECT_DURATION ( UnixDateTime : : from_unix_time_parts ( 1970 , 12 , 1 , 0 , 0 , 0 , 0 ) . offset_to_epoch ( ) , 28857600 , 0 ) ;
EXPECT_DURATION ( UnixDateTime : : from_unix_time_parts ( 1970 , 12 , 31 , 0 , 0 , 0 , 0 ) . offset_to_epoch ( ) , 31449600 , 0 ) ;
2023-05-24 22:19:17 +02:00
EXPECT_DURATION ( UnixDateTime : : from_unix_time_parts ( 1971 , 0 , 0 , 0 , 0 , 0 , 0 ) . offset_to_epoch ( ) , 31536000 , 0 ) ;
EXPECT_DURATION ( UnixDateTime : : from_unix_time_parts ( 1971 , 0 , 1 , 0 , 0 , 0 , 0 ) . offset_to_epoch ( ) , 31536000 , 0 ) ;
2023-05-24 22:05:47 +02:00
EXPECT_DURATION ( UnixDateTime : : from_unix_time_parts ( 1971 , 1 , 0 , 0 , 0 , 0 , 0 ) . offset_to_epoch ( ) , 31449600 , 0 ) ;
EXPECT_DURATION ( UnixDateTime : : from_unix_time_parts ( 1971 , 1 , 1 , 0 , 0 , 0 , 0 ) . offset_to_epoch ( ) , 31536000 , 0 ) ;
EXPECT_DURATION ( UnixDateTime : : from_unix_time_parts ( 1969 , 1 , 1 , 0 , 0 , 0 , 0 ) . offset_to_epoch ( ) , - 31536000 , 0 ) ;
EXPECT_DURATION ( UnixDateTime : : from_unix_time_parts ( 1968 , 3 , 1 , 0 , 0 , 0 , 0 ) . offset_to_epoch ( ) , - 57974400 , 0 ) ;
// Leap day!
EXPECT_DURATION ( UnixDateTime : : from_unix_time_parts ( 1968 , 2 , 29 , 0 , 0 , 0 , 0 ) . offset_to_epoch ( ) , - 58060800 , 0 ) ;
EXPECT_DURATION ( UnixDateTime : : from_unix_time_parts ( 1968 , 2 , 28 , 0 , 0 , 0 , 0 ) . offset_to_epoch ( ) , - 58147200 , 0 ) ;
EXPECT_DURATION ( UnixDateTime : : from_unix_time_parts ( 1968 , 2 , 27 , 0 , 0 , 0 , 0 ) . offset_to_epoch ( ) , - 58233600 , 0 ) ;
EXPECT_DURATION ( UnixDateTime : : from_unix_time_parts ( 1968 , 2 , 1 , 0 , 0 , 0 , 0 ) . offset_to_epoch ( ) , - 60480000 , 0 ) ;
EXPECT_DURATION ( UnixDateTime : : from_unix_time_parts ( 1968 , 1 , 1 , 0 , 0 , 0 , 0 ) . offset_to_epoch ( ) , - 63158400 , 0 ) ;
EXPECT_DURATION ( UnixDateTime : : from_unix_time_parts ( 1967 , 1 , 1 , 0 , 0 , 0 , 0 ) . offset_to_epoch ( ) , - 94694400 , 0 ) ;
}
TEST_CASE ( from_milliseconds )
{
EXPECT_DURATION ( Duration : : from_milliseconds ( 0 ) , 0 , 0 ) ;
EXPECT_DURATION ( Duration : : from_milliseconds ( 42 ) , 0 , 42'000'000 ) ;
EXPECT_DURATION ( Duration : : from_milliseconds ( - 1 ) , - 1 , 999'000'000 ) ;
EXPECT_DURATION ( Duration : : from_milliseconds ( - 1'000'000'000 ) , - 1'000'000 , 0 ) ;
EXPECT_DURATION ( Duration : : from_milliseconds ( 1'000'000'000 ) , 1'000'000 , 0 ) ;
EXPECT_DURATION ( Duration : : from_milliseconds ( 9223372036854775807 ) , 9223372036854775 , 807'000'000 ) ;
EXPECT_DURATION ( Duration : : from_milliseconds ( ( i64 ) - 0x8000'0000'0000'0000 ) , - 9223372036854776 , 192'000'000 ) ;
}
2023-05-24 22:06:39 +02:00
TEST_CASE ( from_unix_time_parts_overflow )
{
// Negative overflow
// I can't easily verify that these values are perfectly exact and correct, but they're close enough.
// Also, for these "years" the most important thing is to avoid crashing (i.e. signed overflow UB).
EXPECT_DURATION ( UnixDateTime : : from_unix_time_parts ( 0 , 1 , 1 , 0 , 0 , 0 , 0 ) . offset_to_epoch ( ) , - 62167219200 , 0 ) ; // Guess: -62167195440, off by 23760 seconds
EXPECT_DURATION ( UnixDateTime : : from_unix_time_parts ( - 1'000'000 , 1 , 1 , 0 , 0 , 0 , 0 ) . offset_to_epoch ( ) , - 31619119219200 , 0 ) ; // Guess: -31619119195440, off by the same 23760 seconds
EXPECT_DURATION ( UnixDateTime : : from_unix_time_parts ( - 2'147'483'648 , 1 , 1 , 0 , 0 , 0 , 0 ) . offset_to_epoch ( ) , - 67768100567971200 , 0 ) ; // Guess: -67768100567916336, off by 54864 seconds
EXPECT_DURATION ( UnixDateTime : : from_unix_time_parts ( - 2'147'483'648 , 1 , 0 , 0 , 0 , 0 , 0 ) . offset_to_epoch ( ) , - 67768100568057600 , 0 ) ; // Guess: -67768100568002736, off by the same 54864 seconds
2023-05-24 22:19:17 +02:00
EXPECT_DURATION ( UnixDateTime : : from_unix_time_parts ( - 2'147'483'648 , 0 , 0 , 0 , 0 , 0 , 0 ) . offset_to_epoch ( ) , - 67768100567971200 , 0 ) ;
2023-05-24 22:06:39 +02:00
// Positive overflow
EXPECT_DURATION ( UnixDateTime : : from_unix_time_parts ( 1970 , 1 , 1 , 0 , 0 , 0 , 65535 ) . offset_to_epoch ( ) , 65 , 535'000'000 ) ;
EXPECT_DURATION ( UnixDateTime : : from_unix_time_parts ( 1970 , 1 , 1 , 0 , 0 , 255 , 0 ) . offset_to_epoch ( ) , 255 , 0 ) ;
EXPECT_DURATION ( UnixDateTime : : from_unix_time_parts ( 1970 , 1 , 1 , 0 , 255 , 0 , 0 ) . offset_to_epoch ( ) , 15300 , 0 ) ;
EXPECT_DURATION ( UnixDateTime : : from_unix_time_parts ( 1970 , 1 , 1 , 255 , 0 , 0 , 0 ) . offset_to_epoch ( ) , 918000 , 0 ) ;
EXPECT_DURATION ( UnixDateTime : : from_unix_time_parts ( 1970 , 1 , 255 , 0 , 0 , 0 , 0 ) . offset_to_epoch ( ) , 21945600 , 0 ) ;
EXPECT_DURATION ( UnixDateTime : : from_unix_time_parts ( 1970 , 12 , 1 , 0 , 0 , 0 , 0 ) . offset_to_epoch ( ) , 28857600 , 0 ) ;
2023-05-24 22:19:17 +02:00
EXPECT_DURATION ( UnixDateTime : : from_unix_time_parts ( 1970 , 255 , 1 , 0 , 0 , 0 , 0 ) . offset_to_epoch ( ) , 0 , 0 ) ;
2023-05-24 22:06:39 +02:00
EXPECT_DURATION ( UnixDateTime : : from_unix_time_parts ( 1'000'000 , 1 , 1 , 0 , 0 , 0 , 0 ) . offset_to_epoch ( ) , 31494784780800 , 0 ) ;
EXPECT_DURATION ( UnixDateTime : : from_unix_time_parts ( 2'147'483'647 , 1 , 1 , 0 , 0 , 0 , 0 ) . offset_to_epoch ( ) , 67767976201996800 , 0 ) ;
EXPECT_DURATION ( UnixDateTime : : from_unix_time_parts ( 2'147'483'647 , 12 , 255 , 0 , 0 , 0 , 0 ) . offset_to_epoch ( ) , 67767976252800000 , 0 ) ;
EXPECT_DURATION ( UnixDateTime : : from_unix_time_parts ( 2'147'483'647 , 12 , 255 , 255 , 255 , 255 , 65535 ) . offset_to_epoch ( ) , 67767976253733620 , 535'000'000 ) ;
2023-05-24 22:19:17 +02:00
EXPECT_DURATION ( UnixDateTime : : from_unix_time_parts ( 2'147'483'647 , 255 , 255 , 255 , 255 , 255 , 65535 ) . offset_to_epoch ( ) , 67767976202930420 , 535'000'000 ) ;
2023-05-24 22:06:39 +02:00
}
2025-06-19 20:04:44 +02:00
TEST_CASE ( time_to_string )
{
auto test = [ ] ( auto format , auto expected , i32 year , u8 month , u8 day , u8 hour , u8 minute , u8 second ) {
auto result = AK : : UnixDateTime : : from_unix_time_parts ( year , month , day , hour , minute , second , 0 ) . to_string ( format , AK : : UnixDateTime : : LocalTime : : No ) ;
VERIFY ( ! result . is_error ( ) ) ;
EXPECT_EQ ( expected , result . value ( ) ) ;
} ;
test ( " %Y/%m/%d %R " sv , " 2023/01/23 10:50 " sv , 2023 , 1 , 23 , 10 , 50 , 10 ) ;
// two-digit year and century
test ( " %y %C " sv , " 23 20 " sv , 2023 , 1 , 23 , 10 , 50 , 10 ) ;
// zero- and space-padded day, and %D shortcut
test ( " %d %e " sv , " 05 5 " sv , 2023 , 1 , 5 , 0 , 0 , 0 ) ;
test ( " %D " sv , " 01/23/23 " sv , 2023 , 1 , 23 , 0 , 0 , 0 ) ;
// full time and seconds
test ( " %T " sv , " 10:50:10 " sv , 2023 , 1 , 23 , 10 , 50 , 10 ) ;
test ( " %S " sv , " 05 " sv , 2023 , 1 , 1 , 0 , 0 , 5 ) ;
// 12-hour clock with AM/PM
test ( " %H %I %p " sv , " 00 12 AM " sv , 2023 , 1 , 5 , 0 , 0 , 0 ) ;
test ( " %H %I %p " sv , " 15 03 PM " sv , 2023 , 1 , 5 , 15 , 0 , 0 ) ;
// short/long weekday and month names
test ( " %a %A " sv , " Mon Monday " sv , 2023 , 1 , 23 , 0 , 0 , 0 ) ;
test ( " %b %B " sv , " Jan January " sv , 2023 , 1 , 5 , 0 , 0 , 0 ) ;
// numeric weekday and day‐ of‐ year
test ( " %w %j " sv , " 1 023 " sv , 2023 , 1 , 23 , 0 , 0 , 0 ) ;
// newline, tab and literal '%'
test ( " %n " sv , " \n " sv , 2023 , 1 , 1 , 0 , 0 , 0 ) ;
test ( " %t " sv , " \t " sv , 2023 , 1 , 1 , 0 , 0 , 0 ) ;
test ( " %% " sv , " % " sv , 2023 , 1 , 1 , 0 , 0 , 0 ) ;
}
2025-06-21 17:18:45 +02:00
TEST_CASE ( parse_time )
{
auto test = [ ] ( auto format , auto time , int year , int month , int day , int hour , int minute , int second = 0 ) {
auto result = AK : : UnixDateTime : : parse ( format , time ) ;
VERIFY ( result . has_value ( ) ) ;
auto result_time = result . value ( ) . to_timespec ( ) ;
struct tm tm ;
# ifdef AK_OS_WINDOWS
VERIFY ( gmtime_r ( & result_time . tv_sec , & tm ) = = 0 ) ;
# else
VERIFY ( gmtime_r ( & result_time . tv_sec , & tm ) ! = nullptr ) ;
# endif
EXPECT_EQ ( year , tm . tm_year + 1900 ) ;
EXPECT_EQ ( month , tm . tm_mon + 1 ) ;
EXPECT_EQ ( day , tm . tm_mday ) ;
EXPECT_EQ ( hour , tm . tm_hour ) ;
EXPECT_EQ ( minute , tm . tm_min ) ;
EXPECT_EQ ( second , tm . tm_sec ) ;
} ;
test ( " %d-%m-%Y %H:%M " sv , " 05-01-2023 00:00 " sv , 2023 , 1 , 5 , 0 , 0 ) ;
test ( " %d-%m-%Y %H:%M GMT " sv , " 05-01-2023 00:00 GMT " sv , 2023 , 1 , 5 , 0 , 0 ) ;
test ( " %Y/%m/%d %R " sv , " 2023/01/23 10:50 " sv , 2023 , 1 , 23 , 10 , 50 ) ;
test ( " %Y-%m-%d %H:%M " sv , " 1999-12-31 23:59 " sv , 1999 , 12 , 31 , 23 , 59 ) ;
test ( " %Y/%m/%d %R " sv , " 1970/01/01 00:00 " sv , 1970 , 1 , 1 , 0 , 0 ) ;
test ( " %Y/%m/%d %R " sv , " 2000/02/29 12:34 " sv , 2000 , 2 , 29 , 12 , 34 ) ; // Leap year
// %T: full time with seconds
test ( " %Y-%m-%d %T " sv , " 2023-01-23 10:50:15 " sv , 2023 , 1 , 23 , 10 , 50 , 15 ) ;
// %S: seconds
test ( " %Y-%m-%d %H:%M:%S " sv , " 2023-01-23 10:50:42 " sv , 2023 , 1 , 23 , 10 , 50 , 42 ) ;
// %I: 12-hour clock, %p: AM/PM
test ( " %Y-%m-%d %I:%M %p " sv , " 2023-01-23 03:21 PM " sv , 2023 , 1 , 23 , 15 , 21 , 0 ) ;
test ( " %Y-%m-%d %I:%M %p " sv , " 2023-01-23 12:01 AM " sv , 2023 , 1 , 23 , 0 , 1 , 0 ) ;
// %D: shortcut for %m/%d/%y
test ( " %D %H:%M:%S " sv , " 01/23/23 10:50:59 " sv , 2023 , 1 , 23 , 10 , 50 , 59 ) ;
// %y: two-digit year, %C: century
test ( " %y %C %m %d %H:%M:%S " sv , " 23 20 01 23 10:50:11 " sv , 2023 , 1 , 23 , 10 , 50 , 11 ) ;
// %a/%A: short/long weekday name (parsing ignores names, but test for correct date)
test ( " %Y-%m-%d %a " sv , " 2023-01-23 Mon " sv , 2023 , 1 , 23 , 0 , 0 , 0 ) ;
test ( " %Y-%m-%d %A " sv , " 2023-01-23 Monday " sv , 2023 , 1 , 23 , 0 , 0 , 0 ) ;
// %b/%B: short/long month name (parsing ignores names, but test for correct date)
test ( " %d %b %Y " sv , " 05 Jan 2023 " sv , 2023 , 1 , 5 , 0 , 0 , 0 ) ;
test ( " %d %B %Y " sv , " 05 January 2023 " sv , 2023 , 1 , 5 , 0 , 0 , 0 ) ;
// %j: day of year
test ( " %Y %j %H:%M:%S " sv , " 2023 023 10:50:12 " sv , 2023 , 1 , 23 , 10 , 50 , 12 ) ;
// %w: weekday number (0=Sunday)
test ( " %Y-%m-%d %w %H:%M:%S " sv , " 2023-01-23 1 10:50:13 " sv , 2023 , 1 , 23 , 10 , 50 , 13 ) ;
// %n: newline, %t: tab, %%: literal %
test ( " %Y-%m-%d%n%H:%M:%S " sv , " 2023-01-23 \n 10:50:14 " sv , 2023 , 1 , 23 , 10 , 50 , 14 ) ;
test ( " %Y-%m-%d%t%H:%M:%S " sv , " 2023-01-23 \t 10:50:15 " sv , 2023 , 1 , 23 , 10 , 50 , 15 ) ;
test ( " %Y-%m-%d %% %H:%M:%S " sv , " 2023-01-23 % 10:50:16 " sv , 2023 , 1 , 23 , 10 , 50 , 16 ) ;
}
TEST_CASE ( parse_wildcard_characters )
{
EXPECT ( ! AK : : UnixDateTime : : parse ( " %+ " sv , " " sv ) . has_value ( ) ) ;
EXPECT ( ! AK : : UnixDateTime : : parse ( " foo%+ " sv , " foo " sv ) . has_value ( ) ) ;
EXPECT ( ! AK : : UnixDateTime : : parse ( " [%*] " sv , " [foo " sv ) . has_value ( ) ) ;
EXPECT ( ! AK : : UnixDateTime : : parse ( " [%*] " sv , " foo] " sv ) . has_value ( ) ) ;
EXPECT ( ! AK : : UnixDateTime : : parse ( " %+%b " sv , " fooJan " sv ) . has_value ( ) ) ;
auto test = [ ] ( auto format , auto time , int year , int month , int day ) {
auto result = AK : : UnixDateTime : : parse ( format , time ) ;
VERIFY ( result . has_value ( ) ) ;
auto result_time = result . value ( ) . to_timespec ( ) ;
struct tm tm ;
# ifdef AK_OS_WINDOWS
VERIFY ( gmtime_r ( & result_time . tv_sec , & tm ) = = 0 ) ;
# else
VERIFY ( gmtime_r ( & result_time . tv_sec , & tm ) ! = nullptr ) ;
# endif
EXPECT_EQ ( year , tm . tm_year + 1900 ) ;
EXPECT_EQ ( month , tm . tm_mon + 1 ) ;
EXPECT_EQ ( day , tm . tm_mday ) ;
} ;
test ( " %Y %+ %m %d " sv , " 2023 whf 01 23 " sv , 2023 , 01 , 23 ) ;
test ( " %Y %m %d %+ " sv , " 2023 01 23 whf " sv , 2023 , 01 , 23 ) ;
test ( " %Y [%+] %m %d " sv , " 2023 [well hello friends!] 01 23 " sv , 2023 , 01 , 23 ) ;
test ( " %Y %m %d [%+] " sv , " 2023 01 23 [well hello friends!] " sv , 2023 , 01 , 23 ) ;
}
TEST_CASE ( parse_time_from_gmt )
{
// Test parsing with from_gmt = true (GMT time)
auto gmt_result = AK : : UnixDateTime : : parse ( " %Y-%m-%d %H:%M:%S " sv ,
" 2023-01-15 12:00:00 " sv , true ) ;
VERIFY ( gmt_result . has_value ( ) ) ;
// Parse a known GMT time and verify the timestamp
auto test_gmt = AK : : UnixDateTime : : parse ( " %Y-%m-%d %H:%M:%S " sv ,
" 1970-01-01 00:00:00 " sv , true ) ;
VERIFY ( test_gmt . has_value ( ) ) ;
EXPECT_EQ ( test_gmt . value ( ) . seconds_since_epoch ( ) , 0 ) ;
// Test another GMT time
auto test_gmt2 = AK : : UnixDateTime : : parse ( " %Y-%m-%d %H:%M:%S " sv ,
" 1970-01-01 01:00:00 " sv , true ) ;
VERIFY ( test_gmt2 . has_value ( ) ) ;
EXPECT_EQ ( test_gmt2 . value ( ) . seconds_since_epoch ( ) , 3600 ) ;
// Test with date components
auto test_gmt3 = AK : : UnixDateTime : : parse ( " %Y-%m-%d %H:%M:%S " sv ,
" 2023-06-15 18:30:45 " sv , true ) ;
VERIFY ( test_gmt3 . has_value ( ) ) ;
// Verify the parsed time by converting back to tm structure
auto result_time = test_gmt3 . value ( ) . to_timespec ( ) ;
struct tm tm ;
# ifdef AK_OS_WINDOWS
VERIFY ( gmtime_r ( & result_time . tv_sec , & tm ) = = 0 ) ;
# else
VERIFY ( gmtime_r ( & result_time . tv_sec , & tm ) ! = nullptr ) ;
# endif
EXPECT_EQ ( tm . tm_year + 1900 , 2023 ) ;
EXPECT_EQ ( tm . tm_mon + 1 , 6 ) ;
EXPECT_EQ ( tm . tm_mday , 15 ) ;
EXPECT_EQ ( tm . tm_hour , 18 ) ;
EXPECT_EQ ( tm . tm_min , 30 ) ;
EXPECT_EQ ( tm . tm_sec , 45 ) ;
}
2025-07-16 20:25:39 +02:00
TEST_CASE ( formatter_unix_date_time )
{
auto test = [ ] ( auto expected , i32 year , u8 month , u8 day , u8 hour , u8 minute , u8 second ) {
auto data = AK : : UnixDateTime : : from_unix_time_parts ( year , month , day , hour , minute , second , 0 ) ;
StringBuilder builder ;
builder . appendff ( " {} " , data ) ;
auto result = builder . to_string ( ) ;
VERIFY ( ! result . is_error ( ) ) ;
EXPECT_EQ ( expected , builder . to_string ( ) . value ( ) ) ;
} ;
test ( " 2023-01-05 00:00:00 " sv , 2023 , 1 , 5 , 0 , 0 , 0 ) ;
test ( " 1970-01-01 00:00:00 " sv , 1970 , 1 , 1 , 0 , 0 , 0 ) ; // Edge case for Unix epoch
test ( " 1970-01-01 23:59:59 " sv , 1970 , 1 , 1 , 23 , 59 , 59 ) ; // Edge case for Unix epoch
test ( " 2000-02-29 12:34:56 " sv , 2000 , 2 , 29 , 12 , 34 , 56 ) ; // Leap year (valid)
test ( " 1999-12-31 23:59:59 " sv , 1999 , 12 , 31 , 23 , 59 , 59 ) ; // Y2K edge
test ( " 2024-02-29 23:59:59 " sv , 2024 , 2 , 29 , 23 , 59 , 59 ) ; // Next leap year
test ( " 1980-01-01 00:00:00 " sv , 1980 , 1 , 1 , 0 , 0 , 0 ) ; // Another leap year start
test ( " 2038-01-19 03:14:07 " sv , 2038 , 1 , 19 , 3 , 14 , 7 ) ; // 32-bit Unix time max
test ( " 2022-12-31 23:59:59 " sv , 2022 , 12 , 31 , 23 , 59 , 59 ) ; // End of year
test ( " 2023-04-01 00:00:00 " sv , 2023 , 4 , 1 , 0 , 0 , 0 ) ; // Start of month
}
2025-10-02 08:58:48 -05:00
TEST_CASE ( from_f64_seconds )
{
constexpr auto max_seconds = Duration : : from_seconds ( NumericLimits < i64 > : : max ( ) ) ;
EXPECT_EQ ( Duration : : from_seconds_f64 ( NumericLimits < float > : : max ( ) ) , max_seconds ) ;
auto smaller_float = nextafterf ( NumericLimits < float > : : max ( ) , 0.0f ) ;
EXPECT_EQ ( Duration : : from_seconds_f64 ( smaller_float ) , max_seconds ) ;
auto max_representable_float = nextafterf ( static_cast < float > ( NumericLimits < i64 > : : max ( ) ) , 0.0f ) ;
constexpr auto max_representable_float_as_integer = 9223371487098961920LL ;
EXPECT_EQ ( Duration : : from_seconds_f64 ( max_representable_float ) , Duration : : from_seconds ( max_representable_float_as_integer ) ) ;
constexpr auto min_seconds = Duration : : from_seconds ( NumericLimits < i64 > : : min ( ) ) ;
EXPECT_EQ ( Duration : : from_seconds_f64 ( NumericLimits < float > : : lowest ( ) ) , min_seconds ) ;
EXPECT_EQ ( Duration : : from_seconds_f64 ( - smaller_float ) , min_seconds ) ;
EXPECT_EQ ( Duration : : from_seconds_f64 ( - max_representable_float ) , Duration : : from_seconds ( - max_representable_float_as_integer ) ) ;
EXPECT_EQ ( Duration : : from_seconds_f64 ( 1.5f ) , Duration : : from_milliseconds ( 1500 ) ) ;
EXPECT_EQ ( Duration : : from_seconds_f64 ( 205321.25f ) , Duration : : from_milliseconds ( 205321250 ) ) ;
EXPECT_EQ ( Duration : : from_seconds_f64 ( - 0.25f ) , Duration : : from_milliseconds ( - 250 ) ) ;
EXPECT_EQ ( Duration : : from_seconds_f64 ( - 1.75f ) , Duration : : from_milliseconds ( - 1750 ) ) ;
EXPECT_DEATH ( " Converting float NaN seconds " , ( void ) Duration : : from_seconds_f64 ( NAN ) ) ;
}
2025-11-10 16:07:17 -06:00
TEST_CASE ( time_units )
{
EXPECT_EQ ( Duration : : from_time_units ( 1 , 1 , 1 ) , Duration : : from_seconds ( 1 ) ) ;
EXPECT_EQ ( Duration : : from_time_units ( - 312 , 1 , 48'000 ) , Duration : : from_microseconds ( - 6'500 ) ) ;
EXPECT_EQ ( Duration : : from_time_units ( 960 , 1 , 48'000 ) , Duration : : from_microseconds ( 20'000 ) ) ;
EXPECT_EQ ( Duration : : from_time_units ( 960 , 1 , 48'000 ) , Duration : : from_microseconds ( 20'000 ) ) ;
EXPECT_EQ ( Duration : : from_time_units ( 8 , 4 , 1 ) , Duration : : from_seconds ( 32 ) ) ;
EXPECT_EQ ( Duration : : from_time_units ( 3 , 3 , 2'000'000'000 ) , Duration : : from_nanoseconds ( 5 ) ) ;
EXPECT_EQ ( Duration : : from_time_units ( 4 , 3 , 2'000'000'000 ) , Duration : : from_nanoseconds ( 6 ) ) ;
EXPECT_EQ ( Duration : : from_time_units ( 999'999'998 , 1 , 2'000'000'000 ) , Duration : : from_nanoseconds ( 499'999'999 ) ) ;
EXPECT_EQ ( Duration : : from_time_units ( 999'999'999 , 1 , 2'000'000'000 ) , Duration : : from_nanoseconds ( 500'000'000 ) ) ;
EXPECT_EQ ( Duration : : from_time_units ( 1'000'000'000 , 1 , 2'000'000'000 ) , Duration : : from_nanoseconds ( 500'000'000 ) ) ;
EXPECT_EQ ( Duration : : from_time_units ( NumericLimits < i64 > : : max ( ) , 1 , 2 ) , Duration : : from_seconds ( NumericLimits < i64 > : : max ( ) / 2 ) + Duration : : from_milliseconds ( 500 ) ) ;
EXPECT_EQ ( Duration : : from_time_units ( ( NumericLimits < i64 > : : max ( ) / 2 ) , 2 , 1 ) , Duration : : from_seconds ( NumericLimits < i64 > : : max ( ) - 1 ) ) ;
EXPECT_EQ ( Duration : : from_time_units ( ( NumericLimits < i64 > : : max ( ) / 2 ) + 1 , 2 , 1 ) , Duration : : from_seconds ( NumericLimits < i64 > : : max ( ) ) ) ;
EXPECT_EQ ( Duration : : from_time_units ( ( NumericLimits < i64 > : : min ( ) / 2 ) , 2 , 1 ) , Duration : : from_seconds ( NumericLimits < i64 > : : min ( ) ) ) ;
EXPECT_EQ ( Duration : : from_time_units ( ( NumericLimits < i64 > : : min ( ) / 2 ) - 1 , 2 , 1 ) , Duration : : from_seconds ( NumericLimits < i64 > : : min ( ) ) ) ;
EXPECT_EQ ( Duration : : from_milliseconds ( 999 ) . to_time_units ( 1 , 48'000 ) , 47'952 ) ;
EXPECT_EQ ( Duration : : from_milliseconds ( - 12'500 ) . to_time_units ( 1 , 1'000 ) , - 12'500 ) ;
EXPECT_EQ ( Duration : : from_milliseconds ( - 12'500 ) . to_time_units ( 1 , 1'000 ) , - 12'500 ) ;
EXPECT_EQ ( Duration : : from_nanoseconds ( 154'489'696 ) . to_time_units ( 1 , 48'000 ) , 7'416 ) ;
EXPECT_EQ ( Duration : : from_nanoseconds ( 154'489'375 ) . to_time_units ( 1 , 48'000 ) , 7'415 ) ;
EXPECT_EQ ( Duration : : from_nanoseconds ( - 154'489'696 ) . to_time_units ( 1 , 48'000 ) , - 7'416 ) ;
EXPECT_EQ ( Duration : : from_nanoseconds ( - 154'489'375 ) . to_time_units ( 1 , 48'000 ) , - 7'415 ) ;
EXPECT_EQ ( Duration : : from_nanoseconds ( 1'900'000'000 ) . to_time_units ( 3 , 2 ) , 1 ) ;
EXPECT_EQ ( Duration : : from_nanoseconds ( 1'800'000'000 ) . to_time_units ( 3 , 1 ) , 1 ) ;
EXPECT_EQ ( Duration : : from_seconds ( 3 ) . to_time_units ( 4 , 1 ) , 1 ) ;
EXPECT_EQ ( Duration : : from_seconds ( 4 ) . to_time_units ( 4 , 1 ) , 1 ) ;
EXPECT_EQ ( Duration : : from_seconds ( 5 ) . to_time_units ( 4 , 1 ) , 1 ) ;
EXPECT_EQ ( Duration : : from_seconds ( 6 ) . to_time_units ( 4 , 1 ) , 2 ) ;
EXPECT_EQ ( Duration : : from_seconds ( 2'147'483'649 ) . to_time_units ( 1 , NumericLimits < u32 > : : max ( ) ) , NumericLimits < i64 > : : max ( ) ) ;
EXPECT_EQ ( Duration : : from_seconds ( 2'147'483'648 ) . to_time_units ( 1 , NumericLimits < u32 > : : max ( ) ) , NumericLimits < i64 > : : max ( ) - ( NumericLimits < u32 > : : max ( ) / 2 ) ) ;
EXPECT_DEATH ( " From time units with zero numerator " , ( void ) Duration : : from_time_units ( 1 , 0 , 1 ) ) ;
EXPECT_DEATH ( " From time units with zero denominator " , ( void ) Duration : : from_time_units ( 1 , 1 , 0 ) ) ;
}