├── .travis.yml
├── LICENSE
├── README.md
├── sample.cc
├── sand.cpp
└── sand.hpp
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: cpp
2 | sudo: required
3 |
4 | compiler:
5 | - clang
6 | - gcc
7 |
8 | install:
9 | - wget --quiet -O - https://raw.githubusercontent.com/r-lyeh/depot/master/travis.pre.sh | bash -x
10 |
11 | script:
12 | - wget --quiet -O - https://raw.githubusercontent.com/r-lyeh/depot/master/travis.build.sh | bash -x
13 | - wget --quiet -O - https://raw.githubusercontent.com/r-lyeh/depot/master/travis.run.sh | bash -x
14 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2015 r-lyeh (https://github.com/r-lyeh)
2 |
3 | This software is provided 'as-is', without any express or implied
4 | warranty. In no event will the authors be held liable for any damages
5 | arising from the use of this software.
6 |
7 | Permission is granted to anyone to use this software for any purpose,
8 | including commercial applications, and to alter it and redistribute it
9 | freely, subject to the following restrictions:
10 |
11 | 1. The origin of this software must not be misrepresented; you must not
12 | claim that you wrote the original software. If you use this software
13 | in a product, an acknowledgment in the product documentation would be
14 | appreciated but is not required.
15 | 2. Altered source versions must be plainly marked as such, and must not be
16 | misrepresented as being the original software.
17 | 3. This notice may not be removed or altered from any source distribution.
18 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | sand
2 | ====
3 |
4 | Sand is a lightweight timer controller (C++11).
5 |
6 | Features:
7 | - [x] Wrapper around Unix stamps, hires timers and calendars.
8 | - [x] Portable. Does not rely on standard C library or locales.
9 | - [x] Cross-platform, stand-alone, no external dependencies only.
10 | - [x] Tiny. One header and one source file.
11 | - [x] ZLIB/LibPNG licensed.
12 |
13 | ### API - time format (64-bit base10)
14 | ```
15 | 18446744073709551615
16 | 00YYMMDDhhmmssxxxxxx xxx xxx = microseconds
17 |
18 | proposal
19 | 18446744073709551615
20 | 1TTTTYYMMDDhhmmssxxx TTTT = timezone, xxx = milliseconds
21 | ```
22 |
23 | ### API
24 | ```c++
25 | namespace sand
26 | {
27 | using point = uint64_t; // absolute time in milliseconds since Unix Epoch (1970/01/01 00:00:00.000 +00:00)
28 | using lapse = int64_t; // relative time in milliseconds between two timepoints; can be negative.
29 | using uint = unsigned int;
30 |
31 | // sleep thread for specified milliseconds (at least)
32 | void sleep( int64_t stamp );
33 |
34 | // UTC absolute time, GMT timezone, local time and uptime since program epoch (in milliseconds)
35 | int64_t utc();
36 | int64_t gmt();
37 | int64_t now();
38 | int64_t uptime();
39 |
40 | // advance/rewind all clocks specified milliseconds (useful for QA and testing purposes)
41 | void shift( int64_t lapse );
42 |
43 | // conversion to milliseconds
44 | int64_t nanoseconds( int64_t lapse );
45 | int64_t microseconds( int64_t lapse );
46 | int64_t milliseconds( int64_t lapse );
47 | int64_t seconds( int64_t lapse );
48 | int64_t minutes( int64_t lapse );
49 | int64_t hours( int64_t lapse );
50 | int64_t days( int64_t lapse );
51 | int64_t weeks( int64_t lapse );
52 |
53 | // conversion from milliseconds
54 | int64_t as_nanoseconds( int64_t lapse );
55 | int64_t as_microseconds( int64_t lapse );
56 | int64_t as_milliseconds( int64_t lapse );
57 | int64_t as_seconds( int64_t lapse );
58 | int64_t as_minutes( int64_t lapse );
59 | int64_t as_hours( int64_t lapse );
60 | int64_t as_days( int64_t lapse );
61 | int64_t as_weeks( int64_t lapse );
62 |
63 | // calendar
64 | int64_t date( int year, int month, int day );
65 | int64_t time( int hour, int minute, int second, int millis = 0 );
66 | int64_t datetime( int year, int month, int day, int hour, int minute, int second, int millis = 0 );
67 |
68 | // extraction
69 | int year( int64_t stamp );
70 | int month( int64_t stamp );
71 | int day( int64_t stamp );
72 | int hour( int64_t stamp );
73 | int minute( int64_t stamp );
74 | int second( int64_t stamp );
75 | int millisecond( int64_t stamp );
76 |
77 | // print
78 | std::string format( int64_t stamp, const std::string &format = "yyyy-mm-dd HH:MM:SS.MS" );
79 | std::string pretty( int64_t lapse );
80 |
81 | // serialization
82 | std::string str( int64_t stamp );
83 | int64_t str( const std::string &ymdhmsmtz );
84 |
85 | class sand::timer dt;
86 | // usage:
87 | // - int64_t nanoseconds_taken = dt.ns(); // (relative time)
88 | // - int64_t seconds_taken = dt.s(); // (relative time)
89 | // - int64_t milliseconds_taken = dt.ms(); // (relative time)
90 | // - see also .reset();
91 |
92 | class sand::chrono chr(3.5); // in seconds
93 | // usage:
94 | // - chr.t() -> [0..1] (normalized floating time)
95 | // - see also .reset();
96 |
97 | class sand::looper lp(3.5); // in seconds (similar to sand::chrono but will loop over and over)
98 | // usage:
99 | // - lp.t() -> [0..1][...] (normalized floating time)
100 | // - see also .reset();
101 | }
102 | ```
103 |
104 | ### Special notes
105 | - g++ users: both `-std=c++11` and `-lrt` may be required when compiling `sand.cpp`
106 |
107 | ### Changelog
108 | - v2.0.0 (2015/09/26)
109 | - A step forward towards portability and determinism.
110 | - v0.1.0 (2015/09/19)
111 | - Moved framerate locker to a library apart
112 | - v0.0.0 (2010/xx/xx)
113 | - Initial version
114 |
--------------------------------------------------------------------------------
/sample.cc:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include "sand.hpp"
5 |
6 | int main() {
7 | using namespace sand;
8 |
9 | sand::timer timer;
10 |
11 | std::cout << format( utc(), "yyyy-mm-ddTHH:MM:MS" ) << std::endl;
12 | std::cout << format( now(), "d/mmmm/yy HH:MM:SS.MS" ) << std::endl;
13 | std::cout << format( uptime(), "HH:MM:SS.MS" ) << std::endl;
14 |
15 | assert( pretty( seconds(- 0) ) == "right now" );
16 | assert( pretty( seconds(- 1) ) == "a second ago" );
17 | assert( pretty( seconds(- 2) ) == "2 seconds ago" );
18 | assert( pretty( seconds(-60) ) == "a minute ago" );
19 | assert( pretty( seconds(-61) ) == "a minute ago" );
20 | assert( pretty( minutes(- 1) ) == "a minute ago" );
21 | assert( pretty( minutes(-60) ) == "an hour ago" );
22 | assert( pretty( minutes(-61) ) == "an hour ago" );
23 | assert( pretty( hours(- 1) ) == "an hour ago" );
24 | assert( pretty( hours(-24) ) == "yesterday" );
25 | assert( pretty( hours(-25) ) == "yesterday" );
26 | assert( pretty( days( -1) ) == "yesterday" );
27 | assert( pretty( days( -5) ) == "5 days ago" );
28 | assert( pretty( days( -7) ) == "7 days ago" );
29 | assert( pretty( days(-12) ) == "12 days ago" );
30 | assert( pretty( days(-13) ) == "13 days ago" );
31 | assert( pretty( days(-14) ) == "2 weeks ago" );
32 | assert( pretty( days(-32) ) == "a month ago" );
33 | assert( pretty( weeks(-52) ) == "11 months ago" );
34 | assert( pretty( weeks(-53) ) == "a year ago" );
35 |
36 | assert( pretty( seconds(+ 0) ) == "right now" );
37 | assert( pretty( seconds(+ 1) ) == "a second from now" );
38 | assert( pretty( seconds(+ 2) ) == "2 seconds from now" );
39 | assert( pretty( seconds(+60) ) == "a minute from now" );
40 | assert( pretty( seconds(+61) ) == "a minute from now" );
41 | assert( pretty( minutes(+ 1) ) == "a minute from now" );
42 | assert( pretty( minutes(+60) ) == "an hour from now" );
43 | assert( pretty( minutes(+61) ) == "an hour from now" );
44 | assert( pretty( hours(+ 1) ) == "an hour from now" );
45 | assert( pretty( hours(+24) ) == "tomorrow" );
46 | assert( pretty( hours(+25) ) == "tomorrow" );
47 | assert( pretty( days( +1) ) == "tomorrow" );
48 | assert( pretty( days( +5) ) == "5 days from now" );
49 | assert( pretty( days( +7) ) == "7 days from now" );
50 | assert( pretty( days(+12) ) == "12 days from now" );
51 | assert( pretty( days(+13) ) == "13 days from now" );
52 | assert( pretty( days(+14) ) == "2 weeks from now" );
53 | assert( pretty( days(+32) ) == "a month from now" );
54 | assert( pretty( weeks(+52) ) == "11 months from now" );
55 | assert( pretty( weeks(+53) ) == "a year from now" );
56 |
57 | std::cout << pretty( str("2000-01-01 00:00:00") - now() ) << std::endl;
58 |
59 | {
60 | auto rtc = now();
61 | auto then = str( "2010-12-31 23:59:59" );
62 | std::cout << str(then) << std::endl;
63 |
64 | auto then2 = date(2010,12,31) + time(23,59,59,00);
65 | std::cout << str(then2) << std::endl;
66 | assert( str(then) == str(then2) );
67 |
68 | assert( year(then) == 2010 );
69 | assert( month(then) == 12 );
70 | assert( day(then) == 31 );
71 | assert( hour(then) == 23 );
72 | assert( minute(then) == 59 );
73 | assert( second(then) == 59 );
74 | assert( millisecond(then) == 0 );
75 |
76 | std::cout << "[ ] print ";
77 | std::cout << "- rtc : " << std::setprecision(20) << rtc << " -> " << str(rtc) << " -> " << pretty(now() - rtc);
78 | std::cout << "\r[x]" << std::endl;
79 |
80 | std::cout << "[ ] serialization ";
81 | std::cout << "- rtc : " << str(rtc);
82 | std::cout << "\r[x]" << std::endl;
83 |
84 | std::cout << "[ ] print ";
85 | std::cout << "- then : " << std::setprecision(20) << then << " -> " << str(then) << " -> " << pretty(then - now());
86 | std::cout << "\r[x]" << std::endl;
87 |
88 | std::cout << "[ ] serialization ";
89 | std::cout << "- then : " << str(then);
90 | std::cout << "\r[x]" << std::endl;
91 |
92 | std::cout << "[ ] logical/arithmetical tests";
93 | rtc ++;
94 | then ++;
95 | assert( rtc == rtc );
96 | assert( rtc != then );
97 | assert( rtc + 1 > rtc );
98 | std::cout << "\r[x]" << std::endl;
99 |
100 | std::cout << "[ ] daylight savings tests";
101 | auto winter = str( "2010-12-31T23:59:59.003Z" );
102 | auto autumn = str( "2001-10-10 17:00:00" );
103 | assert( str(winter) == "2010-12-31 23:59:59.003" );
104 | assert( str(autumn) == "2001-10-10 17:00:00.000" );
105 | std::cout << "\r[x]" << std::endl;
106 | }
107 |
108 |
109 | {
110 | auto
111 | past = str( "1972-06-10 17:00:00" ),
112 | present = now(),
113 | future = str( "2091-12-31 23:59:55" );
114 |
115 | std::cout << str(past) << std::endl;
116 |
117 | assert( str(past) == "1972-06-10 17:00:00.000" );
118 | //assert( str(present) == "your current time and date" );
119 | assert( str(future) == "2091-12-31 23:59:55.000" );
120 |
121 | past += seconds(1);
122 | present += seconds(1);
123 | future += seconds(6);
124 |
125 | assert( str(past) == "1972-06-10 17:00:01.000" );
126 | //assert( str(present) == "your current time and date plus one second" );
127 | assert( str(future) == "2092-01-01 00:00:01.000" );
128 | }
129 |
130 | sand::chrono total(4);
131 | sand::looper looper(0.5);
132 | while( total.t() < 1 ) {
133 | std::cout << "looper: " << looper.t() << std::endl;
134 | sand::sleep(sand::seconds(1)/4);
135 | }
136 |
137 | std::cout << "---" << std::endl;
138 | std::cout << "All ok, " << timer.ms() << "ms " << std::endl;
139 | }
140 |
--------------------------------------------------------------------------------
/sand.cpp:
--------------------------------------------------------------------------------
1 | // Sand, a functional time controller (C++11). ZLIB/LibPNG licensed.
2 | // - rlyeh ~~ listening to The Mission / Butterfly on a wheel
3 |
4 | #include
5 | #include
6 | #include
7 |
8 | #include
9 | #include
10 | #include
11 | #include