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.
--[[ 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
v4 - Revisions by Suslik V
removed %dx Reason: No localization.
added %ms Month as a custom string (12 values)
added %ws Weekday as a custom string (7 values)
added %Hn Hour, in 24h format as a decimal number (0-23)
]]
local obs = obslua
local source_name = ""
local datetime_format = ""
local activated = false
local week = {}
local month = {}
-- Function to set the time text
function set_datetime_text(source, format)
local x = 0
local d = ""
if string.find(format, "%%dn") ~= nil then
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
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, "%%Hn") ~= nil then
d = os.date("%H")
x = tonumber(d) -- make the hour (24 hour clock) string a number
format = format.gsub(format, "%%Hn", tostring(x))
end
if string.find(format, "%%In") ~= nil then
d = os.date("%I")
x = tonumber(d) -- make the hour (12 hour clock) string a number
format = format.gsub(format, "%%In", tostring(x))
end
if string.find(format, "%%ws") ~= nil then
d = os.date("%w")
x = tonumber(d) -- make the week string a number
format = format.gsub(format, "%%ws", week[x + 1])
end
if string.find(format, "%%ms") ~= nil then
d = os.date("%m")
x = tonumber(d) -- make the month string a number
format = format.gsub(format, "%%ms", month[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."
end
function script_properties()
local props = obs.obs_properties_create()
obs.obs_properties_add_text(props, "sunday_0", "Sunday", obs.OBS_TEXT_DEFAULT)
obs.obs_properties_add_text(props, "monday_1", "Monday", obs.OBS_TEXT_DEFAULT)
obs.obs_properties_add_text(props, "tuesday_2", "Tuesday", obs.OBS_TEXT_DEFAULT)
obs.obs_properties_add_text(props, "wednesday_3", "Wednesday", obs.OBS_TEXT_DEFAULT)
obs.obs_properties_add_text(props, "thursday_4", "Thursday", obs.OBS_TEXT_DEFAULT)
obs.obs_properties_add_text(props, "friday_5", "Friday", obs.OBS_TEXT_DEFAULT)
obs.obs_properties_add_text(props, "saturday_6", "Saturday", obs.OBS_TEXT_DEFAULT)
obs.obs_properties_add_text(props, "month_1", "Jun", obs.OBS_TEXT_DEFAULT)
obs.obs_properties_add_text(props, "month_2", "Feb", obs.OBS_TEXT_DEFAULT)
obs.obs_properties_add_text(props, "month_3", "Mar", obs.OBS_TEXT_DEFAULT)
obs.obs_properties_add_text(props, "month_4", "Apr", obs.OBS_TEXT_DEFAULT)
obs.obs_properties_add_text(props, "month_5", "May", obs.OBS_TEXT_DEFAULT)
obs.obs_properties_add_text(props, "month_6", "Jun", obs.OBS_TEXT_DEFAULT)
obs.obs_properties_add_text(props, "month_7", "Jul", obs.OBS_TEXT_DEFAULT)
obs.obs_properties_add_text(props, "month_8", "Aug", obs.OBS_TEXT_DEFAULT)
obs.obs_properties_add_text(props, "month_9", "Sep", obs.OBS_TEXT_DEFAULT)
obs.obs_properties_add_text(props, "month_10", "Oct", obs.OBS_TEXT_DEFAULT)
obs.obs_properties_add_text(props, "month_11", "Nov", obs.OBS_TEXT_DEFAULT)
obs.obs_properties_add_text(props, "month_12", "Dec", obs.OBS_TEXT_DEFAULT)
p = obs.obs_properties_add_text(props, "format", "Datetime format", obs.OBS_TEXT_DEFAULT)
local desc = "Specifier Replaced by [Example]\
%a Abbreviated weekday name [Thu]\
%A Full weekday name [Thursday]\
%b Abbreviated month name [Aug]\
%B Full month name [August]\
%c Date and time representation [Thu Aug 23 14:55:02 2001]\
%C Year divided by 100 and truncated to integer (00-99) [20]\
%d Day of the month, zero-padded (01-31) [04]\
%dn Day of the month (1-31) [4]\
%D Short MM/DD/YY date, equivalent to %m/%d/%y [08/23/01]\
%e Day of the month, space-padded ( 1-31) [ 3]\
%F Short YYYY-MM-DD date, equivalent to %Y-%m-%d [2001-08-23]\
%g Week-based year, last two digits (00-99) [01]\
%G Week-based year [2001]\
%h Abbreviated month name (same as %b) [Aug]\
%H Hour in 24h format, zero-padded (00-23) [14]\
%I Hour in 12h format, zero padded (01-12) [02]\
%Hn Hour, in 24h format as a decimal number [0-23] [21]\
%In Hour, in 12h format as a decimal number [1-12] [9]\
%j Day of the year (001-366) [235]\
%m Month as a decimal number, zero padded (01-12) [08]\
%mn Month as a decimal number (1-12) [8]\
%ms Month as a custom string (12 values) [Winter]\
%M Minute (00-59) [55]\
%n New-line character ('\\n')\
%p AM or PM designation [PM]\
%r 12-hour clock time [02:55:02 pm]\
%R 24-hour HH:MM time, equivalent to %H:%M [14:55]\
%S Second (00-61) [02]\
%t Horizontal-tab character ('\\t')\
%T ISO 8601 time format (HH:MM:SS), equivalent to %H:%M:%S [14:55:02]\
%u ISO 8601 weekday as number with Monday as 1 (1-7) [4]\
%U Week number with the first Sunday as the first day of week one (00-53) [33]\
%V ISO 8601 week number (01-53) [34]\
%w Weekday as a decimal number with Sunday as 0 (0-6) [4]\
%ws Weekday as a custom string (7 values) [Middle day]\
%W Week number with the first Monday as the first day of week one (00-53) [34]\
%x Date representation [08/23/01]\
%X Time representation [14:55:02]\
%y Year, last two digits (00-99) [01]\
%Y Year [2001]\
%z ISO 8601 offset from UTC in timezone (1 minute=1, 1 hour=100)\
If timezone cannot be determined, no characters [+0200]\
%Z Timezone name or abbreviation\
If timezone cannot be determined, no characters [CDT]\
%% A % sign"
obs.obs_property_set_long_description(p, desc)
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_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")
obs.obs_data_set_default_string(settings, "sunday_0", "First day of week")
obs.obs_data_set_default_string(settings, "monday_1", "Second day of week")
obs.obs_data_set_default_string(settings, "tuesday_2", "Third day of week")
obs.obs_data_set_default_string(settings, "wednesday_3", "Middle day of week")
obs.obs_data_set_default_string(settings, "thursday_4", "Fifth day of week")
obs.obs_data_set_default_string(settings, "friday_5", "Sixth day of week")
obs.obs_data_set_default_string(settings, "saturday_6", "Last day of week")
obs.obs_data_set_default_string(settings, "month_1", "I")
obs.obs_data_set_default_string(settings, "month_2", "II")
obs.obs_data_set_default_string(settings, "month_3", "III")
obs.obs_data_set_default_string(settings, "month_4", "IV")
obs.obs_data_set_default_string(settings, "month_5", "V")
obs.obs_data_set_default_string(settings, "month_6", "VI")
obs.obs_data_set_default_string(settings, "month_7", "VII")
obs.obs_data_set_default_string(settings, "month_8", "VIII")
obs.obs_data_set_default_string(settings, "month_9", "IX")
obs.obs_data_set_default_string(settings, "month_10", "X")
obs.obs_data_set_default_string(settings, "month_11", "XI")
obs.obs_data_set_default_string(settings, "month_12", "XII")
end
function script_update(settings)
activate(false)
week[1] = obs.obs_data_get_string(settings, "sunday_0")
week[2] = obs.obs_data_get_string(settings, "monday_1")
week[3] = obs.obs_data_get_string(settings, "tuesday_2")
week[4] = obs.obs_data_get_string(settings, "wednesday_3")
week[5] = obs.obs_data_get_string(settings, "thursday_4")
week[6] = obs.obs_data_get_string(settings, "friday_5")
week[7] = obs.obs_data_get_string(settings, "saturday_6")
month[1] = obs.obs_data_get_string(settings, "month_1")
month[2] = obs.obs_data_get_string(settings, "month_2")
month[3] = obs.obs_data_get_string(settings, "month_3")
month[4] = obs.obs_data_get_string(settings, "month_4")
month[5] = obs.obs_data_get_string(settings, "month_5")
month[6] = obs.obs_data_get_string(settings, "month_6")
month[7] = obs.obs_data_get_string(settings, "month_7")
month[8] = obs.obs_data_get_string(settings, "month_8")
month[9] = obs.obs_data_get_string(settings, "month_9")
month[10] = obs.obs_data_get_string(settings, "month_10")
month[11] = obs.obs_data_get_string(settings, "month_11")
month[12] = obs.obs_data_get_string(settings, "month_12")
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