From f1f611e500b2f76953c27c1af731aa8a59e33600 Mon Sep 17 00:00:00 2001
From: TiviPlus <57223640+TiviPlus@users.noreply.github.com>
Date: Tue, 1 Apr 2025 22:08:15 +0200
Subject: [PATCH] =?UTF-8?q?Force=20UTC=C2=B10=20for=20time2text=20logging?=
=?UTF-8?q?=20and=20IC=20times=20(#90347)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
## About The Pull Request
This won't actually do anything on live, since those are all set to
UTC±0 currently
Pins logging and IC uses of time2text to UTC±0 instead of using the
system timezone (byond default)
Timezones not being set to utc0 caused issues before (and is again)
All timezones are now passed explicitly to make it more likely it's
cargo culted properly at least
Deletes worldtime2text cus it was gameTimestamp default args
## Why It's Good For The Game
Server timezone changes probably shouldn't affect logging, round times,
file hashes, IC time, when you caught fish, etc
## Changelog
:cl:
refactor: Logging and IC timestamps will now always use UTC±0 and not be
affected by server system timezone changes
fix: Station and round times will not longer be incorrect if the system
timezone is not UTC±0
/:cl:
---------
Co-authored-by: TiviPlus <572233640+TiviPlus@users.noreply.com>
---
code/__DEFINES/time.dm | 5 ++++-
code/__HELPERS/time.dm | 18 +++++++++---------
code/__HELPERS/type2type.dm | 1 -
code/_globalvars/time_vars.dm | 2 +-
code/controllers/master.dm | 2 +-
code/controllers/subsystem/dynamic/dynamic.dm | 12 ++++++------
.../subsystem/dynamic/dynamic_rulesets.dm | 2 +-
.../dynamic/dynamic_rulesets_roundstart.dm | 2 +-
.../subsystem/dynamic/ruleset_picking.dm | 2 +-
code/controllers/subsystem/events.dm | 8 ++++----
.../subsystem/persistent_paintings.dm | 2 +-
code/controllers/subsystem/statpanel.dm | 2 +-
code/datums/json_savefile.dm | 2 +-
code/datums/memory/_memory.dm | 4 ++--
code/game/machinery/civilian_bounties.dm | 4 ++--
.../objects/items/AI_modules/_AI_modules.dm | 2 +-
code/game/objects/items/devices/table_clock.dm | 2 +-
.../game/objects/items/devices/taperecorder.dm | 2 +-
.../structures/signs/signs_interactive.dm | 4 ++--
code/game/world.dm | 9 ++++-----
code/modules/admin/verbs/map_export.dm | 2 +-
.../antagonists/heretic/heretic_knowledge.dm | 6 +++---
code/modules/art/paintings.dm | 2 +-
code/modules/assembly/signaler.dm | 2 +-
code/modules/buildmode/submodes/map_export.dm | 2 +-
code/modules/detectivework/scanner.dm | 3 ---
code/modules/events/_event.dm | 2 +-
code/modules/fishing/fish_mount.dm | 2 +-
code/modules/holiday/holidays.dm | 6 +++---
code/modules/logging/log_holder.dm | 2 +-
code/modules/lost_crew/damages/_damages.dm | 4 ++--
.../mob/living/silicon/robot/robot_defense.dm | 2 +-
.../computers/item/computer.dm | 2 +-
.../file_system/programs/signalcommander.dm | 2 +-
code/modules/paperwork/paper.dm | 4 ++--
code/modules/transport/tram/tram_controller.dm | 2 +-
.../modules/wiremod/components/action/radio.dm | 2 +-
37 files changed, 66 insertions(+), 68 deletions(-)
diff --git a/code/__DEFINES/time.dm b/code/__DEFINES/time.dm
index 5edba8746f8..ad87ba9229c 100644
--- a/code/__DEFINES/time.dm
+++ b/code/__DEFINES/time.dm
@@ -2,7 +2,7 @@
#define MIDNIGHT_ROLLOVER 864000
///displays the current time into the round, with a lot of extra code just there for ensuring it looks okay after an entire day passes
-#define ROUND_TIME(...) ( "[world.time - SSticker.round_start_time > MIDNIGHT_ROLLOVER ? "[round((world.time - SSticker.round_start_time)/MIDNIGHT_ROLLOVER)]:[worldtime2text()]" : worldtime2text()]" )
+#define ROUND_TIME(...) ( "[world.time - SSticker.round_start_time > MIDNIGHT_ROLLOVER ? "[round((world.time - SSticker.round_start_time)/MIDNIGHT_ROLLOVER)]:[gameTimestamp()]" : gameTimestamp()]" )
///Returns the time that has passed since the game started
#define STATION_TIME_PASSED(...) (world.time - SSticker.round_start_time)
@@ -174,3 +174,6 @@ When using time2text(), please use "DDD" to find the weekday. Refrain from using
/// Anywhere on Earth
#define TIMEZONE_ANYWHERE_ON_EARTH -12
+
+/// in the grim darkness of the thirteenth space station there is no timezones, since they break IC game times. Use this for all IC/round time values
+#define NO_TIMEZONE 0
diff --git a/code/__HELPERS/time.dm b/code/__HELPERS/time.dm
index 5d39ff47177..49de184a915 100644
--- a/code/__HELPERS/time.dm
+++ b/code/__HELPERS/time.dm
@@ -1,19 +1,19 @@
-//Returns the world time in english
-/proc/worldtime2text()
- return gameTimestamp("hh:mm:ss", world.time)
-
+/// Returns UTC timestamp with the specifified format and optionally deciseconds
/proc/time_stamp(format = "hh:mm:ss", show_ds)
- var/time_string = time2text(world.timeofday, format)
+ var/time_string = time2text(world.timeofday, format, TIMEZONE_UTC)
return show_ds ? "[time_string]:[world.timeofday % 10]" : time_string
+/// Returns timestamp since the server started, for use with world.time
/proc/gameTimestamp(format = "hh:mm:ss", wtime=world.time)
- return time2text(wtime, format)
+ return time2text(wtime, format, NO_TIMEZONE)
+///returns the current IC station time in a world.time format
/proc/station_time(display_only = FALSE, wtime=world.time)
return ((((wtime - SSticker.round_start_time) * SSticker.station_time_rate_multiplier) + SSticker.gametime_offset) % 864000) - (display_only? GLOB.timezoneOffset : 0)
+///returns the current IC station time in a human readable format
/proc/station_time_timestamp(format = "hh:mm:ss", wtime)
- return time2text(station_time(TRUE, wtime), format)
+ return time2text(station_time(TRUE, wtime), format, NO_TIMEZONE)
/proc/station_time_debug(force_set)
if(isnum(force_set))
@@ -25,9 +25,9 @@
else
SSticker.gametime_offset = CEILING(SSticker.gametime_offset, 3600)
-//returns timestamp in a sql and a not-quite-compliant ISO 8601 friendly format
+///returns timestamp in a sql and a not-quite-compliant ISO 8601 friendly format. Do not use for SQL, use NOW() instead
/proc/ISOtime(timevar)
- return time2text(timevar || world.timeofday, "YYYY-MM-DD hh:mm:ss")
+ return time2text(timevar || world.timeofday, "YYYY-MM-DD hh:mm:ss", world.timezone)
GLOBAL_VAR_INIT(midnight_rollovers, 0)
diff --git a/code/__HELPERS/type2type.dm b/code/__HELPERS/type2type.dm
index aae96c38601..c7b7cdd4bc1 100644
--- a/code/__HELPERS/type2type.dm
+++ b/code/__HELPERS/type2type.dm
@@ -4,7 +4,6 @@
* file2list
* angle2dir
* angle2text
- * worldtime2text
* text2dir_extended & dir2text_short
*/
diff --git a/code/_globalvars/time_vars.dm b/code/_globalvars/time_vars.dm
index cc830721145..29526f845b2 100644
--- a/code/_globalvars/time_vars.dm
+++ b/code/_globalvars/time_vars.dm
@@ -2,5 +2,5 @@
/// The difference betwen midnight (of the host computer) and 0 world.ticks.
GLOBAL_VAR_INIT(timezoneOffset, 0)
-GLOBAL_VAR_INIT(year, time2text(world.realtime,"YYYY"))
+GLOBAL_VAR_INIT(year, time2text(world.realtime, "YYYY", NO_TIMEZONE))
GLOBAL_VAR_INIT(year_integer, text2num(year)) // = 2013???
diff --git a/code/controllers/master.dm b/code/controllers/master.dm
index 92ca73f4268..d48cd14f311 100644
--- a/code/controllers/master.dm
+++ b/code/controllers/master.dm
@@ -268,7 +268,7 @@ ADMIN_VERB(cmd_controller_view_ui, R_SERVER|R_DEBUG, "Controller Overview", "Vie
/datum/controller/master/Recover()
- var/msg = "## DEBUG: [time2text(world.timeofday)] MC restarted. Reports:\n"
+ var/msg = "## DEBUG: [time2text(world.timeofday, "DDD MMM DD hh:mm:ss YYYY", TIMEZONE_UTC)] MC restarted. Reports:\n"
var/list/master_attributes = Master.vars
var/list/filtered_variables = list(
NAMEOF(src, name),
diff --git a/code/controllers/subsystem/dynamic/dynamic.dm b/code/controllers/subsystem/dynamic/dynamic.dm
index d6d99e318d1..65ffc205b56 100644
--- a/code/controllers/subsystem/dynamic/dynamic.dm
+++ b/code/controllers/subsystem/dynamic/dynamic.dm
@@ -247,9 +247,9 @@ SUBSYSTEM_DEF(dynamic)
if(!threatadd)
return
if(threatadd > 0)
- create_threat(threatadd, threat_log, "[worldtime2text()]: increased by [key_name(usr)]")
+ create_threat(threatadd, threat_log, "[gameTimestamp()]: increased by [key_name(usr)]")
else
- spend_midround_budget(-threatadd, threat_log, "[worldtime2text()]: decreased by [key_name(usr)]")
+ spend_midround_budget(-threatadd, threat_log, "[gameTimestamp()]: decreased by [key_name(usr)]")
else if (href_list["injectlate"])
latejoin_injection_cooldown = 0
late_forced_injection = TRUE
@@ -317,7 +317,7 @@ SUBSYSTEM_DEF(dynamic)
addtimer(CALLBACK(src, PROC_REF(send_intercept)), 10 SECONDS)
return
- . = "Nanotrasen Department of Intelligence Threat Advisory, Spinward Sector, TCD [time2text(world.realtime, "DDD, MMM DD")], [CURRENT_STATION_YEAR]:
"
+ . = "Nanotrasen Department of Intelligence Threat Advisory, Spinward Sector, TCD [time2text(world.realtime, "DDD, MMM DD", NO_TIMEZONE)], [CURRENT_STATION_YEAR]:
"
. += generate_advisory_level()
var/min_threat = 100
@@ -512,7 +512,7 @@ SUBSYSTEM_DEF(dynamic)
roundstart(roundstart_rules)
log_dynamic("[round_start_budget] round start budget was left, donating it to midrounds.")
- threat_log += "[worldtime2text()]: [round_start_budget] round start budget was left, donating it to midrounds."
+ threat_log += "[gameTimestamp()]: [round_start_budget] round start budget was left, donating it to midrounds."
mid_round_budget += round_start_budget
var/starting_rulesets = ""
@@ -719,7 +719,7 @@ SUBSYSTEM_DEF(dynamic)
var/added_threat = ruleset.scale_up(roundstart_pop_ready, scaled_times)
if(ruleset.pre_execute(roundstart_pop_ready))
- threat_log += "[worldtime2text()]: Roundstart [ruleset.name] spent [ruleset.cost + added_threat]. [ruleset.scaling_cost ? "Scaled up [ruleset.scaled_times]/[scaled_times] times." : ""]"
+ threat_log += "[gameTimestamp()]: Roundstart [ruleset.name] spent [ruleset.cost + added_threat]. [ruleset.scaling_cost ? "Scaled up [ruleset.scaled_times]/[scaled_times] times." : ""]"
if(ruleset.flags & ONLY_RULESET)
only_ruleset_executed = TRUE
if(ruleset.flags & HIGH_IMPACT_RULESET)
@@ -777,7 +777,7 @@ SUBSYSTEM_DEF(dynamic)
new_rule.load_templates()
if (new_rule.ready(forced))
if (!ignore_cost)
- spend_midround_budget(new_rule.cost, threat_log, "[worldtime2text()]: Forced rule [new_rule.name]")
+ spend_midround_budget(new_rule.cost, threat_log, "[gameTimestamp()]: Forced rule [new_rule.name]")
new_rule.pre_execute(population)
if (new_rule.execute()) // This should never fail since ready() returned 1
if(new_rule.flags & HIGH_IMPACT_RULESET)
diff --git a/code/controllers/subsystem/dynamic/dynamic_rulesets.dm b/code/controllers/subsystem/dynamic/dynamic_rulesets.dm
index 17939cf426a..1eca2aeaff3 100644
--- a/code/controllers/subsystem/dynamic/dynamic_rulesets.dm
+++ b/code/controllers/subsystem/dynamic/dynamic_rulesets.dm
@@ -218,7 +218,7 @@
/// This one only handles refunding the threat, override in ruleset to clean up the rest.
/datum/dynamic_ruleset/proc/clean_up()
SSdynamic.refund_threat(cost + (scaled_times * scaling_cost))
- SSdynamic.threat_log += "[worldtime2text()]: [ruletype] [name] refunded [cost + (scaled_times * scaling_cost)]. Failed to execute."
+ SSdynamic.threat_log += "[gameTimestamp()]: [ruletype] [name] refunded [cost + (scaled_times * scaling_cost)]. Failed to execute."
/// Gets weight of the ruleset
/// Note that this decreases weight if repeatable is TRUE and repeatable_weight_decrease is higher than 0
diff --git a/code/controllers/subsystem/dynamic/dynamic_rulesets_roundstart.dm b/code/controllers/subsystem/dynamic/dynamic_rulesets_roundstart.dm
index 324ae14f3a1..b0a56cccad0 100644
--- a/code/controllers/subsystem/dynamic/dynamic_rulesets_roundstart.dm
+++ b/code/controllers/subsystem/dynamic/dynamic_rulesets_roundstart.dm
@@ -607,7 +607,7 @@ GLOBAL_VAR_INIT(revolutionary_win, FALSE)
log_game("Starting a round of extended.")
SSdynamic.spend_roundstart_budget(SSdynamic.round_start_budget)
SSdynamic.spend_midround_budget(SSdynamic.mid_round_budget)
- SSdynamic.threat_log += "[worldtime2text()]: Extended ruleset set threat to 0."
+ SSdynamic.threat_log += "[gameTimestamp()]: Extended ruleset set threat to 0."
return TRUE
//////////////////////////////////////////////
diff --git a/code/controllers/subsystem/dynamic/ruleset_picking.dm b/code/controllers/subsystem/dynamic/ruleset_picking.dm
index f01250069e4..baeceada57c 100644
--- a/code/controllers/subsystem/dynamic/ruleset_picking.dm
+++ b/code/controllers/subsystem/dynamic/ruleset_picking.dm
@@ -105,7 +105,7 @@
/// Mainly here to facilitate delayed rulesets. All midround/latejoin rulesets are executed with a timered callback to this proc.
/datum/controller/subsystem/dynamic/proc/execute_midround_latejoin_rule(sent_rule)
var/datum/dynamic_ruleset/rule = sent_rule
- spend_midround_budget(rule.cost, threat_log, "[worldtime2text()]: [rule.ruletype] [rule.name]")
+ spend_midround_budget(rule.cost, threat_log, "[gameTimestamp()]: [rule.ruletype] [rule.name]")
rule.pre_execute(GLOB.alive_player_list.len)
if (rule.execute())
log_dynamic("Injected a [rule.ruletype] ruleset [rule.name].")
diff --git a/code/controllers/subsystem/events.dm b/code/controllers/subsystem/events.dm
index f4b8c8138b8..ff6b23da6ef 100644
--- a/code/controllers/subsystem/events.dm
+++ b/code/controllers/subsystem/events.dm
@@ -165,10 +165,10 @@ GLOBAL_LIST(holidays)
for(var/timezone in holiday.timezones)
var/time_in_timezone = world.realtime + timezone HOURS
- var/YYYY = text2num(time2text(time_in_timezone, "YYYY")) // get the current year
- var/MM = text2num(time2text(time_in_timezone, "MM")) // get the current month
- var/DD = text2num(time2text(time_in_timezone, "DD")) // get the current day
- var/DDD = time2text(time_in_timezone, "DDD") // get the current weekday
+ var/YYYY = text2num(time2text(time_in_timezone, "YYYY", world.timezone)) // get the current year
+ var/MM = text2num(time2text(time_in_timezone, "MM", world.timezone)) // get the current month
+ var/DD = text2num(time2text(time_in_timezone, "DD", world.timezone)) // get the current day
+ var/DDD = time2text(time_in_timezone, "DDD", world.timezone) // get the current weekday
if(holiday.shouldCelebrate(DD, MM, YYYY, DDD))
holiday.celebrate()
diff --git a/code/controllers/subsystem/persistent_paintings.dm b/code/controllers/subsystem/persistent_paintings.dm
index 7da30fd4772..b2f0921df6d 100644
--- a/code/controllers/subsystem/persistent_paintings.dm
+++ b/code/controllers/subsystem/persistent_paintings.dm
@@ -245,7 +245,7 @@ SUBSYSTEM_DEF(persistent_paintings)
new_data["title"] = old_data["title"] || "Untitled Artwork"
new_data["creator_ckey"] = old_data["ckey"] || ""
new_data["creator_name"] = "Anonymous"
- new_data["creation_date"] = time2text(world.realtime) // Could use creation/modified file helpers in rustg
+ new_data["creation_date"] = time2text(world.realtime, "DDD MMM DD hh:mm:ss YYYY", TIMEZONE_UTC) // Could use creation/modified file helpers in rustg
new_data["creation_round_id"] = GLOB.round_id
new_data["tags"] = list(category,"Migrated from version 0")
new_data["patron_ckey"] = ""
diff --git a/code/controllers/subsystem/statpanel.dm b/code/controllers/subsystem/statpanel.dm
index a9736751c47..9f0f2077a2f 100644
--- a/code/controllers/subsystem/statpanel.dm
+++ b/code/controllers/subsystem/statpanel.dm
@@ -28,7 +28,7 @@ SUBSYSTEM_DEF(statpanels)
"Map: [SSmapping.current_map?.map_name || "Loading..."]",
cached ? "Next Map: [cached.map_name]" : null,
"Round ID: [GLOB.round_id ? GLOB.round_id : "NULL"]",
- "Server Time: [time2text(world.timeofday, "YYYY-MM-DD hh:mm:ss")]",
+ "Server Time: [time2text(world.timeofday, "YYYY-MM-DD hh:mm:ss", world.timezone)]",
"Round Time: [ROUND_TIME()]",
"Station Time: [station_time_timestamp()]",
"Time Dilation: [round(SStime_track.time_dilation_current,1)]% AVG:([round(SStime_track.time_dilation_avg_fast,1)]%, [round(SStime_track.time_dilation_avg,1)]%, [round(SStime_track.time_dilation_avg_slow,1)]%)"
diff --git a/code/datums/json_savefile.dm b/code/datums/json_savefile.dm
index dd2a6af0b98..f68efd432d1 100644
--- a/code/datums/json_savefile.dm
+++ b/code/datums/json_savefile.dm
@@ -95,7 +95,7 @@ GENERAL_PROTECT_DATUM(/datum/json_savefile)
return
COOLDOWN_START(src, download_cooldown, (CONFIG_GET(number/seconds_cooldown_for_preferences_export) * (1 SECONDS)))
- var/file_name = "[account_name ? "[account_name]_" : ""]preferences_[time2text(world.timeofday, "MMM_DD_YYYY_hh-mm-ss")].json"
+ var/file_name = "[account_name ? "[account_name]_" : ""]preferences_[time2text(world.timeofday, "MMM_DD_YYYY_hh-mm-ss", TIMEZONE_UTC)].json"
var/temporary_file_storage = "data/preferences_export_working_directory/[file_name]"
if(!text2file(json_encode(tree, JSON_PRETTY_PRINT), temporary_file_storage))
diff --git a/code/datums/memory/_memory.dm b/code/datums/memory/_memory.dm
index 08a694616a3..fe5546ea330 100644
--- a/code/datums/memory/_memory.dm
+++ b/code/datums/memory/_memory.dm
@@ -358,9 +358,9 @@
//after replacement section for performance
if(story_flags & STORY_FLAG_DATED)
if(memory_flags & MEMORY_FLAG_NOSTATIONNAME)
- parsed_story += "This took place in [time2text(world.realtime, "Month")] of [CURRENT_STATION_YEAR]."
+ parsed_story += "This took place in [time2text(world.realtime, "Month", NO_TIMEZONE)] of [CURRENT_STATION_YEAR]."
else
- parsed_story += "This took place in [time2text(world.realtime, "Month")] of [CURRENT_STATION_YEAR] on [station_name()]."
+ parsed_story += "This took place in [time2text(world.realtime, "Month", NO_TIMEZONE)] of [CURRENT_STATION_YEAR] on [station_name()]."
parsed_story = trim_right(parsed_story)
diff --git a/code/game/machinery/civilian_bounties.dm b/code/game/machinery/civilian_bounties.dm
index 5024a588e23..839151e7025 100644
--- a/code/game/machinery/civilian_bounties.dm
+++ b/code/game/machinery/civilian_bounties.dm
@@ -317,7 +317,7 @@
/obj/item/bounty_cube/examine()
. = ..()
if(speed_bonus)
- . += span_notice("[time2text(next_nag_time - world.time,"mm:ss")] remains until [bounty_value * speed_bonus] credit speedy delivery bonus lost.")
+ . += span_notice("[time2text(next_nag_time - world.time,"mm:ss", NO_TIMEZONE)] remains until [bounty_value * speed_bonus] credit speedy delivery bonus lost.")
if(handler_tip && !bounty_handler_account)
. += span_notice("Scan this in the cargo shuttle with an export scanner to register your bank account for the [bounty_value * handler_tip] credit handling tip.")
@@ -363,7 +363,7 @@
"LOCATION" = get_area_name(src),
"PERSON" = bounty_holder,
"RANK" = bounty_holder_job,
- "BONUSTIME" = time2text(next_nag_time - world.time,"mm:ss"),
+ "BONUSTIME" = time2text(next_nag_time - world.time,"mm:ss", NO_TIMEZONE),
"COST" = bounty_value
), src, list(RADIO_CHANNEL_SUPPLY))
diff --git a/code/game/objects/items/AI_modules/_AI_modules.dm b/code/game/objects/items/AI_modules/_AI_modules.dm
index cf689584805..be1d5a311cf 100644
--- a/code/game/objects/items/AI_modules/_AI_modules.dm
+++ b/code/game/objects/items/AI_modules/_AI_modules.dm
@@ -89,7 +89,7 @@
else
to_chat(user, span_notice("Upload complete."))
- var/time = time2text(world.realtime,"hh:mm:ss")
+ var/time = time2text(world.realtime,"hh:mm:ss", TIMEZONE_UTC)
var/ainame = law_datum.owner ? law_datum.owner.name : "empty AI core"
var/aikey = law_datum.owner ? law_datum.owner.ckey : "null"
diff --git a/code/game/objects/items/devices/table_clock.dm b/code/game/objects/items/devices/table_clock.dm
index 8f35a60b0e4..329b38bcc92 100644
--- a/code/game/objects/items/devices/table_clock.dm
+++ b/code/game/objects/items/devices/table_clock.dm
@@ -31,7 +31,7 @@
. += span_info("It appears to be currently broken. You can use it in-hand to repair it.")
else
. += span_info("The current CST (local) time is: [station_time_timestamp()].")
- . += span_info("The current TCT (galactic) time is: [time2text(world.realtime, "hh:mm:ss")].")
+ . += span_info("The current TCT (galactic) time is: [time2text(world.realtime, "hh:mm:ss", NO_TIMEZONE)].")
/obj/item/table_clock/attackby(obj/item/attacking_item, mob/user, params)
. = ..()
diff --git a/code/game/objects/items/devices/taperecorder.dm b/code/game/objects/items/devices/taperecorder.dm
index d624288703e..79748bec7f2 100644
--- a/code/game/objects/items/devices/taperecorder.dm
+++ b/code/game/objects/items/devices/taperecorder.dm
@@ -159,7 +159,7 @@
return
mytape.timestamp += mytape.used_capacity
- mytape.storedinfo += "\[[time2text(mytape.used_capacity,"mm:ss")]\] [speaker.GetVoice()]: [raw_message]"
+ mytape.storedinfo += "\[[time2text(mytape.used_capacity,"mm:ss", NO_TIMEZONE)]\] [speaker.GetVoice()]: [raw_message]"
/obj/item/taperecorder/verb/record()
diff --git a/code/game/objects/structures/signs/signs_interactive.dm b/code/game/objects/structures/signs/signs_interactive.dm
index 1e407034f4a..5ef9031fef9 100644
--- a/code/game/objects/structures/signs/signs_interactive.dm
+++ b/code/game/objects/structures/signs/signs_interactive.dm
@@ -8,7 +8,7 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/structure/sign/clock, 32)
/obj/structure/sign/clock/examine(mob/user)
. = ..()
. += span_info("The current CST (local) time is: [station_time_timestamp()].")
- . += span_info("The current TCT (galactic) time is: [time2text(world.realtime, "hh:mm:ss")].")
+ . += span_info("The current TCT (galactic) time is: [time2text(world.realtime, "hh:mm:ss", 0)].")
/obj/structure/sign/calendar
name = "wall calendar"
@@ -19,7 +19,7 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/structure/sign/calendar, 32)
/obj/structure/sign/calendar/examine(mob/user)
. = ..()
- . += span_info("The current date is: [time2text(world.realtime, "DDD, MMM DD")], [CURRENT_STATION_YEAR].")
+ . += span_info("The current date is: [time2text(world.realtime, "DDD, MMM DD", world.timezone)], [CURRENT_STATION_YEAR].")
if(length(GLOB.holidays))
. += span_info("Events:")
for(var/holidayname in GLOB.holidays)
diff --git a/code/game/world.dm b/code/game/world.dm
index 2485481fd79..b3b1e90a827 100644
--- a/code/game/world.dm
+++ b/code/game/world.dm
@@ -223,10 +223,10 @@ GLOBAL_PROTECT(tracy_init_reason)
var/override_dir = params[OVERRIDE_LOG_DIRECTORY_PARAMETER]
if(!override_dir)
var/realtime = world.realtime
- var/texttime = time2text(realtime, "YYYY/MM/DD")
+ var/texttime = time2text(realtime, "YYYY/MM/DD", TIMEZONE_UTC)
GLOB.log_directory = "data/logs/[texttime]/round-"
GLOB.public_log_directory = "data/public/logs/[texttime]/round-" // BUBBER EDIT ADDITION
- GLOB.picture_logging_prefix = "L_[time2text(realtime, "YYYYMMDD")]_"
+ GLOB.picture_logging_prefix = "L_[time2text(realtime, "YYYYMMDD", TIMEZONE_UTC)]_"
GLOB.picture_log_directory = "data/picture_logs/[texttime]/round-"
if(GLOB.round_id)
GLOB.log_directory += "[GLOB.round_id]"
@@ -252,8 +252,7 @@ GLOBAL_PROTECT(tracy_init_reason)
if(!fexists(GLOB.master_public_log_file)) // BUBBER EDIT ADDITION
rustg_file_write("Starting up round ID [GLOB.round_id].\n --------------------------\n", GLOB.master_public_log_file) // BUBBER EDIT ADDITION
-
- var/latest_changelog = file("[global.config.directory]/../html/changelogs/archive/" + time2text(world.timeofday, "YYYY-MM") + ".yml")
+ var/latest_changelog = file("[global.config.directory]/../html/changelogs/archive/" + time2text(world.timeofday, "YYYY-MM", TIMEZONE_UTC) + ".yml")
GLOB.changelog_hash = fexists(latest_changelog) ? md5(latest_changelog) : 0 //for telling if the changelog has changed recently
if(GLOB.round_id)
@@ -427,7 +426,7 @@ GLOBAL_PROTECT(tracy_init_reason)
else if(SSticker.current_state == GAME_STATE_SETTING_UP)
new_status += "
Starting: Now"
else if(SSticker.IsRoundInProgress())
- new_status += "
Time: [time2text(STATION_TIME_PASSED(), "hh:mm", 0)]"
+ new_status += "
Time: [time2text(STATION_TIME_PASSED(), "hh:mm", NO_TIMEZONE)]"
if(SSshuttle?.emergency && SSshuttle?.emergency?.mode != (SHUTTLE_IDLE || SHUTTLE_ENDGAME))
new_status += " | Shuttle: [SSshuttle.emergency.getModeStr()] [SSshuttle.emergency.getTimerStr()]"
else if(SSticker.current_state == GAME_STATE_FINISHED)
diff --git a/code/modules/admin/verbs/map_export.dm b/code/modules/admin/verbs/map_export.dm
index 056a2ea1f8a..057a8476892 100644
--- a/code/modules/admin/verbs/map_export.dm
+++ b/code/modules/admin/verbs/map_export.dm
@@ -7,7 +7,7 @@ ADMIN_VERB(map_export, R_DEBUG, "Map Export", "Select a part of the map by coord
var/start_y = tgui_input_number(user, "Start Y?", "Map Exporter", user_y || 1, world.maxy, 1)
var/end_x = tgui_input_number(user, "End X?", "Map Exporter", user_x || 1, world.maxx, 1)
var/end_y = tgui_input_number(user, "End Y?", "Map Exporter", user_y || 1, world.maxy, 1)
- var/date = time2text(world.timeofday, "YYYY-MM-DD_hh-mm-ss")
+ var/date = time2text(world.timeofday, "YYYY-MM-DD_hh-mm-ss", TIMEZONE_UTC)
var/file_name = sanitize_filename(tgui_input_text(user, "Filename?", "Map Exporter", "exported_map_[date]"))
var/confirm = tgui_alert(user, "Are you sure you want to do this? This will cause extreme lag!", "Map Exporter", list("Yes", "No"))
diff --git a/code/modules/antagonists/heretic/heretic_knowledge.dm b/code/modules/antagonists/heretic/heretic_knowledge.dm
index 30d12425e11..16b1ac1f95e 100644
--- a/code/modules/antagonists/heretic/heretic_knowledge.dm
+++ b/code/modules/antagonists/heretic/heretic_knowledge.dm
@@ -529,7 +529,7 @@
to_chat(user, span_boldnotice("[name] completed!"))
to_chat(user, span_hypnophrase(span_big("[pick_list(HERETIC_INFLUENCE_FILE, "drain_message")]")))
desc += " (Completed!)"
- log_heretic_knowledge("[key_name(user)] completed a [name] at [worldtime2text()].")
+ log_heretic_knowledge("[key_name(user)] completed a [name] at [gameTimestamp()].")
user.add_mob_memory(/datum/memory/heretic_knowledge_ritual)
return TRUE
@@ -558,7 +558,7 @@
for(var/datum/heretic_knowledge/knowledge as anything in flatten_list(our_heretic.researched_knowledge))
total_points += knowledge.cost
- log_heretic_knowledge("[key_name(user)] gained knowledge of their final ritual at [worldtime2text()]. \
+ log_heretic_knowledge("[key_name(user)] gained knowledge of their final ritual at [gameTimestamp()]. \
They have [length(our_heretic.researched_knowledge)] knowledge nodes researched, totalling [total_points] points \
and have sacrificed [our_heretic.total_sacrifices] people ([our_heretic.high_value_sacrifices] of which were high value)")
@@ -605,7 +605,7 @@
human_user.physiology.burn_mod *= 0.5
SSblackbox.record_feedback("tally", "heretic_ascended", 1, GLOB.heretic_research_tree[type][HKT_ROUTE])
- log_heretic_knowledge("[key_name(user)] completed their final ritual at [worldtime2text()].")
+ log_heretic_knowledge("[key_name(user)] completed their final ritual at [gameTimestamp()].")
notify_ghosts(
"[user] has completed an ascension ritual!",
source = user,
diff --git a/code/modules/art/paintings.dm b/code/modules/art/paintings.dm
index b3bcc4c8829..d92ac0582f8 100644
--- a/code/modules/art/paintings.dm
+++ b/code/modules/art/paintings.dm
@@ -248,7 +248,7 @@
painting_metadata.creator_ckey = user.ckey
painting_metadata.creator_name = user.real_name
- painting_metadata.creation_date = time2text(world.realtime)
+ painting_metadata.creation_date = time2text(world.realtime, "DDD MMM DD hh:mm:ss YYYY", TIMEZONE_UTC)
painting_metadata.creation_round_id = GLOB.round_id
generate_proper_overlay()
finalized = TRUE
diff --git a/code/modules/assembly/signaler.dm b/code/modules/assembly/signaler.dm
index b5346386d7d..31219791e2f 100644
--- a/code/modules/assembly/signaler.dm
+++ b/code/modules/assembly/signaler.dm
@@ -146,7 +146,7 @@
if(!radio_connection)
return
- var/time = time2text(world.realtime,"hh:mm:ss")
+ var/time = time2text(world.realtime, "hh:mm:ss", TIMEZONE_UTC)
var/turf/T = get_turf(src)
var/logging_data = "[time] : [key_name(usr)] used [src] @ location ([T.x],[T.y],[T.z]) : [format_frequency(frequency)]/[code]"
diff --git a/code/modules/buildmode/submodes/map_export.dm b/code/modules/buildmode/submodes/map_export.dm
index 9d59263aa47..0276fd199f2 100644
--- a/code/modules/buildmode/submodes/map_export.dm
+++ b/code/modules/buildmode/submodes/map_export.dm
@@ -84,7 +84,7 @@ GLOBAL_VAR_INIT(map_writing_running, FALSE)
var/dat = write_map(minx, miny, minz, maxx, maxy, maxz, save_flag, shuttle_flag)
//Step 2: Write the data to a file and give map to client
- var/date = time2text(world.timeofday, "YYYY-MM-DD_hh-mm-ss")
+ var/date = time2text(world.timeofday, "YYYY-MM-DD_hh-mm-ss", TIMEZONE_UTC)
var/file_name = sanitize_filename(tgui_input_text(usr, "Filename?", "Map Exporter", "exported_map_[date]"))
send_exported_map(usr, file_name, dat)
to_chat(usr, span_green("The map was successfully saved!"))
diff --git a/code/modules/detectivework/scanner.dm b/code/modules/detectivework/scanner.dm
index aedec750914..57bd2735707 100644
--- a/code/modules/detectivework/scanner.dm
+++ b/code/modules/detectivework/scanner.dm
@@ -205,9 +205,6 @@
log_data += list(log_entry_data)
return TRUE
-/proc/get_timestamp()
- return time2text(world.time + 432000, ":ss")
-
/obj/item/detective_scanner/click_alt(mob/living/user)
return clear_logs()
diff --git a/code/modules/events/_event.dm b/code/modules/events/_event.dm
index 94dae2c571f..6da47fd5a33 100644
--- a/code/modules/events/_event.dm
+++ b/code/modules/events/_event.dm
@@ -168,7 +168,7 @@ Runs the event
if(announce_chance_override != null)
round_event.announce_chance = announce_chance_override
- testing("[time2text(world.time, "hh:mm:ss")] [round_event.type]")
+ testing("[time2text(world.time, "hh:mm:ss", 0)] [round_event.type]")
triggering = TRUE
if(!triggering)
diff --git a/code/modules/fishing/fish_mount.dm b/code/modules/fishing/fish_mount.dm
index 37eeb0049f2..903a08801f4 100644
--- a/code/modules/fishing/fish_mount.dm
+++ b/code/modules/fishing/fish_mount.dm
@@ -124,7 +124,7 @@
if(!fish.catcher_name)
fish.catcher_name = catcher
if(!fish.catch_date)
- fish.catch_date = "[time2text(world.realtime, "Day, Month DD")], [CURRENT_STATION_YEAR]"
+ fish.catch_date = "[time2text(world.realtime, "Day, Month DD", NO_TIMEZONE)], [CURRENT_STATION_YEAR]"
AddElement(/datum/element/beauty, get_fish_beauty())
RegisterSignals(fish, list(COMSIG_ATOM_ATTACK_HAND, COMSIG_ATOM_ATTACK_PAW), PROC_REF(on_fish_attack_hand))
diff --git a/code/modules/holiday/holidays.dm b/code/modules/holiday/holidays.dm
index 68ce6651450..df760526a8f 100644
--- a/code/modules/holiday/holidays.dm
+++ b/code/modules/holiday/holidays.dm
@@ -147,7 +147,7 @@
return pick("Aotearoa","Kiwi","Fish 'n' Chips","Kākāpō","Southern Cross")
/datum/holiday/nz/greet()
- var/nz_age = text2num(time2text(world.timeofday, "YYYY")) - 1840
+ var/nz_age = text2num(time2text(world.timeofday, "YYYY", TIMEZONE_NZST)) - 1840
return "On this day [nz_age] years ago, New Zealand's Treaty of Waitangi, the founding document of the nation, was signed!"
/datum/holiday/valentines
@@ -172,7 +172,7 @@
poster_icon = "holiday_cake" // is a lie
/datum/holiday/birthday/greet()
- var/game_age = text2num(time2text(world.timeofday, "YYYY")) - 2003
+ var/game_age = text2num(time2text(world.timeofday, "YYYY", world.timezone)) - 2003
var/Fact
switch(game_age)
if(16)
@@ -870,7 +870,7 @@
/datum/holiday/easter/shouldCelebrate(dd, mm, yyyy, ddd)
if(!begin_month)
- current_year = text2num(time2text(world.timeofday, "YYYY"))
+ current_year = text2num(time2text(world.timeofday, "YYYY", world.timezone))
var/list/easterResults = EasterDate(current_year+year_offset)
begin_day = easterResults["day"]
diff --git a/code/modules/logging/log_holder.dm b/code/modules/logging/log_holder.dm
index 2fb94500ce9..8f136d2206e 100644
--- a/code/modules/logging/log_holder.dm
+++ b/code/modules/logging/log_holder.dm
@@ -276,7 +276,7 @@ ADMIN_VERB(log_viewer_new, R_ADMIN|R_DEBUG, "View Round Logs", "View the rounds
init_category_file(category_instance, category_header)
/datum/log_holder/proc/human_readable_timestamp(precision = 3)
- var/start = time2text(world.timeofday, "YYYY-MM-DD hh:mm:ss")
+ var/start = time2text(world.timeofday, "YYYY-MM-DD hh:mm:ss", TIMEZONE_UTC)
// now we grab the millis from the rustg timestamp
var/rustg_stamp = rustg_unix_timestamp()
var/list/timestamp = splittext(rustg_stamp, ".")
diff --git a/code/modules/lost_crew/damages/_damages.dm b/code/modules/lost_crew/damages/_damages.dm
index 6fdc2a8eee9..ab54334af70 100644
--- a/code/modules/lost_crew/damages/_damages.dm
+++ b/code/modules/lost_crew/damages/_damages.dm
@@ -118,8 +118,8 @@
body.timeofdeath = world.time - died_how_long_ago
var/death_real_time = world.realtime - died_how_long_ago
- var/current_date = time2text(death_real_time, "DD Month")
- var/current_year = text2num(time2text(death_real_time, "YYYY")) + STATION_YEAR_OFFSET
+ var/current_date = time2text(death_real_time, "DD Month", 0)
+ var/current_year = text2num(time2text(death_real_time, "YYYY", NO_TIMEZONE)) + STATION_YEAR_OFFSET
body.station_timestamp_timeofdeath = "[current_date] [current_year]"
/// Main corpse damage type that's used to apply damages to a body
diff --git a/code/modules/mob/living/silicon/robot/robot_defense.dm b/code/modules/mob/living/silicon/robot/robot_defense.dm
index a645f3583e4..65eb42ff19e 100644
--- a/code/modules/mob/living/silicon/robot/robot_defense.dm
+++ b/code/modules/mob/living/silicon/robot/robot_defense.dm
@@ -445,7 +445,7 @@ GLOBAL_LIST_INIT(blacklisted_borg_hats, typecacheof(list( //Hats that don't real
set_connected_ai(null)
message_admins("[ADMIN_LOOKUPFLW(user)] emagged cyborg [ADMIN_LOOKUPFLW(src)]. Laws overridden.")
log_silicon("EMAG: [key_name(user)] emagged cyborg [key_name(src)]. Laws overridden.")
- var/time = time2text(world.realtime,"hh:mm:ss")
+ var/time = time2text(world.realtime,"hh:mm:ss", TIMEZONE_UTC)
if(user)
GLOB.lawchanges.Add("[time] : [user.name]([user.key]) emagged [name]([key])")
else
diff --git a/code/modules/modular_computers/computers/item/computer.dm b/code/modules/modular_computers/computers/item/computer.dm
index fcad39f80ff..06243edd0f5 100644
--- a/code/modules/modular_computers/computers/item/computer.dm
+++ b/code/modules/modular_computers/computers/item/computer.dm
@@ -621,7 +621,7 @@
data["PC_programheaders"] = program_headers
data["PC_stationtime"] = station_time_timestamp()
- data["PC_stationdate"] = "[time2text(world.realtime, "DDD, Month DD")], [CURRENT_STATION_YEAR]"
+ data["PC_stationdate"] = "[time2text(world.realtime, "DDD, Month DD", NO_TIMEZONE)], [CURRENT_STATION_YEAR]"
data["PC_showexitprogram"] = !!active_program // Hides "Exit Program" button on mainscreen
return data
diff --git a/code/modules/modular_computers/file_system/programs/signalcommander.dm b/code/modules/modular_computers/file_system/programs/signalcommander.dm
index 1e6e3e54051..6a96a68d7fd 100644
--- a/code/modules/modular_computers/file_system/programs/signalcommander.dm
+++ b/code/modules/modular_computers/file_system/programs/signalcommander.dm
@@ -79,7 +79,7 @@
if(user)
computer.balloon_alert(user, "signaled")
- var/time = time2text(world.realtime,"hh:mm:ss")
+ var/time = time2text(world.realtime,"hh:mm:ss", TIMEZONE_UTC)
var/turf/T = get_turf(computer)
var/user_deets
if(signaling)
diff --git a/code/modules/paperwork/paper.dm b/code/modules/paperwork/paper.dm
index ef05d31ba22..2b827707c5c 100644
--- a/code/modules/paperwork/paper.dm
+++ b/code/modules/paperwork/paper.dm
@@ -223,9 +223,9 @@
if(is_signature)
field_text = signature_name
else if(is_date)
- field_text = "[time2text(world.timeofday, "DD/MM")]/[CURRENT_STATION_YEAR]"
+ field_text = "[time2text(world.timeofday, "DD/MM", NO_TIMEZONE)]/[CURRENT_STATION_YEAR]"
else if(is_time)
- field_text = time2text(world.timeofday, "hh:mm")
+ field_text = time2text(world.timeofday, "hh:mm", NO_TIMEZONE)
var/field_font = is_signature ? SIGNATURE_FONT : font
diff --git a/code/modules/transport/tram/tram_controller.dm b/code/modules/transport/tram/tram_controller.dm
index a84495a7cbe..e8a27c44c2a 100644
--- a/code/modules/transport/tram/tram_controller.dm
+++ b/code/modules/transport/tram/tram_controller.dm
@@ -89,7 +89,7 @@
else
serial_number = "LT306TG[rand(000000, 999999)]"
- mfg_date = "[CURRENT_STATION_YEAR]-[time2text(world.timeofday, "MM-DD")]"
+ mfg_date = "[CURRENT_STATION_YEAR]-[time2text(world.timeofday, "MM-DD", NO_TIMEZONE)]"
install_location = specific_transport_id
/datum/tram_mfg_info/proc/load_from_json(list/json_data)
diff --git a/code/modules/wiremod/components/action/radio.dm b/code/modules/wiremod/components/action/radio.dm
index 3940059453e..bda4624c069 100644
--- a/code/modules/wiremod/components/action/radio.dm
+++ b/code/modules/wiremod/components/action/radio.dm
@@ -86,7 +86,7 @@
if(COMPONENT_TRIGGERED_BY(trigger_input, port))
var/signal_code = round(code.value) || 0
var/turf/location = get_turf(src)
- var/time = time2text(world.realtime,"hh:mm:ss")
+ var/time = time2text(world.realtime,"hh:mm:ss", TIMEZONE_UTC)
var/list/loggable_strings = list("[time] : The [QDELETED(parent_shell) ? "null circuit shell(?)" : parent_shell] @ location ([location.x],[location.y],[location.z]) transmitted the following signal : [format_frequency(current_freq)]/[signal_code] via the radio circuit component.")
if(!isnull(owner_ckey))