Calculating holiday dates - sql

I have to create "holiday" table and then create php script so I could show it on my site.
Holidays can be specific, like 15.05.2012 - 15-th of the may.
And non-specific: First(or second, third) sunday of july
Is there any way to create calculated column, so this phrase "First(or second, third) sunday of july", could turn into x.07.2012.

Use a calendar table. There is no magic code built into SQL Server that knows when Easter is. This article shows the basic premise - you fill up a table with all the dates from year x to year y, then you update a column called IsHoliday for the dates that are holidays based on specific logic (easiest to do this once, in a loop, then all your code later can refer to the calculated bit):
ASP Faq reference. The current link no longer works, this is the archive.org cached version of the page

The link in the answer now takes you to a bogus page that wants to load a virus. Just heads up.
http://codeinet.blogspot.com/2006/08/auxiliary-calendar-table-for-sql.html
This seems to be a working version.

Related

How do I add new rows to SQL automatically by time?

I'm a pretty new programmer and I'm working on a project that I'm not sure how to make work. I'm hoping for some advice please.
Part of the project I'm working on will be used by a company to allow employees to sign up for lunch from their computers. I'm doing the project in MVC ASP.NET
The interface will look something like this:
----------------------
|1200 | Employee Dropdown Name 1
| Employee Dropdown Name 2
|---------------------
|1230 | Employee Dropdown Name 1
| Employee Dropdown Name 2
|---------------------
and on and on and on.
With this company, everything has to be recorded and stored. So, I already have a table with employee information. That will populate the drop down areas. Lunch times need to be stored in the database so it can be searched years down the line. So it has to be in a table.
The table get more tricky because not every time of the day is available for lunch (i.e. - no lunches after 0430 and before 0800).
My question is about how to create the future time slots in the database.
I could obviously make the table with all of these rows already in places for several years down the line. That's time-consuming, though, and I'll have to go back in in several years and fix it. Horrible idea.
What I'd LOVE to do is make it so every 24 hours, the database just automatically adds new rows with the next days times available - so just increment (at midnight, the program will just add the next day's times associated with that date (so at midnight on February 6, 2020, it will create February 7, 2020 0000, February 7, 2020 0030, etc. I've studied a lot but I'm still beside myself on how to make this work.
Thanks in advance everyone!!!
As I understand, you want to drive your interface from the database table so that the user can select Name 1 and Name 2 and a time slot and submit.
It sounds like you also want the available timeslots to be driven by the database also (ie, timeslot in table without names with it is availlable). This is not a good idea. As you mentioned, you would be inserting data that is not actually a record but a placeholder. That will be very confusing down the track when you come to query the data.
My approach would be to do the following:
* add NOT NULL constraints to all columns in your database (if your database supports this feature) or have your app complain very much about NULLS in any of the columns. There is no need for NULLS in your use case by the look of it.
the database should have a CHECK constraint that the time is within the allowable time range, and (assuming employees can not double book time slots) a CHECK constraint that there is no overlapping time slots, and also a UNIQUE constraint that ensures no duplicate times.... adjust to suit your needs.
your app populates times between 0800 and 1630 (8AM and 4:30PM) and also query the database for all records matching the current day so those booked slots can be removed from the list of available time slots... adjust to suit.
your app sends the user request of name and time slot to the DB. All the critical requirements are accepted or rejected by the DB schema and if there is something wrong, display an appropriate error in the app.
This way, your database is literally storing records of booked lunches.
I would NOT go down the path of pre inserting as then it becomes more complex as some records are "real" and some are artificially generated records to drive a GUI...
If you can't do the time slot calculations in your app rather than in the DB, then at least use a separate table that is maintained by a worker thread in your app OR if your DB supports it, a Stored Procedure which returns a table of available time slots.
I would use the stored procedure if I was avoiding doing complex time calculations in my app (also avoids need to worry about time zones - if you make sure to only store and display UTC times in your DB).
Having in mind structure like this:
LunchTimeSlots (id, time_slot)
Employee (id, name, preferred_time_slot_id, etc)
Lunches(employee_id, time_slot_id, date)
You need a scheduled job to add records to the "Lunches" table every midnight. How to define the job depends on your database vendor. But most of the popular rdbms have this feature. (f.e. mssql)
Despite it's possible to do what you want with db schedulers or any other scheduler, i would recommend to avoid such db design. It's always better to write real facts to the database like a list of employees or fact that lunch was served
to employee at 1pm today.
Unlike real facts, virtual data can be always generated "on-the-fly" by sql queries. F.e. by joining employees to list of dates from today till year 2100, we can get planned lunches for all employees for next 80 years.

IBM Domino: View formula with #now

There are some views which has columns with formula including #now. These columns are used to calculate days from now. But these views are so slow. I just need to get documents in specific category from result of view. Are there any setting in view to get category's document before calculate days? Or do I have to remove days columns from view and write an agent to add&calculate days columns to the view's result?
"Or [do] I have to remove days columns from view and write an agent to add&calculate days columns to the view's result?"
Yes. #Now in a view formula is a recipe for poor performance. Create a scheduled agent that runs once per day and updates a field on the document then show that field in the view.
This column formula allows you to add a Today value without using #Today and hence lots of continual processing;
TodayDateString:= "Today";
Today := #TextToTime(TodayDateString);
#Abs(#Integer((Today - DateToCompare) / (60 * 60 * 24)))
Already answered, but I still felt the need to add my thoughts.
If you can afford to touch your documents every day (e.g. it's just a web on a single or clustered server) then I'd seriously consider writing an agent that updates a "NumDaysOld" field.
The reason why performance is slow if you have #Now or #Today in a view selection or column formula is because the indexer then knows that it is time-dependent and therefore doesn't store the view index (or maybe just doesn't store the entire index, I'm not sure), causing it to rebuild every time it's accessed.
If you cheat this by using #TextToTime("Today") then your view indexes risk being out of date because if a document doesn't change for n days, the view doesn't change for n days, and the indexer isn't triggered...
Perhaps a best practice would be to write an agent to change the column formula every day so that instead of #Today, use a literal date (by using square brackets, like [5/29/2018]) and then write an agent to change that column formula every day. I've never tried that because that wasn't available to me when I had needed to do something like this. (It's been a long time.) Instead I have resolved this need by:
writing an agent that modified each document to update the age of the document, or
making folders for "< 1 month", "2 to 6 months", etc., and had a daily agent that would populating/correct the folders, or
avoiding the problem by having a view of open documents sorted by date and then trying to convince the end-users that was close enough! :-P (not proud of this one)

How do you get the ticket created date in trac?

I want to play with some really simple queries for a report, but I want to group everything by the creation date. The problem I am having is that time exists in the database, but not the date. From searching around in trac-related resources, it looks like I need to install trac.util.datefmt to be able to extract this information from datetime(time). I can find the API documentation for trac.util.datefmt, but not a download link to get the .egg.
Am I going in the right direction? If I can do what I need (i.e. get the creation month/day/year) without a plugin, what column do I use? I don't see anything else in the schema that is reasonable. If I do need trac.util.datefmt, where do I download it from? And if I really need a different plugin, which one should I be using?
I'll assume Trac >= 1.0. The time column is unix epoch time: the number of seconds that have elapsed since January 1st 1970. You can divide the value by 1e6 and put the value in a converter to see an example of extracting the datetime from the time column. trac.util.datefmt is part of the egg that ships with Trac, but since you are working with reports it doesn't sound like you need to know more about that function to accomplish your aim.
In a Trac report the time column will be automatically formatted as a date. You can look at the default report {1} as an example. I'm not sure how you intend to group by creation date. Do you wish to group tickets created in a certain datetime range?

How to Extend the End Date in a SQL Calendar Table?

I have a report that, according to users, started miscalculating dates in one field in November 2015. After some digging around, I found that one of the tables the field referenced seemed to have an end date on 2015-10-31.
The "D" field seems to represent the day of the week, with Sunday being day 1 and Saturday being 7.
Is there a way to extend the calendar so that it ends further into the future, for example 2049-12-31?
Our calendar table, for a variety of reasons, goes the the end of the current year. We have written a query that adds a new year to this table. This query takes care of most of the fields in that table. It does not touch the holiday field. That is updated manually through a web page.
We send ourselves reminders. Starting in March, we send monthly reminders that we should think about adding another year. After ensuring that the database segment has space, and that none of the definitions, such as fiscal periods, have changed, we run the query that adds a year.
Later in the year we start mailing ourselves reminders about the holidays. Then we check to see if HR has declared them, and if so, update the records accordingly.
This meets our business requirements. Yours will be different of course.

SQL Filtering based on Calculated Time Slots

Im making a simple booking system for our projectors at work.
Here is the scenario. Each projectors can have its availability set to quarter hour segments throughout the entire day. i.e projector 1 is available between 8:15am - 1:45pm and 3pm-5:15pm each day (can also be changed to have different availabilities set for each day). A projector can be booked for anytime time segment during the day as long as it is available. So ive got that setup in my sql database (with my asp.net mvc front end).
The question i have is what is the best way to search on this scenario. i.e. UserA comes in and says find me the projectors that are available this friday between 12pm-3pm. Im struggling to write an efficient sql query that will filter this. My best option so far is to pull back all projectors and than programatically work out if they are available and not booked between this time. It works but it is incredibly inefficient. I stumbled an idea of using a temp table generated by a stored proc that can than be filtered but it isnt quite there.
Has anyone got any ideas how i could approach this?
Thanks in advance
I would probably have a table called ProjectorReservations which contained a start time and end time (amongst other fields you might care about i.e. who is renting the projector).
Searching a projector would look something like this:
SELECT projectorName
FROM Projectors
WHERE NOT EXISTS
(SELECT 1 FROM ProjectorReservations
WHERE Projectors.projectorName = ProjectorReservations.projectorName
AND (ProjectorReservations.startTime < {end_time}
OR ProjectorReservations.endTime > {start_time}))
That pretty much checks to make sure no reservations start before the one you are looking for ends and vice versa. Obviously you will need to swap in your fields accordingly but that should give you the general idea