This commit is contained in:
Charles Dang 2025-03-25 18:24:32 -04:00 committed by GitHub
commit 665ac80b52
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
25 changed files with 131 additions and 120 deletions

View File

@ -298,11 +298,6 @@ std::size_t config_attribute_value::to_size_t(std::size_t def) const
return apply_visitor(attribute_numeric_visitor<std::size_t>(def));
}
std::time_t config_attribute_value::to_time_t(std::time_t def) const
{
return apply_visitor(attribute_numeric_visitor<std::time_t>(def));
}
double config_attribute_value::to_double(double def) const
{
return apply_visitor(attribute_numeric_visitor<double>(def));

View File

@ -33,7 +33,6 @@
#include <chrono>
#include <climits>
#include <ctime>
#include <iosfwd>
#include <string>
#include <vector>
@ -153,7 +152,6 @@ public:
long long to_long_long(long long def = 0) const;
unsigned to_unsigned(unsigned def = 0) const;
std::size_t to_size_t(std::size_t def = 0) const;
std::time_t to_time_t(std::time_t def = 0) const;
double to_double(double def = 0.) const;
std::string str(const std::string& fallback = "") const;
t_string t_str() const;

View File

@ -25,6 +25,7 @@
#include "gettext.hpp"
#include "log.hpp"
#include "serialization/base64.hpp"
#include "serialization/chrono.hpp"
#include "serialization/string_utils.hpp"
#include "serialization/unicode.hpp"
#include "utils/general.hpp"
@ -443,6 +444,9 @@ static bfs::path subtract_path(const bfs::path& full, const bfs::path& prefix_pa
return rest;
}
// Forward declaration, implemented below
std::chrono::system_clock::time_point file_modified_time(const bfs::path& path);
void get_files_in_dir(const std::string& dir,
std::vector<std::string>* files,
std::vector<std::string>* dirs,
@ -503,10 +507,7 @@ void get_files_in_dir(const std::string& dir,
push_if_exists(files, di->path(), mode == name_mode::ENTIRE_FILE_PATH);
if(checksum != nullptr) {
std::time_t mtime = bfs::last_write_time(di->path(), ec);
if(ec) {
LOG_FS << "Failed to read modification time of " << di->path().string() << ": " << ec.message();
} else if(mtime > checksum->modified) {
if(auto mtime = file_modified_time(di->path()); mtime > checksum->modified) {
checksum->modified = mtime;
}
@ -1243,15 +1244,21 @@ bool file_exists(const std::string& name)
return file_exists(bfs::path(name));
}
std::time_t file_modified_time(const std::string& fname)
/** @todo expose to public interface. Most string functions should take a path object */
std::chrono::system_clock::time_point file_modified_time(const bfs::path& path)
{
error_code ec;
std::time_t mtime = bfs::last_write_time(bfs::path(fname), ec);
std::time_t mtime = bfs::last_write_time(path, ec);
if(ec) {
LOG_FS << "Failed to read modification time of " << fname << ": " << ec.message();
LOG_FS << "Failed to read modification time of " << path.string() << ": " << ec.message();
}
return mtime;
return chrono::parse_timestamp(mtime);
}
std::chrono::system_clock::time_point file_modified_time(const std::string& fname)
{
return file_modified_time(bfs::path(fname));
}
bool is_map(const std::string& filename)

View File

@ -20,7 +20,7 @@
#pragma once
#include <ctime>
#include <chrono>
#include <cstdint>
#include <fstream>
#include <iosfwd>
@ -274,7 +274,7 @@ bool is_directory(const std::string& fname);
bool file_exists(const std::string& name);
/** Get the modification time of a file. */
std::time_t file_modified_time(const std::string& fname);
std::chrono::system_clock::time_point file_modified_time(const std::string& fname);
/** Returns true if the file ends with the mapfile extension. */
bool is_map(const std::string& filename);
@ -309,13 +309,12 @@ bool is_legal_user_file_name(const std::string& name, bool allow_whitespace = tr
struct file_tree_checksum
{
file_tree_checksum();
file_tree_checksum() = default;
explicit file_tree_checksum(const config& cfg);
void write(config& cfg) const;
void reset() {nfiles = 0;modified = 0;sum_size=0;}
// @todo make variables private!
std::size_t nfiles, sum_size;
std::time_t modified;
std::size_t nfiles{}, sum_size{};
std::chrono::system_clock::time_point modified{};
bool operator==(const file_tree_checksum &rhs) const;
bool operator!=(const file_tree_checksum &rhs) const
{ return !operator==(rhs); }

View File

@ -17,6 +17,7 @@
#include "config.hpp"
#include "log.hpp"
#include "serialization/chrono.hpp"
#include "serialization/string_utils.hpp"
#include "serialization/unicode.hpp"
#include "utils/general.hpp"
@ -264,14 +265,10 @@ bool looks_like_pbl(const std::string& file)
return utils::wildcard_string_match(utf8::lowercase(file), "*.pbl");
}
file_tree_checksum::file_tree_checksum()
: nfiles(0), sum_size(0), modified(0)
{}
file_tree_checksum::file_tree_checksum(const config& cfg) :
nfiles (cfg["nfiles"].to_size_t()),
sum_size(cfg["size"].to_size_t()),
modified(cfg["modified"].to_time_t())
file_tree_checksum::file_tree_checksum(const config& cfg)
: nfiles(cfg["nfiles"].to_size_t())
, sum_size(cfg["size"].to_size_t())
, modified(chrono::parse_timestamp(cfg["modified"]))
{
}
@ -279,7 +276,7 @@ void file_tree_checksum::write(config& cfg) const
{
cfg["nfiles"] = nfiles;
cfg["size"] = sum_size;
cfg["modified"] = modified;
cfg["modified"] = chrono::serialize_timestamp(modified);
}
bool file_tree_checksum::operator==(const file_tree_checksum &rhs) const
@ -341,7 +338,7 @@ const file_tree_checksum& data_tree_checksum(bool reset)
{
static file_tree_checksum checksum;
if (reset)
checksum.reset();
checksum = file_tree_checksum{};
if(checksum.nfiles == 0) {
get_file_tree_checksum_internal("data/",checksum);
get_file_tree_checksum_internal(get_user_data_dir() + "/data/",checksum);

View File

@ -15,22 +15,65 @@
#include "format_time_summary.hpp"
#include "assert.h"
#include "gettext.hpp"
#include "preferences/preferences.hpp"
#include "serialization/chrono.hpp"
namespace utils {
#include <cassert>
#ifndef CPP20_CHRONO_SUPPORT
#include <ctime>
#endif
std::string format_time_summary(std::time_t t) {
std::time_t curtime = std::time(nullptr);
const std::tm* timeptr = std::localtime(&curtime);
namespace utils
{
std::string format_time_summary(const std::chrono::system_clock::time_point& t)
{
#ifdef CPP20_CHRONO_SUPPORT
const auto now = std::chrono::system_clock::now();
std::string format_string;
auto curr_time = std::chrono::year_month_weekday{std::chrono::floor<std::chrono::days>(now)};
auto save_time = std::chrono::year_month_weekday{std::chrono::floor<std::chrono::days>(t)};
if(curr_time == save_time) {
// save is from today
format_string = prefs::get().use_twelve_hour_clock_format()
// TRANSLATORS: 12-hour time, eg '1:59 PM'
? _("%I:%M %p")
// TRANSLATORS: 24-hour time, eg '13:59'
: _("%H:%M");
} else if(curr_time.month() == save_time.month() && curr_time.index() == save_time.index()) {
// save is from this week
format_string = prefs::get().use_twelve_hour_clock_format()
// TRANSLATORS: Day of week + 12-hour time, eg 'Sunday, 1:59 PM'
? _("%A, %I:%M %p")
// TRANSLATORS: Day of week + 24-hour time, eg 'Sunday, 13:59'
: _("%A, %H:%M");
} else if(curr_time.year() == save_time.year()) {
// save is from current year
// TRANSLATORS: Month + day of month, eg 'Nov 02'. Format for your locale.
format_string = _("%b %d");
} else {
// save is from a different year
// TRANSLATORS: Month + day of month + year, eg 'Nov 02 2021'. Format for your locale.
format_string = _("%b %d %Y");
}
#else
const auto now = std::chrono::system_clock::now();
auto as_time_t = std::chrono::system_clock::to_time_t(now);
const std::tm* timeptr = std::localtime(&as_time_t);
if(timeptr == nullptr) {
return "";
}
const std::tm current_time = *timeptr;
timeptr = std::localtime(&t);
as_time_t = std::chrono::system_clock::to_time_t(t);
timeptr = std::localtime(&as_time_t);
if(timeptr == nullptr) {
return "";
}
@ -71,9 +114,10 @@ std::string format_time_summary(std::time_t t) {
// TRANSLATORS: Month + day of month + year, eg 'Nov 02 2021'. Format for your locale.
format_string = _("%b %d %Y");
}
#endif
// TODO: make sure this doesn't result in #1709 coming back
assert(!format_string.empty());
return translation::strftime(format_string, &save_time);
return chrono::format_local_timestamp(t, format_string);
}
}
} // namespace utils

View File

@ -15,9 +15,9 @@
#pragma once
#include <ctime>
#include <chrono>
#include <string>
namespace utils {
std::string format_time_summary(std::time_t t);
std::string format_time_summary(const std::chrono::system_clock::time_point& t);
}

View File

@ -21,7 +21,6 @@
#include "serialization/string_utils.hpp"
#include <ctime>
#include <string_view>
class variable_set;

View File

@ -15,7 +15,6 @@
#pragma once
#include <ctime>
#include <vector>
#include <string>

View File

@ -552,16 +552,6 @@ int icompare(const std::string& s1, const std::string& s2)
#endif
}
std::string strftime(const std::string& format, const std::tm* time)
{
std::basic_ostringstream<char> dummy;
dummy.imbue(get_manager().get_locale()); // TODO: Calling imbue() with hard-coded locale appears to work with put_time in glibc, but not with get_locale()...
// Revert to use of boost (from 1.14) instead of std::put_time() because the latter does not appear to handle locale properly in Linux
dummy << bl::as::ftime(format) << mktime(const_cast<std::tm*>(time));
return dummy.str();
}
bool ci_search(const std::string& s1, const std::string& s2)
{
const std::locale& locale = get_manager().get_locale();

View File

@ -80,8 +80,6 @@ namespace translation
/** Case-insensitive lexicographical comparison. */
int icompare(const std::string& s1,const std::string& s2);
std::string strftime(const std::string& format, const std::tm* time);
/** Case-insensitive search. @a s2 will be checked against @a s1. */
bool ci_search(const std::string& s1, const std::string& s2);

View File

@ -21,7 +21,6 @@
#include "addon/manager.hpp"
#include "addon/state.hpp"
#include "help/help.hpp"
#include "gettext.hpp"
#include "gui/dialogs/addon/license_prompt.hpp"
@ -38,6 +37,7 @@
#include "gui/widgets/text_box.hpp"
#include "gui/widgets/window.hpp"
#include "preferences/preferences.hpp"
#include "serialization/chrono.hpp"
#include "serialization/string_utils.hpp"
#include "formula/string_utils.hpp"
#include "picture.hpp"
@ -1097,8 +1097,7 @@ static std::string format_addon_time(const std::chrono::system_clock::time_point
// Format reference: https://www.boost.org/doc/libs/1_85_0/doc/html/date_time/date_time_io.html#date_time.format_flags
: _("%B %d %Y, %H:%M");
auto as_time_t = std::chrono::system_clock::to_time_t(time);
return translation::strftime(format, std::localtime(&as_time_t));
return chrono::format_local_timestamp(time, format);
}
void addon_manager::on_addon_select()

View File

@ -15,7 +15,6 @@
#define GETTEXT_DOMAIN "wesnoth-lib"
#ifdef DEBUG_WINDOW_LAYOUT_GRAPHS
#include "gui/widgets/debug.hpp"
@ -26,6 +25,7 @@
#include "gui/widgets/listbox.hpp"
#include "gui/widgets/scrollbar_container.hpp"
#include "gui/widgets/window.hpp"
#include "serialization/chrono.hpp"
#include "serialization/string_utils.hpp"
#include <fstream>
@ -82,8 +82,8 @@ std::string get_base_filename()
{
std::ostringstream ss;
std::time_t t = std::time(nullptr);
ss << std::put_time(std::localtime(&t), "%Y%m%d_%H%M%S");
const auto now = std::chrono::system_clock::now();
ss << chrono::format_local_timestamp(now, "%Y%m%d_%H%M%S");
static unsigned counter = 0;
++counter;

View File

@ -30,7 +30,6 @@
#include <boost/algorithm/string.hpp>
#include <map>
#include <ctime>
#include <mutex>
#include <iostream>
#include <iomanip>
@ -133,11 +132,11 @@ void rotate_logs(const std::string& log_dir)
std::string unique_log_filename()
{
std::ostringstream o;
const std::time_t cur = std::time(nullptr);
const auto now = std::chrono::system_clock::now();
randomness::mt_rng rng;
o << lg::log_file_prefix
<< std::put_time(std::localtime(&cur), "%Y%m%d-%H%M%S-")
<< chrono::format_local_timestamp(now, "%Y%m%d-%H%M%S-")
<< rng.get_next_random();
return o.str();

View File

@ -56,7 +56,6 @@
#include <string>
#include <utility>
#include <chrono>
#include <ctime>
#include <cstdint>
#include "formatter.hpp"

View File

@ -23,7 +23,6 @@
#include "log.hpp"
#include "serialization/unicode.hpp"
#include <ctime>
#include <iomanip>
#include <iostream>

View File

@ -29,6 +29,7 @@
#include "pathfind/pathfind.hpp"
#include "picture.hpp"
#include "preferences/preferences.hpp"
#include "serialization/chrono.hpp"
#include "serialization/markup.hpp"
#include "team.hpp"
#include "terrain/movement.hpp"
@ -40,7 +41,6 @@
#include "whiteboard/manager.hpp"
#include <boost/format.hpp>
#include <ctime>
#include <iomanip>
#include <utility>
@ -1752,15 +1752,12 @@ REPORT_GENERATOR(report_clock, /*rc*/)
config report;
add_image(report, game_config::images::time_icon, "");
std::ostringstream ss;
const char* format = prefs::get().use_twelve_hour_clock_format()
? "%I:%M %p"
: "%H:%M";
std::time_t t = std::time(nullptr);
ss << std::put_time(std::localtime(&t), format);
add_text(report, ss.str(), _("Clock"));
const auto now = std::chrono::system_clock::now();
add_text(report, chrono::format_local_timestamp(now, format), _("Clock"));
return report;
}

View File

@ -22,6 +22,7 @@
#include "gettext.hpp"
#include "log.hpp"
#include "preferences/preferences.hpp"
#include "serialization/chrono.hpp"
#include "serialization/parser.hpp"
#include "team.hpp"
#include "utils/general.hpp"
@ -42,11 +43,11 @@ void extract_summary_from_config(config&, config&);
void save_index_class::rebuild(const std::string& name)
{
std::time_t modified = filesystem::file_modified_time(dir_ + "/" + name);
auto modified = filesystem::file_modified_time(dir_ + "/" + name);
rebuild(name, modified);
}
void save_index_class::rebuild(const std::string& name, const std::time_t& modified)
void save_index_class::rebuild(const std::string& name, const std::chrono::system_clock::time_point& modified)
{
log_scope("load_summary_from_file");
@ -62,7 +63,7 @@ void save_index_class::rebuild(const std::string& name, const std::time_t& modif
summary["corrupt"] = true;
}
summary["mod_time"] = std::to_string(static_cast<int>(modified));
summary["mod_time"] = chrono::serialize_timestamp(modified);
write_save_index();
}
@ -73,7 +74,7 @@ void save_index_class::remove(const std::string& name)
write_save_index();
}
void save_index_class::set_modified(const std::string& name, const std::time_t& modified)
void save_index_class::set_modified(const std::string& name, const std::chrono::system_clock::time_point& modified)
{
modified_[name] = modified;
}
@ -81,10 +82,10 @@ void save_index_class::set_modified(const std::string& name, const std::time_t&
config& save_index_class::get(const std::string& name)
{
config& result = data(name);
std::time_t m = modified_[name];
const auto& m = modified_[name];
config::attribute_value& mod_time = result["mod_time"];
if(mod_time.empty() || mod_time.to_time_t() != m) {
if(mod_time.empty() || chrono::parse_timestamp(mod_time) != m) {
rebuild(name, m);
}
@ -248,24 +249,20 @@ const config& save_info::summary() const
std::string save_info::format_time_local() const
{
if(std::tm* tm_l = std::localtime(&modified())) {
const std::string format = prefs::get().use_twelve_hour_clock_format()
// TRANSLATORS: Day of week + month + day of month + year + 12-hour time, eg 'Tue Nov 02 2021, 1:59 PM'. Format for your locale.
? _("%a %b %d %Y, %I:%M %p")
// TRANSLATORS: Day of week + month + day of month + year + 24-hour time, eg 'Tue Nov 02 2021, 13:59'. Format for your locale.
: _("%a %b %d %Y, %H:%M");
const std::string format = prefs::get().use_twelve_hour_clock_format()
// TRANSLATORS: Day of week + month + day of month + year + 12-hour time, eg 'Tue Nov 02 2021, 1:59 PM'.
// Format for your locale.
? _("%a %b %d %Y, %I:%M %p")
// TRANSLATORS: Day of week + month + day of month + year + 24-hour time, eg 'Tue Nov 02 2021, 13:59'.
// Format for your locale.
: _("%a %b %d %Y, %H:%M");
return translation::strftime(format, tm_l);
}
LOG_SAVE << "localtime() returned null for time " << this->modified() << ", save " << name();
return "";
return chrono::format_local_timestamp(modified(), format);
}
std::string save_info::format_time_summary() const
{
std::time_t t = modified();
return utils::format_time_summary(t);
return utils::format_time_summary(modified());
}
bool save_info_less_time::operator()(const save_info& a, const save_info& b) const
@ -392,7 +389,7 @@ create_save_info::create_save_info(const std::shared_ptr<save_index_class>& mana
save_info create_save_info::operator()(const std::string& filename) const
{
std::time_t modified = filesystem::file_modified_time(manager_->dir() + "/" + filename);
auto modified = filesystem::file_modified_time(manager_->dir() + "/" + filename);
manager_->set_modified(filename, modified);
return save_info(filename, manager_, modified);
}

View File

@ -17,6 +17,8 @@
#include "config.hpp"
#include <chrono>
namespace savegame
{
class save_index_class;
@ -27,7 +29,9 @@ class save_info
private:
friend class create_save_info;
save_info(const std::string& name, const std::shared_ptr<save_index_class>& index, const std::time_t& modified)
save_info(const std::string& name,
const std::shared_ptr<save_index_class>& index,
const std::chrono::system_clock::time_point& modified)
: name_(name)
, save_index_(index)
, modified_(modified)
@ -40,7 +44,7 @@ public:
return name_;
}
const std::time_t& modified() const
const auto& modified() const
{
return modified_;
}
@ -52,7 +56,7 @@ public:
private:
std::string name_;
std::shared_ptr<save_index_class> save_index_;
std::time_t modified_;
std::chrono::system_clock::time_point modified_;
};
/**
@ -95,11 +99,11 @@ public:
void delete_game(const std::string& name);
void rebuild(const std::string& name);
void rebuild(const std::string& name, const std::time_t& modified);
void rebuild(const std::string& name, const std::chrono::system_clock::time_point& modified);
/** Delete a savegame from the index, without deleting the underlying file. */
void remove(const std::string& name);
void set_modified(const std::string& name, const std::time_t& modified);
void set_modified(const std::string& name, const std::chrono::system_clock::time_point& modified);
config& get(const std::string& name);
const std::string& dir() const;
@ -128,7 +132,7 @@ private:
bool loaded_;
config data_;
std::map<std::string, std::time_t> modified_;
std::map<std::string, std::chrono::system_clock::time_point> modified_;
const std::string dir_;
/**
* The instance for default_saves_dir() writes a cache file. For other instances,

View File

@ -38,6 +38,7 @@
#include "save_index.hpp"
#include "saved_game.hpp"
#include "serialization/binary_or_text.hpp"
#include "serialization/chrono.hpp"
#include "serialization/utf8_exception.hpp"
#include "utils/optimer.hpp"
#include "video.hpp" // only for faked
@ -572,10 +573,7 @@ replay_savegame::replay_savegame(saved_game& gamestate, const compression::forma
std::string replay_savegame::create_initial_filename(unsigned int) const
{
time_t t = std::time(nullptr);
tm tm = *std::localtime(&t);
auto time = std::put_time(&tm, "%Y%m%d-%H%M%S");
auto time = chrono::format_local_timestamp(std::chrono::system_clock::now(), "%Y%m%d-%H%M%S");
// TRANSLATORS: This string is used as part of a filename, as in, "HttT-The Elves Besieged replay.gz"
return formatter() << gamestate().classification().label << " " << _("replay") << " " << time;
}

View File

@ -48,7 +48,6 @@
#endif
#include <csignal>
#include <ctime>
#include <iomanip>
#include <iostream>
#include <utility>

View File

@ -333,9 +333,6 @@ std::pair<bool, utils::optional<std::chrono::system_clock::time_point>> ban_mana
const std::string& duration, std::chrono::system_clock::time_point start_time) const
{
if(duration.substr(0, 4) == "TIME") {
auto as_time_t = std::chrono::system_clock::to_time_t(start_time);
std::tm* loc = std::localtime(&as_time_t);
std::size_t number = 0;
for(auto i = duration.begin() + 4; i != duration.end(); ++i) {
if(is_digit(*i)) {
@ -343,22 +340,22 @@ std::pair<bool, utils::optional<std::chrono::system_clock::time_point>> ban_mana
} else {
switch(*i) {
case 'Y':
loc->tm_year = number;
start_time += chrono::years{number};
break;
case 'M':
loc->tm_mon = number;
start_time += chrono::months{number};
break;
case 'D':
loc->tm_mday = number;
start_time += chrono::days{number};
break;
case 'h':
loc->tm_hour = number;
start_time += std::chrono::hours{number};
break;
case 'm':
loc->tm_min = number;
start_time += std::chrono::minutes{number};
break;
case 's':
loc->tm_sec = number;
start_time += std::chrono::seconds{number};
break;
default:
LOG_SERVER << "Invalid time modifier given: '" << *i << "'.";
@ -367,7 +364,7 @@ std::pair<bool, utils::optional<std::chrono::system_clock::time_point>> ban_mana
number = 0;
}
}
return { true, std::chrono::system_clock::from_time_t(std::mktime(loc)) };
return { true, start_time };
}
std::string dur_lower;

View File

@ -17,7 +17,6 @@
#include <boost/test/unit_test.hpp>
#include <array>
#include <ctime>
#include "formula/formula.hpp"
#include "formula/callable.hpp"

View File

@ -15,8 +15,6 @@
#pragma once
#include <ctime>
namespace n_unit {
struct unit_id

View File

@ -43,6 +43,7 @@
#include "scripting/plugins/manager.hpp"
#include "sdl/exception.hpp" // for exception
#include "serialization/binary_or_text.hpp" // for config_writer
#include "serialization/chrono.hpp"
#include "serialization/parser.hpp" // for read
#include "serialization/preprocessor.hpp" // for preproc_define, etc
#include "serialization/schema_validator.hpp" // for strict_validation_enabled and schema_validator
@ -77,7 +78,6 @@
#include <clocale> // for setlocale, LC_ALL, etc
#include <cstdio> // for remove, fprintf, stderr
#include <cstdlib> // for srand, exit
#include <ctime> // for time, ctime, std::time_t
#include <exception> // for exception
#include <vector>
#include <iostream>
@ -421,9 +421,9 @@ static int process_command_args(commandline_options& cmdline_opts)
}
if(!cmdline_opts.nobanner) {
const auto now = std::chrono::system_clock::now();
PLAIN_LOG << "Battle for Wesnoth v" << game_config::revision << " " << game_config::build_arch();
const std::time_t t = std::time(nullptr);
PLAIN_LOG << "Started on " << ctime(&t);
PLAIN_LOG << "Started on " << chrono::format_local_timestamp(now, "%a %b %d %T %Y") << '\n';
}
if(cmdline_opts.usercache_path) {