Roger Moore
Roger Moore

Reputation: 1121

Date in another Timezone: C++ on Linux

Is there any way of getting the date...preferably in YYYYMMDD format...in the Australia/Sydney timezone (not just GMT+11).....through C++ on Linux?

Thanks,

Roger

Upvotes: 6

Views: 4812

Answers (3)

Anya Shenanigans
Anya Shenanigans

Reputation: 94849

Yes, but you just use the standard c library mechanisms.

set the desired time zone in the environment by creating a string:

std::string tz = "Australia/Sydney";
setenv("TX", const_cast<char *>(tz.c_str()), 1);
tzset(); // Initialize timezone data
time_t aTime = time(NULL); // get the time - this is GMT based.
struct tm retTime;
localtime_r(&aTime, &retTime); // Convert time into current timezone.
char destString[1024];
strftime(destString, 1023, "%Y%m%d %Z", &retTime); // Format the output in the local time.
std::cout << destString << std::endl;

The problem is that this code is not thread safe - multiple threads changing the timezone information does not end well.

This Answer Gives you a way to do it using boost, which is definitely much easier.

Upvotes: 4

Howard Hinnant
Howard Hinnant

Reputation: 219345

New answer for old question:

In C++20 you can write:

#include <chrono>
#include <format>
#include <iostream>

int
main()
{
    using namespace std::chrono;
    using namespace std;

    zoned_time ymd{"Australia/Sydney", system_clock::now()};
    cout << format("{:%Y%m%d}", ymd) << '\n';
}

Which just output for me:

20220617

It is thread safe. It is as up-to-date as the copy of the IANA timezone database you're C++ vendor provides. And if your date happens to not be "now", it will correctly use the historical data from the IANA database.

Upvotes: 0

&#201;ric Malenfant
&#201;ric Malenfant

Reputation: 14148

Using Boost.DateTime (Warning: Not tested, for illustration purposes only)

// Load the timezone database
tz_database db;
// TODO: Adjust this path to your environment
db.load_from_file("./boost/libs/date_time/data/date_time_zonespec.csv"); 

// Get the Sydney timezone
time_zone_ptr sydney_zone = db.time_zone_from_region("Australia/Sydney");

// Current date/time in Sydney
local_date_time sydney_time = local_sec_clock::local_time(sydney_zone);

// Format sydney_time in desired format
std::ostringstream formatter;
formatter.imbue(std::locale(), new local_time_facet("%Y%m%d"));
formatter << sydney_time;

See:

Upvotes: 1

Related Questions