-
Notifications
You must be signed in to change notification settings - Fork 685
Boost datetime Examples Translated
Howard Hinnant edited this page Feb 14, 2021
·
44 revisions
This page shows how the boost datetime examples shown here:
http://www.boost.org/doc/libs/1_59_0/doc/html/date_time/examples.html#date_time.examples.time_math
look if ported to this library.
- Dates as Strings
- Days Alive
- Days Between New Years
- Last Day of the Months
- Localization Demonstration
- Date Period Calculations
- Print Holidays
- Print Month
- Month Adding
- Time Math
- Print Hours
- Local to UTC Conversion
- Time Periods
- Simple Time Zones
- Daylight Savings Calc Rules
- Flight Time Example
- Seconds Since Epoch
#include "date/date.h"
#include <cassert>
#include <iostream>
#include <sstream>
#include <exception>
int
main()
{
using namespace date;
using namespace std;
try
{
// The following date is in ISO 8601 extended format (CCYY-MM-DD)
istringstream in{"2001-10-9"}; // 2001-October-09
year_month_day d;
in >> parse("%F", d);
assert(d.ok());
cout << format("%Y-%b-%d\n", d);
// Read ISO Standard(CCYYMMDD) and output ISO Extended
in.str("20011009"); // 2001-Oct-09
in >> parse("%Y%m%d", d);
assert(d.ok());
cout << d << '\n'; // 2001-10-09
// Output the parts of the date - Tuesday October 9, 2001
cout << format("%A %B %e, %Y\n", d);
// Let's send in month 25 by accident and create an exception
in.str("20012509"); // 2001-??-09
in.clear();
in.exceptions(std::ios::failbit);
cout << "An expected exception is next:" << endl;
in >> parse("%Y%m%d", d);
cout << "oh oh, you shouldn't reach this line:\n";
}
catch (const exception& e)
{
cout << "Exception: " << e.what() << '\n';
}
}
#include "date/tz.h"
#include <iostream>
int
main()
{
std::string s;
std::cout << "Enter birth day YYYY-MM-DD (eg: 2002-02-01): ";
try
{
using namespace std::chrono;
using namespace date;
std::cin.exceptions(std::ios::failbit);
local_days d;
std::cin >> parse("%F", d);
auto today = make_zoned(current_zone(), system_clock::now());
auto days_alive = floor<days>(today.get_local_time() - d);
if (days_alive == days{1})
std::cout << "Born yesterday, very funny\n";
else if (days_alive < days{0})
std::cout << "Not born yet, hmm: " << days_alive.count()
<< " days\n";
else
std::cout << "Days alive: " << days_alive.count() << '\n';
}
catch (...)
{
std::cout << "Bad date entered\n";
}
}
#include "date/tz.h"
#include <iostream>
int
main()
{
using namespace std::chrono;
using namespace date;
auto today = floor<days>(make_zoned(current_zone(),
system_clock::now()).get_local_time());
auto current_year = year_month_day{today}.year();
auto days_since_year_start = today - local_days{current_year/January/1};
std::cout << "Days since Jan 1: "
<< days_since_year_start.count() << '\n';
auto days_until_year_start =
local_days{(current_year + years{1})/January/1} - today;
std::cout << "Days until next Jan 1: "
<< days_until_year_start.count() << '\n';
}
#include "date.h"
#include <cassert>
#include <iostream>
int
main()
{
using namespace date;
std::cout << " Enter Year(ex: 2002): ";
year y;
std::cin >> parse("%Y", y);
assert(!std::cin.fail());
std::cout << " Enter Month(1..12): ";
month m;
std::cin >> parse(" %m", m);
assert(!std::cin.fail());
auto start_of_next_year = y/jan + years{1};
for (auto ym = y/m; ym < start_of_next_year; ym += months{1})
std::cout << year_month_day{ym/last} << '\n';
}
#include "date.h"
#include <iomanip>
#include <iostream>
// Define a series of char arrays for short and long name strings
// to be associated with German date output (US names will be
// retrieved from the locale).
const char* const de_long_month_names[] =
{
"Januar", "Februar", "Marz", "April", "Mai",
"Juni", "Juli", "August", "September", "Oktober",
"November", "Dezember", "NichtDerMonat"
};
const char* const de_long_weekday_names[] =
{
"Sonntag", "Montag", "Dienstag", "Mittwoch",
"Donnerstag", "Freitag", "Samstag"
};
int
main()
{
using namespace date;
// create some gregorian objects to output
auto d1 = 2002_y/oct/1;
auto m = d1.month();
auto wd = weekday{d1};
using namespace std;
// output the date in German using short month names
cout << d1.day() << '.'
<< setw(2) << static_cast<unsigned>(d1.month())
<< '.' << d1.year() << '\n';
cout << de_long_month_names[static_cast<unsigned>(m)-1] << '\n';
cout << de_long_weekday_names[static_cast<unsigned>(wd)] << '\n';
cout << static_cast<unsigned>(d1.month()) << '/' << d1.day()
<< '/' << d1.year() << '\n';
cout << d1.year() << '-' << d1.month() << '-' << d1.day() << '\n';
}
If your OS supports the std::locale("de_DE")
the above can be simplified to:
#include "date.h"
#include "tz.h"
#include <iostream>
int
main()
{
using namespace date;
// create some gregorian objects to output
auto d1 = 2002_y/oct/1;
using namespace std;
locale loc("de_DE");
cout << format(loc, "%x\n", local_days{d1});
cout << format(loc, "%B\n", local_days{d1});
cout << format(loc, "%A\n", local_days{d1});
cout << format(loc, "%D\n", local_days{d1});
cout << format(loc, "%F\n", local_days{d1});
}
#include "date.h"
#include <iostream>
int
main()
{
using namespace date;
using date_period = std::pair<year_month_day, year_month_day>;
constexpr date_period ps[] =
{
{feb/ 2/2002, feb/ 4/2002}, // weekend of 2nd-3rd
{feb/ 9/2002, feb/11/2002},
{feb/16/2002, feb/18/2002},
{feb/23/2002, feb/25/2002},
{feb/12/2002, feb/13/2002} // a random holiday 2-12
};
std::cout << "Number Excluded Periods: " << sizeof(ps)/sizeof(ps[0]) << '\n';
auto d = feb/16/2002;
for (const auto& p : ps)
{
std::cout << p.first << " / " << p.second << '\n';
if (p.first <= d && d < p.second)
std::cout << "In Exclusion Period: "
<< d << " --> "
<< p.first << " / " << p.second << '\n';
}
}
#include "date.h"
#include <iostream>
#include <vector>
std::vector<date::sys_days>
generate_holidays(date::year y)
{
using namespace date;
std::vector<sys_days> holidays;
holidays.push_back(y/jan/1); // Western New Year
holidays.push_back(y/jul/4); // US Independence Day
holidays.push_back(y/dec/25); // Christmas day
holidays.push_back(y/sep/mon[1]); // US labor day
holidays.push_back(y/jan/mon[3]); // MLK Day
holidays.push_back(y/feb/tue[2]); // Pres day
holidays.push_back(y/nov/thu[4]); // Thanksgiving
std::sort(holidays.begin(), holidays.end());
return holidays;
}
int
main()
{
using namespace date;
std::cout << "Enter Year: ";
year y;
std::cin >> parse("%Y", y);
//define a collection of holidays fixed by month and day
auto holidays = generate_holidays(y);
for (const auto& d : holidays)
std::cout << d << " [" << weekday{d} << "]\n";
std::cout << "Number Holidays: " << holidays.size() << '\n';
}
#include "date.h"
#include <iostream>
int
main()
{
using namespace date;
try
{
std::cin.exceptions(std::ios::failbit);
std::cout << "Enter Year: ";
year y;
std::cin >> parse("%Y", y);
std::cout << "Enter Month(1..12): ";
month m;
std::cin >> parse(" %m", m);
auto ym = y/m;
auto endOfMonth = (ym/last).day();
for (auto d = 1_d; d <= endOfMonth; d += days{1})
std::cout << format("%F [%a]\n", ym/d);
}
catch (const std::exception& e)
{
std::cerr << "Error bad date, check your entry: \n"
<< " Details: " << e.what() << '\n';
}
}
#include "tz.h"
#include <iostream>
int
main()
{
using namespace std::chrono;
using namespace date;
auto d = year_month_day{floor<days>(make_zoned(current_zone(),
system_clock::now()).get_local_time())};
auto d2 = d + months{1};
if (!d2.ok())
d2 = d2.year()/d2.month()/last; // boost snaps to last
std::cout << "Today is: " << d << ".\n"
<< "One month from today will be: " << d2 << '\n';
}
#include "date.h"
#include <iostream>
int
main()
{
using namespace std::chrono;
using namespace date;
auto d = sys_days{2002_y/feb/1}; // an arbitrary date;
// construct a time by adding up some durations durations
auto t1 = d + 5h + 4min + 2s + 1ms;
// construct a new time by subtracting some times
auto t2 = t1 - 5h - 4min - 2s - 1ms;
// construct a duration by taking the difference between times
auto td = t2 - t1;
std::cout << t2 << " - " << t1 << " = " << format("%T\n", td);
// 2002-02-01 00:00:00.000 - 2002-02-01 05:04:02.001 = -05:04:02.001
}
#include "tz.h"
#include <iostream>
int
main()
{
using namespace std::chrono;
using namespace date;
// get the current local time from the clock -- one second resolution
auto now = make_zoned(current_zone(),
floor<seconds>(system_clock::now())).get_local_time();
// Get the date part out of the time
auto today = floor<days>(now);
auto tomorrow = today + days{1}; // midnight
for (auto i = now; i < tomorrow; i += 1h)
std::cout << i << '\n';
std::cout << format("Time left until midnight: %T\n", tomorrow - now);
}
#include "tz.h"
#include <iostream>
int
main()
{
using namespace std::chrono;
using namespace date;
auto zone = current_zone();
auto t10 = sys_days(2002_y/jan/1) + 7h;
auto t11 = make_zoned(zone, t10);
std::cout << "UTC <--> Zone base on current setting\n";
std::cout << t11 << " is " << t10 << " UTC time\n";
auto td = t11.get_local_time().time_since_epoch() - t10.time_since_epoch();
std::cout << "A difference of: " << format("%T\n", td);
// eastern timezone is utc-5
zone = locate_zone("America/New_York");
// 5 hours b/f midnight NY time
auto t1 = local_days{2001_y/dec/31} + 19h + 0s;
std::cout << "\nUTC <--> New York while DST is NOT active (5 hours)\n";
auto t2 = make_zoned(zone, t1);
std::cout << t1 << " in New York is " << t2.get_sys_time() << " UTC time\n";
std::cout << t2.get_sys_time() << " UTC is " << t2.get_local_time() << " New York time\n\n";
// 4 hours b/f midnight NY time
auto t4 = local_days{2002_y/may/31} + 20h + 0s;
std::cout << "UTC <--> New York while DST is active (4 hours)\n";
auto t5 = make_zoned(zone, t4);
std::cout << t4 << " in New York is " << t5.get_sys_time() << " UTC time\n";
std::cout << t5.get_sys_time() << " UTC is " << t5.get_local_time() << " New York time\n\n";
// Arizona timezone is utc-7 with no dst
zone = locate_zone("America/Phoenix");
auto t7 = local_days(2002_y/may/31) + 17h + 0s;
std::cout << "UTC <--> Arizona (7 hours)\n";
auto t8 = zone->to_sys(t7);
std::cout << t7 << " in Arizona is " << t8 << " UTC time\n";
}
#include "date.h"
#include <iostream>
int
main()
{
using namespace std::chrono;
using namespace date;
auto d = sys_days{2002_y/feb/1}; // an arbitrary date
auto t = d + 3h + 5s; //an arbitray time on that day
if (d <= t && t < d + days{1})
std::cout << d << " contains " << t << '\n';
// Time periods not part of this library but can be built
// from a pair of time_points.
}
The boost example shows custom time zones. This library supports only the full history of the IANA timezone database. To achieve a custom timezone you would need to edit the IANA timezone database. For an example using the IANA timezone database see the Local to UTC Conversion example.
// This library does not support custom daylight savings rules. But it
// does support the notion of partial dates and finding the nth (or last)
// weekday of a month.
#include "date.h"
int
main()
{
using namespace date::literals;
auto fd_start = sun[1]/may;
auto ld_start = sun[last]/may;
auto nkd_start = sun[3]/may;
auto pd_start = may/1;
auto fd_end = sun[1]/oct;
auto ld_end = sun[last]/oct;
auto nkd_end = sun[3]/oct;
auto pd_end = oct/31;
}
#include "date/tz.h"
#include <iostream>
int
main()
{
using namespace std::chrono;
using namespace date;
// set up some timezones for creating and adjusting local times
auto phx_tz = locate_zone("America/Phoenix");
auto nyc_tz = locate_zone("America/New_York");
// local departure time in phoenix is 11 pm on March 30 2005
// (ny changes to dst on apr 3 at 2 am)
zoned_seconds phx_departure{phx_tz, local_days{2005_y/March/30} + 23h};
// flight is 4 hours, 30 minutes
zoned_seconds phx_arrival{phx_tz, phx_departure.get_sys_time() + 4h + 30min};
zoned_seconds nyc_arrival{nyc_tz, phx_arrival};
std::cout << "departure phx time: " << phx_departure << '\n';
std::cout << "arrival phx time: " << phx_arrival << '\n';
std::cout << "arrival nyc time: " << nyc_arrival << '\n';
}
// Output:
//
// departure phx time: 2005-03-30 23:00:00 MST
// arrival phx time: 2005-03-31 03:30:00 MST
// arrival nyc time: 2005-03-31 05:30:00 EST
//
// Note that boost states a nyc_arrival time of 2005-Mar-31 06:30:00 EDT
// because boost uses the current US daylightsavings rules as opposed to
// those that were in effect in 2005. This library varies its DST rules
// with the date.
#include "tz.h"
#include <iostream>
int
main()
{
using namespace std::chrono;
using namespace date;
auto nyc_time = make_zoned("America/New_York",
local_days(2004_y/oct/4) + 12h + 14min + 32s);
std::cout << nyc_time << '\n';
auto sys_epoch = sys_days{};
std::cout << sys_epoch << '\n';
// first convert nyc_time to utc via the get_sys_time()
// call and subtract the sys_epoch.
auto sys_time = nyc_time.get_sys_time();
// Expected 1096906472
std::cout << "Seconds diff: " << sys_time - sys_epoch << '\n';
// Take leap seconds into account
auto utc_time = to_utc_time(sys_time);
auto utc_epoc = to_utc_time(sys_epoch);
// Expected 1096906494, an extra 22s
std::cout << "Seconds diff: " << utc_time - utc_epoc << '\n';
}