I have done several modifications to the script to accommodate timezone in the format specifiers and appending st, nd, rd th to the day of month.
--[[ OBS Studio datetime script
This script transforms a text source into a digital clock. The datetime format
is configurable and uses the same syntax than the Lua os.date() call.
https://www.lua.org/pil/22.1.html
v1 - Created by Albin Kauffmann (albinou) https://gitlab.com/albinou/obs-scripts/-/blob/master/datetime.lua
v2 - Revisions by Richard Gagnon
added %dx day of month with st,rd,th,nd (01st) [01-31]\
noted %z
noted %Z
fixed ability to choose Text Source
v3 - Revisions by Scott Hardwick
added %dn day of the month as a decimal number [1-31]
added %mn month as a decimal number [1-12]
added %In hour, using a 12-hour clock as a decimal number [1-12]
noted %n
]]
obs = obslua
source_name = ""
datetime_format = ""
activated = false
-- Function to set the time text
function set_datetime_text(source, format)
if string.find(format, "%%dx") ~= nil then
local s = "thstndrd"
local i = 0
local x = 0
local d = os.date("%d")
x = tonumber(d) -- make the day string a number
if x < 4 or x > 20 then
i = tonumber(d.sub(d, -1)) * 2 -- get the number value of the last digit and multiple by 2 for indexing into s
if i > 6 then
i = 0
end
end
format = format.gsub(format, "%%dx", tostring(x)..string.sub(s, i + 1, i + 2))
end
if string.find(format, "%%dn") ~= nil then
local x = 0
local d = os.date("%d")
x = tonumber(d) -- make the day string a number
format = format.gsub(format, "%%dn", tostring(x))
end
if string.find(format, "%%mn") ~= nil then
local x = 0
local d = os.date("%m")
x = tonumber(d) -- make the month string a number
format = format.gsub(format, "%%mn", tostring(x))
end
if string.find(format, "%%In") ~= nil then
local x = 0
local d = os.date("%I")
x = tonumber(d) -- make the hour (12 hour clock) string a number
format = format.gsub(format, "%%In", tostring(x))
end
local text = os.date(format)
local settings = obs.obs_data_create()
obs.obs_data_set_string(settings, "text", text)
obs.obs_source_update(source, settings)
obs.obs_data_release(settings)
end
function timer_callback()
local source = obs.obs_get_source_by_name(source_name)
if source ~= nil then
set_datetime_text(source, datetime_format)
obs.obs_source_release(source)
end
end
function activate(activating)
if activated == activating then
return
end
activated = activating
if activating then
obs.timer_add(timer_callback, 1000)
else
obs.timer_remove(timer_callback)
end
end
-- Called when a source is activated/deactivated
function activate_signal(cd, activating)
local source = obs.calldata_source(cd, "source")
if source ~= nil then
local name = obs.obs_source_get_name(source)
if (name == source_name) then
activate(activating)
end
end
end
function source_activated(cd)
activate_signal(cd, true)
end
function source_deactivated(cd)
activate_signal(cd, false)
end
function reset()
activate(false)
local source = obs.obs_get_source_by_name(source_name)
if source ~= nil then
local active = obs.obs_source_showing(source)
obs.obs_source_release(source)
activate(active)
end
end
----------------------------------------------------------
function script_description()
return "Sets a text source to act as a clock when the source is active.\
\
The datetime format can use the following tags:\
\
%a abbreviated weekday name (e.g., Wed)\
%A full weekday name (e.g., Wednesday)\
%b abbreviated month name (e.g., Sep)\
%B full month name (e.g., September)\
%c date and time (e.g., 09/16/98 23:48:10)\
%d day of the month (16) [01-31]\
%dn day of the month as a decimal number [1-31]\
%dx day of month with st,rd,th,nd (01st) [01-31]\
%H hour, using a 24-hour clock (23) [00-23]\
%I hour, using a 12-hour clock (11) [01-12]\
%In hour, using a 12-hour clock as a decimal number [1-12]\
%M minute (48) [00-59]\
%m month (09) [01-12]\
%mn month as a decimal number [1-12]\
%p either \"am\" or \"pm\" (pm)\
%S second (10) [00-61]\
%w weekday (3) [0-6 = Sunday-Saturday]\
%x date (e.g., 09/16/98)\
%X time (e.g., 23:48:10)\
%Y full year (1998)\
%y two-digit year (98) [00-99]\
%z timezone (0600)\
%Z timezone (Mountain Standard Time)\
%n newline\
%% the character `%´"
end
function script_properties()
local props = obs.obs_properties_create()
obs.obs_properties_add_text(props, "format", "Datetime format", obs.OBS_TEXT_DEFAULT)
local p = obs.obs_properties_add_list(props, "source", "Text Source", obs.OBS_COMBO_TYPE_EDITABLE, obs.OBS_COMBO_FORMAT_STRING)
local sources = obs.obs_enum_sources()
if sources ~= nil then
for _, source in ipairs(sources) do
-- THIS LINE IS INCORRECT use following line source_id = obs.obs_source_get_id(source)
source_id = obs.obs_source_get_unversioned_id(source)
if source_id == "text_gdiplus" or source_id == "text_ft2_source" then
local name = obs.obs_source_get_name(source)
obs.obs_property_list_add_string(p, name, name)
end
end
end
obs.source_list_release(sources)
return props
end
function script_defaults(settings)
obs.obs_data_set_default_string(settings, "format", "%X")
end
function script_update(settings)
activate(false)
source_name = obs.obs_data_get_string(settings, "source")
datetime_format = obs.obs_data_get_string(settings, "format")
reset()
end
function script_load(settings)
local sh = obs.obs_get_signal_handler()
obs.signal_handler_connect(sh, "source_show", source_activated)
obs.signal_handler_connect(sh, "source_hide", source_deactivated)
end
As @erikfdev mentioned, you need to change the locale in order to change the language. Update the start of the set_date_time() function with something like this (where "de_DE.UTF-8" is the German locale):Is it possible to change the language to german?
function set_datetime_text(source, format)
-- save the current locale "time" setting
local locale_backup = os.setlocale(nil, "time")
-- set our own "time" locale setting
os.setlocale("de_DE.UTF-8", "time")
local text = os.date(format)
-- restore the original "time" locale setting
os.setlocale(locale_backup, "time")
local settings = obs.obs_data_create()
...
...
Is it possible to manually set a timezone? IE I'm in EST (-4) but want to display PST (-7)
os.date()
can be called with a second argument (the date to display, in seconds). This date can obtained with a call to os.time()
.os.date()
call with:local text = os.date(format, os.time() * - 8 * 60 * 60)
View attachment 77410
how to make it look like my screenshot? display HOUR above its position and DATE below its position, with Indonesian not English.
Did you to use a "\n" into the date & time format? ("\n" is a line break).
And in order to get the Indonesian date, you should change the locale (to "id_ID" I guess ?).
if "variable" == "value"
%ñ = "Sunday Mass"
--[[ OBS Studio datetime script
This script transforms a text source into a digital clock. The datetime format
is configurable and uses the same syntax than the Lua os.date() call.
]]
obs = obslua
source_name = ""
datetime_format = ""
time_offset = ""
activated = false
-- Function to set the time text
function set_datetime_text(source, format)
local time = os.time()
local time = time - (60*60*11) + (60*60*time_offset)
local text = os.date("!".. format, time)
-- print(text)
local settings = obs.obs_data_create()
obs.obs_data_set_string(settings, "text", text)
obs.obs_source_update(source, settings)
obs.obs_data_release(settings)
end
function timer_callback()
local source = obs.obs_get_source_by_name(source_name)
if source ~= nil then
set_datetime_text(source, datetime_format)
obs.obs_source_release(source)
end
end
function activate(activating)
if activated == activating then
return
end
activated = activating
if activating then
obs.timer_add(timer_callback, 1000)
else
obs.timer_remove(timer_callback)
end
end
-- Called when a source is activated/deactivated
function activate_signal(cd, activating)
local source = obs.calldata_source(cd, "source")
if source ~= nil then
local name = obs.obs_source_get_name(source)
if (name == source_name) then
activate(activating)
end
end
end
function source_activated(cd)
activate_signal(cd, true)
end
function source_deactivated(cd)
activate_signal(cd, false)
end
function reset()
activate(false)
local source = obs.obs_get_source_by_name(source_name)
if source ~= nil then
local active = obs.obs_source_showing(source)
obs.obs_source_release(source)
activate(active)
end
end
----------------------------------------------------------
function script_description()
return "Sets a text source to act as a clock when the source is active.\
\
The datetime format can use the following tags:\
\
%a abbreviated weekday name (e.g., Wed)\
%A full weekday name (e.g., Wednesday)\
%b abbreviated month name (e.g., Sep)\
%B full month name (e.g., September)\
%c date and time (e.g., 09/16/98 23:48:10)\
%d day of the month (16) [01-31]\
%H hour, using a 24-hour clock (23) [00-23]\
%I hour, using a 12-hour clock (11) [01-12]\
%M minute (48) [00-59]\
%m month (09) [01-12]\
%p either \"am\" or \"pm\" (pm)\
%S second (10) [00-61]\
%w weekday (3) [0-6 = Sunday-Saturday]\
%x date (e.g., 09/16/98)\
%X time (e.g., 23:48:10)\
%Y full year (1998)\
%y two-digit year (98) [00-99]\
%% the character `%´"
end
function script_properties()
local props = obs.obs_properties_create()
obs.obs_properties_add_text(props, "format", "Datetime format", obs.OBS_TEXT_DEFAULT)
int = obs.obs_properties_add_list(props, "offset", "Houre offset", obs.OBS_COMBO_TYPE_LIST, obs.OBS_COMBO_FORMAT_INT)
obs.obs_property_list_add_int(int, "UTC", 11)
obs.obs_property_list_add_int(int, "UTC + 1", 12)
obs.obs_property_list_add_int(int, "UTC + 2", 13)
obs.obs_property_list_add_int(int, "UTC + 3", 14)
obs.obs_property_list_add_int(int, "UTC + 4", 15)
obs.obs_property_list_add_int(int, "UTC + 5", 16)
obs.obs_property_list_add_int(int, "UTC + 6", 17)
obs.obs_property_list_add_int(int, "UTC + 7", 18)
obs.obs_property_list_add_int(int, "UTC + 8", 19)
obs.obs_property_list_add_int(int, "UTC + 9", 20)
obs.obs_property_list_add_int(int, "UTC + 10", 21)
obs.obs_property_list_add_int(int, "UTC + 11", 22)
obs.obs_property_list_add_int(int, "UTC + 12", 23)
obs.obs_property_list_add_int(int, "UTC - 1", 10)
obs.obs_property_list_add_int(int, "UTC - 2", 9)
obs.obs_property_list_add_int(int, "UTC - 3", 8)
obs.obs_property_list_add_int(int, "UTC - 4", 7)
obs.obs_property_list_add_int(int, "UTC - 5", 6)
obs.obs_property_list_add_int(int, "UTC - 6", 5)
obs.obs_property_list_add_int(int, "UTC - 7", 4)
obs.obs_property_list_add_int(int, "UTC - 8", 3)
obs.obs_property_list_add_int(int, "UTC - 9", 2)
obs.obs_property_list_add_int(int, "UTC - 10", 1)
obs.obs_property_list_add_int(int, "UTC - 11", 0)
local p = obs.obs_properties_add_list(props, "source", "Text Source", obs.OBS_COMBO_TYPE_EDITABLE, obs.OBS_COMBO_FORMAT_STRING)
local sources = obs.obs_enum_sources()
if sources ~= nil then
for _, source in ipairs(sources) do
source_id = obs.obs_source_get_id(source)
if source_id == "text_gdiplus_v2" or source_id == "text_ft2_source_v2" then
local name = obs.obs_source_get_name(source)
obs.obs_property_list_add_string(p, name, name)
end
end
end
obs.source_list_release(sources)
return props
end
function script_defaults(settings)
obs.obs_data_set_default_string(settings, "format", "%X")
end
function script_update(settings)
activate(false)
source_name = obs.obs_data_get_string(settings, "source")
datetime_format = obs.obs_data_get_string(settings, "format")
time_offset = obs.obs_data_get_int(settings, "offset")
reset()
end
function script_load(settings)
local sh = obs.obs_get_signal_handler()
obs.signal_handler_connect(sh, "source_show", source_activated)
obs.signal_handler_connect(sh, "source_hide", source_deactivated)
end
like this right?View attachment 77567
Using \n still can't. What is the solution?
where in the lua script change or add the "id_ID"? I can't find it, fyi I'm not a programmer and don't understand coding.