It is currently April 26th, 2024, 11:48 am

Using Regexp to calculate time?

Get help with creating, editing & fixing problems with skins
BunnyHelp
Posts: 3
Joined: May 6th, 2018, 10:50 pm

Using Regexp to calculate time?

Post by BunnyHelp »

Hello!
I'm attempting to create my very first skin - where my desktop background will change according to the time of day.

There are to be 4 "time of day" phases - Night, Dawn, Day, and Dusk (with a condition for it raining/snowing outside but we're not going to talk about that).


So right now, I'm trying to find the total number of minutes until Dawn, and my input string is "6:14 AM".

I've been trying to use RegExp to pull the minute and hour values from "6:14 AM", but have been failing miserably for hours.

Any ideas?
User avatar
jsmorley
Developer
Posts: 22630
Joined: April 19th, 2009, 11:02 pm
Location: Fort Hunt, Virginia, USA

Re: Using Regexp to calculate time?

Post by jsmorley »

Give me a few minutes to play with something, and I'll see if I can't get you started. It's not really quite as simple as pulling the "hour" and "minute" out of "6:45 AM", in order to know how many minutes until or since dawn it is right now, but likely doable.
User avatar
jsmorley
Developer
Posts: 22630
Joined: April 19th, 2009, 11:02 pm
Location: Fort Hunt, Virginia, USA

Re: Using Regexp to calculate time?

Post by jsmorley »

Perhaps something like:

Code: Select all

[Rainmeter]
AccurateText=1
DynamicWindowSize=1
Update=1000

[Variables]
Sunrise=6:45 AM

[MeasureToday]
Measure=Time
Format=%m %d %Y

[MeasureTomorrow]
Measure=Time
Timestamp=([MeasureToday:Timestamp] + 86400)
Format=%m %d %Y
DynamicVariables=1

[MeasureNowHour]
Measure=Time
Format=%#H

[MeasureNowMinute]
Measure=Time
Format=%M

[MeasureSunriseHour]
Measure=String
String=#Sunrise#
RegExpSubstitute=1
Substitute="^([\d]{1,2}):[\d]{2} \w\w$":"\1"

[MeasureSunriseMinute]
Measure=String
String=#Sunrise#
RegExpSubstitute=1
Substitute="^[\d]{1,2}:([\d]{2}) \w\w$":"\1"

[MeasureBeforeOrAfter]
Measure=Calc
Formula=1
IfCondition=(MeasureNowHour * 3600 + MeasureNowMinute * 60) > ([MeasureSunRiseHour] * 3600 + [MeasureSunRiseMinute] * 60)
IfTrueAction=[!SetOption MeasureSunRiseTimestamp TimeStamp "[*MeasureTomorrow*] [*MeasureSunriseHour*] [*MeasureSunriseMinute*]"]
IfFalseAction=[!SetOption MeasureSunRiseTimestamp TimeStamp "[*MeasureToday*] [*MeasureSunriseHour*] [*MeasureSunriseMinute*]"]
DynamicVariables=1

[MeasureSunRiseTimestamp]
Measure=Time
TimeStamp=[MeasureToday] [MeasureSunriseHour] [MeasureSunriseMinute]
TimestampFormat=%m %d %Y %#I %M
DynamicVariables=1

[MeasureDifference]
Measure=Calc
Formula=Abs(([MeasureToday:Timestamp] - [MeasureSunRiseTimestamp:Timestamp]))
DynamicVariables=1

[MeasureFormatDifference]
Measure=Uptime
SecondsValue=[MeasureDifference:]
Format=%3!i! hours %2!i! minutes %1!i! seconds
DynamicVariables=1

[MeterDifference]
Meter=String
MeasureName=MeasureFormatDifference
FontSize=11
FontWeight=400
FontColor=255,255,255,255
SolidColor=47,47,47,255
Padding=5,5,5,5
AntiAlias=1
https://docs.rainmeter.net/manual-beta/measures/time/
https://docs.rainmeter.net/manual-beta/measures/uptime/
1.jpg
You do not have the required permissions to view the files attached to this post.
User avatar
jsmorley
Developer
Posts: 22630
Joined: April 19th, 2009, 11:02 pm
Location: Fort Hunt, Virginia, USA

Re: Using Regexp to calculate time?

Post by jsmorley »

That feels like it has a logic flaw when the current time is the same day as the sunrise value, but before it, so like midnight til 6:44 AM in this case. I can't quite put my finger on it yet, as it gets pretty complicated pretty quick... ;-)

I think it will work fine to answer "how long until sunrise tomorrow?" though.

This really should be done in Lua... What you really want is to know how long til sunrise is when it is currently night, and how long til sunset is when it is currently day.
User avatar
balala
Rainmeter Sage
Posts: 16172
Joined: October 11th, 2010, 6:27 pm
Location: Gheorgheni, Romania

Re: Using Regexp to calculate time?

Post by balala »

BunnyHelp wrote:So right now, I'm trying to find the total number of minutes until Dawn, and my input string is "6:14 AM".
Beside jsmorley reply, I'm not sure where would you like to use WebParser measures (RegExp). Also when is the moment of "Dawn"? Do you get it through WebParser measure(s), downloading it?
Details would be needed.
User avatar
jsmorley
Developer
Posts: 22630
Joined: April 19th, 2009, 11:02 pm
Location: Fort Hunt, Virginia, USA

Re: Using Regexp to calculate time?

Post by jsmorley »

You can use something like this to get the sunrise / sunset values for your location.

Code: Select all

[Rainmeter]
Update=1000
DynamicWindowSize=1
AccurateText=1

[Variables]
TimeColor=232,232,232
DayColor=242,232,177
NightColor=150,147,128

LocationCode=USVA0944

[MeasureTime12]
Measure=Time
Format=%#I:%M

[MeasureSiteSun]
Measure=WebParser
URL=https://wxdata.weather.com/wxdata/weather/local/#LocationCode#
RegExp=(?siU).*<sunr>(.*)</sunr>.*<suns>(.*)</suns>
FinishAction=[!EnableMeasureGroup Sun]

[MeasureSiteRise]
Measure=WebParser
URL=[MeasureSiteSun]
StringIndex=1
RegExpSubstitute=1
Substitute=":":"."," AM":"+0"," PM":"+12","^(.+)$":"(\1)","^$":"6.00"

[MeasureSiteSet]
Measure=WebParser
URL=[MeasureSiteSun]
StringIndex=2
RegExpSubstitute=1
Substitute=":":"."," AM":"+0"," PM":"+12","^(.+)$":"(\1)","^$":"18.00"

[MeasureTime24]
Measure=Time
Group=Sun
Format=%#H.%#M
Disabled=1

[MeasureSun]
Measure=Calc
Group=Sun
Formula=(MeasureTime24 >= 0) && (MeasureTime24 < 1) ? 1 : ((MeasureTime24 >= 12) && (MeasureTime24 < 13) ? 2 : (MeasureTime24 < 12 ? 3 : (MeasureTime24 < 16 ? 4 : 5)))
Substitute="1":"Midnight Hour","2":"Noon Hour","3":"Morning","4":"Afternoon","5":"Evening"
IfCondition=(MeasureTime24 > [MeasureSiteRise]) && (MeasureTime24 < [MeasureSiteSet])
IfTrueAction=[!SetOption MeterSun FontColor "#DayColor#"][!SetOption MeterSun Text "[MeasureSun]"]
IfFalseAction=[!SetOption MeterSun FontColor "#NightColor#"][!SetOption MeterSun Text "[MeasureSun]"]
DynamicVariables=1
IfConditionMode=1
Disabled=1

[MeterTime]
Meter=String
MeasureName=MeasureTime12
FontSize=44
FontColor=#TimeColor#
SolidColor=0,0,0,1
AntiAlias=1

[MeterSun]
Meter=String
X=([MeterTime:W] - 5)
Y=-7R
StringAlign=Right
FontSize=13
AntiAlias=1
DynamicVariables=1
1.jpg
You do not have the required permissions to view the files attached to this post.
User avatar
jsmorley
Developer
Posts: 22630
Joined: April 19th, 2009, 11:02 pm
Location: Fort Hunt, Virginia, USA

Re: Using Regexp to calculate time?

Post by jsmorley »

I still think this will be easier, or at least less brute-force code, to do in Lua.

This is the logic I think one needs:
sunrise might be today or tomorrow
sunset will always be today

sunrise will always be am
sunset will always be pm

We don't care when sunrise is when the sun is currently up
We don't care when sunset is when the sun is currently down

if it is at or after sunrise, then time til sunset will be the number of seconds until sunset
if it is at or after sunset, but before midnight, then time til sunrise will be the number of seconds until midnight today, plus the number of seconds until sunrise tomorrow
if it is at or after sunset, but at or after midnight, then time til sunrise will be the number of seconds until sunrise
I'll play with this today and see if I can't come up with something fairly flexible and easy to use. Seems that one would want to be able to ask "is it daytime or nighttime?". "if it's daytime, how long until nighttime?". "if it's nighttime, how long until daytime?".
User avatar
jsmorley
Developer
Posts: 22630
Joined: April 19th, 2009, 11:02 pm
Location: Fort Hunt, Virginia, USA

Re: Using Regexp to calculate time?

Post by jsmorley »

See if this doesn't get you off on the right foot...

https://forum.rainmeter.net/viewtopic.php?p=148336#p148336

Skin:

Code: Select all

[Rainmeter]
Update=1000
DynamicWindowSize=1
AccurateText=1

[Variables]
LocationCode=USVA0944

[MeasureTime]
Measure=Time
Format=%#I:%M:%S %p

[MeasureSun]
Measure=WebParser
URL=https://wxdata.weather.com/wxdata/weather/local/#LocationCode#
RegExp=(?siU).*<sunr>(.*)</sunr>.*<suns>(.*)</suns>
FinishAction=[!EnableMeasure Lua][!UpdateMeasure Lua][!ShowMeterGroup MyMeters]

[MeasureRise]
Measure=WebParser
URL=[MeasureSun]
StringIndex=1

[MeasureSet]
Measure=WebParser
URL=[MeasureSun]
StringIndex=2

[Lua]
Measure=Script
ScriptFile=#CURRENTPATH#SunRiseSet.lua
Disabled=1

[MeterBack]
Meter=Image
Group=MyMeters
W=350
H=85
SolidColor=47,47,47,255
Hidden=1

[MeterDayState]
Meter=String
Group=MyMeters
X=10
Y=10
FontSize=15
FontWeight=700
FontColor=255,255,255,255
AntiAlias=1
Hidden=1
Text=Good [Lua:dayStateString]
DynamicVariables=1

[MeterSunState]
Meter=String
Group=MyMeters
X=10
Y=5R
FontSize=11
FontWeight=400
FontColor=255,255,255,255
InlineSetting=Weight | 700
InlinePattern=currently (.*) at
AntiAlias=1
Hidden=1
Text=It is currently [Lua:sunStateString] at [MeasureTime]
DynamicVariables=1

[MeterChange]
Meter=String
Group=MyMeters
X=10
Y=5R
FontSize=11
FontWeight=400
FontColor=255,255,255,255
InlineSetting=Weight | 700
InlinePattern=(.*) is in
AntiAlias=1
Hidden=1
Text=[Lua:changeString][Lua:formatString]
DynamicVariables=1
Lua:

Code: Select all

function Initialize()

	measureRise = SKIN:GetMeasure('MeasureRise')
	measureSet = SKIN:GetMeasure('MeasureSet')
	
end

function Update()

	inSunrise = measureRise:GetStringValue()
	inSunset = measureSet:GetStringValue()
	
	NextChange(inSunrise, inSunset)
	
	return formatString
	
end

function NextChange(inSunrise, inSunset)

	currentTime = os.date('*t')
	secondsSinceMidnight = os.time() - os.time({year=currentTime.year, month=currentTime.month, day=currentTime.day, hour=0, min=0, sec=0})
	secondsTilMidnight = os.time({year=currentTime.year, month=currentTime.month, day=currentTime.day, hour=23, min=59, sec=59}) - os.time()
	
	riseHour = string.match(inSunrise, '(.-):')
	riseMinute = string.match(inSunrise, '.-:(%d%d)')
	setHour = string.match(inSunset, '(.-):') + 12
	setMinute = string.match(inSunset, '.-:(%d%d)')
	
	if currentTime.hour >= 0 and currentTime.hour < 12 then
		dayStateString = 'Morning'
	elseif currentTime.hour >= 12 and currentTime.hour < setHour then
		dayStateString = 'Afternoon'
	else
		dayStateString = 'Evening'
	end
	
	if os.time() >= os.time({year=currentTime.year, month=currentTime.month, day=currentTime.day, hour=setHour, min=setMinute})  then
		dayState = 'SunRiseTomorrow'
	elseif os.time() <= os.time({year=currentTime.year, month=currentTime.month, day=currentTime.day, hour=riseHour, min=riseMinute}) then
		dayState = 'SunRiseToday'
	else
		dayState = 'SunSetToday'
	end
	
	if dayState == 'SunRiseTomorrow' then
		secondsTilChange = secondsTilMidnight + (riseHour * 3600) + (riseMinute * 60)
	end
	
	if dayState == 'SunRiseToday' then
		secondsTilChange = ((riseHour * 3600) + (riseMinute * 60)) - secondsSinceMidnight
	end
	
	if dayState == 'SunSetToday' then
		secondsTilChange = os.time({year=currentTime.year, month=currentTime.month, day=currentTime.day, hour=setHour, min=setMinute}) - os.time()
	end
	
	formatTable = ConvertSeconds(secondsTilChange)
	formatString = formatTable.hours..' hours '..formatTable.mins..' minutes '..formatTable.secs..' seconds'
	
	if dayState == 'SunSetToday' then
		sunStateString = 'Daytime'
		changeString = 'Sunset is in '
	else 
		sunStateString = 'Nighttime'
		changeString = 'Sunrise is in '
	end

	if os.time() >= os.time({year=currentTime.year, month=currentTime.month, day=currentTime.day, hour=setHour, min=setMinute}) - 1800 and os.time() <= os.time({year=currentTime.year, month=currentTime.month, day=currentTime.day, hour=setHour, min=setMinute}) + 1800 then
		sunStateString = 'Twilight'
	end

	if os.time() >= os.time({year=currentTime.year, month=currentTime.month, day=currentTime.day, hour=riseHour, min=riseMinute}) - 1800 and os.time() <= os.time({year=currentTime.year, month=currentTime.month, day=currentTime.day, hour=riseHour, min=riseMinute}) + 1800 then
		sunStateString = 'Dawn'
	end
	
	return formatString
	
end


function ConvertSeconds(secondsArg)
   
   local daysDiff = math.floor(secondsArg / 86400)
   local remainder = (secondsArg % 86400)
   local hoursDiff = math.floor(remainder / 3600)
   local remainder = (secondsArg % 3600)
   local minsDiff = math.floor(remainder / 60)
   local secsDiff = (remainder % 60)
   
   local elapsedTable = {days=daysDiff, hours=hoursDiff, mins=minsDiff, secs=secsDiff}   
   
   return elapsedTable
   
end
Working with Date and Time in Lua
Inline Lua
1.jpg
You do not have the required permissions to view the files attached to this post.
User avatar
SilverAzide
Rainmeter Sage
Posts: 2610
Joined: March 23rd, 2015, 5:26 pm

Re: Using Regexp to calculate time?

Post by SilverAzide »

jsmorley wrote:I still think this will be easier, or at least less brute-force code, to do in Lua.

This is the logic I think one needs:

I'll play with this today and see if I can't come up with something fairly flexible and easy to use. Seems that one would want to be able to ask "is it daytime or nighttime?". "if it's daytime, how long until nighttime?". "if it's nighttime, how long until daytime?".
This is an interesting exercise, and I would not want to complicate it further, but one item that may have been lost in the OP's original question (if he's still interested) was that he wanted 4 timespans: dawn, day, dusk, and night. The duration of dawn/dusk are not insignificant spans of time (especially in higher/lower latitudes), and you can't get the dawn/dusk times from weather.com. User buckb recently posted some brain-bending Lua code on this thread here that can tell you all 4 of these intervals, I think, but I have not figured out how to do it yet. Mordasius has some steampunk skins with Lua scripts for this too. The only use I've seen for weather.com so far is to get the user's lat/long (and TZ offset), then do everything else with Lua.
Gadgets Wiki GitHub More Gadgets...
User avatar
jsmorley
Developer
Posts: 22630
Joined: April 19th, 2009, 11:02 pm
Location: Fort Hunt, Virginia, USA

Re: Using Regexp to calculate time?

Post by jsmorley »

SilverAzide wrote:This is an interesting exercise, and I would not want to complicate it further, but one item that may have been lost in the OP's original question (if he's still interested) was that he wanted 4 timespans: dawn, day, dusk, and night. The duration of dawn/dusk are not insignificant spans of time (especially in higher/lower latitudes), and you can't get the dawn/dusk times from weather.com. User buckb recently posted some brain-bending Lua code on this thread here that can tell you all 4 of these intervals, I think, but I have not figured out how to do it yet. Mordasius has some steampunk skins with Lua scripts for this too. The only use I've seen for weather.com so far is to get the user's lat/long (and TZ offset), then do everything else with Lua.
Whew... Yeah.

What I've got is not all that complicated. The only slightly tricky bit is knowing the amount of time from the evening of "today" until sunrise "tomorrow". That takes a bit of crunching, but not much.