diff --git a/include/textproc.h b/include/textproc.h index 12f28be01..d536a5511 100644 --- a/include/textproc.h +++ b/include/textproc.h @@ -79,6 +79,12 @@ namespace Anope */ extern CoreExport Anope::string FormatCTCP(const Anope::string &name, const Anope::string &body = ""); + /** Formats a date/time as an IS0 8601 timestamp. + * @param ts UNIX timestamp to format. + * @param ms Number of milliseconds to format. + */ + extern CoreExport Anope::string FormatISO8601(time_t ts, unsigned long long ms); + /** Parses a CTCP message received from a client. * @param text The raw message to parse. * @param name The location to store the name of the CTCP. diff --git a/modules/chanserv/cs_entrymsg.cpp b/modules/chanserv/cs_entrymsg.cpp index 72e6799e9..da9d4839f 100644 --- a/modules/chanserv/cs_entrymsg.cpp +++ b/modules/chanserv/cs_entrymsg.cpp @@ -299,11 +299,7 @@ public: { Anope::map tags; if (timestamp) - { - char timebuf[32]; - strftime(timebuf, sizeof(timebuf), "%Y-%m-%dT%H:%M:%S.000Z", gmtime(&message->when)); - tags["time"] = timebuf; - } + tags["time"] = Anope::FormatISO8601(message->when, 0); if (u->ShouldPrivmsg()) IRCD->SendContextPrivmsg(c->ci->WhoSends(), u, c, message->message, tags); diff --git a/src/misc.cpp b/src/misc.cpp index 175282ed2..66831df3b 100644 --- a/src/misc.cpp +++ b/src/misc.cpp @@ -1178,6 +1178,24 @@ Anope::string Anope::FormatCTCP(const Anope::string &name, const Anope::string & return Anope::Format("\1%s %s\1", name.c_str(), value.c_str()); } +Anope::string Anope::FormatISO8601(time_t ts, unsigned long long ms) +{ + static time_t last_ts = -1; + static unsigned long long last_ms = -1; + static Anope::string timestamp; + if (ts != last_ts || ms != last_ms) + { + last_ts = ts; + last_ms = ms; + char timebuf[32]; + const auto *tm = gmtime(&ts); + strftime(timebuf, sizeof(timebuf), "%Y-%m-%dT%H:%M:%S", tm); + timestamp = Anope::Format("%s.%03lldZ", timebuf, ms); + } + return timestamp; +} + + bool Anope::ParseCTCP(const Anope::string &text, Anope::string &name, Anope::string &body) { // According to draft-oakley-irc-ctcp-02 a valid CTCP must begin with SOH and