Setting date range to start on Monday of the current week, and view to Sunday of the same week

Hello. I am attempting to create a date range that, effectively, shows the current as its range. When a user clicks the forward or backward buttons on the date range, I would like for them to be able to jump to the Monday of that previous week.

Here is the script that I’ve been using to set the range, but instead of setting to the range I would expect, it starts with a range of a month, and then after pressing one of the two navigation buttons it changes to a range of 2 days.

from datetime import datetime, timedelta
monday = datetime.today() - timedelta(days=datetime.today().weekday() % 7)
print monday

rootContainer.getComponent('Date Range').startDate = monday

sunday = system.date.addDays(monday, 6)

print sunday

rootContainer.getComponent('Date Range').endDate = sunday

outer_start = system.date.addMonths(monday, -2)
outer_end = system.date.addMonths(monday, 2)

rootContainer.getComponent('Date Range').outerRangeStartDate = outer_start
rootContainer.getComponent('Date Range').outerRangeEndDate = outer_end

This script is ran each time this vision window is opened, so it should set the range and days each time this window is opened.

I’m unsure why this is not erroring out if the result is so wildly different from what I would expect.

Why not use an expression binding? On your date range start date use my ugly expression to get the current Monday. Note this will only run once when the window opens because I have 0 poll rate for now(), that way you can change it without it reverting.

dateArithmetic(midnight(now(0)), -(getDayOfWeek(now(0))-2), "day")

Then for end date, outer range start, and outer range end use an appropriate expression binding

addDays({Root Container.Date Range.startDate},6) #for sunday
addMonths({Root Container.Date Range.startDate},2) # for outer start
addMonths({Root Container.Date Range.startDate},-2) # for outer end

Your navigation script would be simple

start = event.source.parent.getComponent('Date Range').startDate
newStart = system.date.addWeeks(start,-1)
event.source.parent.getComponent('Date Range').startDate = newStart
4 Likes

Maybe I miss-understand your first expression that should find Monday, but would -2 in that expression make it so only works on Wednesday?

Everything else makes absolute sense though.

Thank you very much!

EDIT: midnight is apparently an unrecognized function in Ignition 7.8

You will have to probably get a little more creative to replace the midnight portion, but it isn’t required. I just like to make sure I capture a complete day by starting from midnight. On the -2 part, what happens is if the current day is 5 which is Thursday and I want Monday? Monday is day 2.

5 - (5 - 2) = 2
6 - (6 - 2) = 2
1 - (1 - 2) = 2
and so on...
3 Likes

Ahh, okay, this break down of the logic makes a lot more sense now, thank you.

And yes, I figured midnight wasn’t necessarily required, but I may see if I can get creative and replicate its functionality regardless.

Thank you, you’ve been an excellent help.

1 Like

After getting back into this solution after working on another aspect of our project during the morning, I’ve ran into the issue that getDayOfWeek() doesn’t exist in ignition 7.8 expressions.

It looks like it exists inside of scripting, but not inside of expressions.

I ended up going back to the drawing board for this idea, and while it might be a little bit hack-y, I think it turned out fairly well.

In Ignition 7.8, which was one of the tags for this topic, the date range and expression functions are a little bit lacking for what I wanted to try to do.

Essentially I created a date range of my own using @dkhayes117 recommendation, but instead of using expression bindings which lacked the required functions for this purpose, I used scripting and other components.

An example of the GUI:
image

Effectively, each button has a fair bit of code which I’ll share here if anyone is interested.

Confirm Worker Button:

# create a dataset based on the selected user

# declare the database we'll use
db = 'database'

# create a reference to the date range label that we will be treating as our date range object.
date_range = event.source.parent.getComponent('Date Range')

# start by getting default start and stop dates
start_date = system.date.midnight(system.date.addDays(system.date.now(), -(system.date.getDayOfWeek(system.date.now()) -2)))
end_date = system.date.midnight(system.date.addDays(start_date, 6))

# assign the dates back to the date_range's custom property
date_range.start_date = start_date
date_range.end_date = end_date

# from there create a query and form the dataset
emp_id = event.source.parent.getComponent('Employee Select').selectedStringValue

user_query = 'select * FROM time_clock where date_time >= ? and date_time <= ? and emp_id = ? order by date_time asc'
user_values = [start_date, end_date, emp_id]
user_data = system.db.runPrepQuery(user_query, user_values, db)
user_dataset = system.dataset.toDataSet(user_data)

# populate the table from the dataset that has been created
event.source.parent.getComponent('Management Table').data = user_dataset

# format the dates to be readable in the application
readable_start_date = system.date.format(start_date, date_range.date_format)
readable_end_date = system.date.format(end_date, date_range.date_format)

# enable visibility of the date components
event.source.parent.getComponent('Date Range').visible = True
event.source.parent.getComponent('Date Range').text = str(readable_start_date) + ' - ' + str(readable_end_date)
event.source.parent.getComponent('Date Range Label').visible = True
event.source.parent.getComponent('Forward').visible = True
event.source.parent.getComponent('Backward').visible = True

Back Button:

# button used to navigate backwards through the date range

# declare the db that will be used
db = 'database'

# declare the date range object, (it's a label with custom properties)
date_range = event.source.parent.getComponent('Date Range')

# declare the date format that will be used (modified by changing the
# date_range label's custom property 'date_format'
date_format = date_range.date_format

# take the date_range's existing date properties, adjust them to be a week earlier
start_date = system.date.addDays(date_range.start_date, -7)
end_date = system.date.addDays(date_range.end_date, -7)

# assign the dates back to the date_range's custom property
date_range.start_date = start_date
date_range.end_date = end_date

# recreate the dataset with the new information
emp_id = event.source.parent.getComponent('Employee Select').selectedStringValue

user_query = 'select * FROM time_clock where date_time >= ? and date_time <= ? and emp_id = ? order by date_time asc'
user_values = [start_date, end_date, emp_id]
user_data = system.db.runPrepQuery(user_query, user_values, db)
user_dataset = system.dataset.toDataSet(user_data)

# populate the table from the dataset that has been created
event.source.parent.getComponent('Management Table').data = user_dataset

# update the date_range label with the changed date
readable_start_date = system.date.format(start_date, date_format)
readable_end_date = system.date.format(end_date, date_format)

# change the appearance of the date range
date_range.text = str(readable_start_date) + ' - ' + str(readable_end_date)

Forward button is the same as this code, but adding 7 days instead of subtracting them, naturally.

The one thing that is important though, is that your date_range label must have the date properties so that they can be adjusted and referenced.

Thanks very much to @dkhayes117 again because without their idea for the expression I probably wouldn’t have been able to get this far.

2 Likes

This was the thread that pulled up when I tried to check how to do this.
Took me a long time to figure out what @dkhayes117 had done.
I'm trying to do something similar today.
It was like X-(X-2)=2 to me. 2 for Monday.

Expression

dateArithmetic(midnight(now(0)), (2-getDayOfWeek(now(0))), "day")

Script

start_date = system.date.midnight(system.date.addDays(system.date.now(), 
+(2-system.date.getDayOfWeek(system.date.now()) )))

SQL

Dateadd(Day, 2-DATEPART(WEEKDAY, GETDATE()), 
DATEADD(Day, DATEDIFF(Day, 0, GETDATE()), 0))