Set a range limit for the date parameters - sql-server

I have a report where I defined two parameters to set the starting date and ending date.
However, I want to implement a logic so that the user can choose starting date and ending date unless the range between them pass over 1 year. As an example, if the user chooses "01/01/2017" for the start date, the maximum available end date must be displayed and limited to "01/01/2018". The vice versa also must be applied, when the user chooses the end date first, start date must be limited.
Is that possible to implement this logic into Sql Reporting Services? Thanks in advance.

Related

Alexa AMAZON.DATE slot default to past dates

I am using the AMAZON.DATE slot and I would like it to default to past dates.
For example, if a user says Monday I would like it to automatically select last Monday rather than next Monday.
In the documentation it confirms that it defaults to 'on or after the current date':
"Utterances that map to a specific date (such as "today", "now", or
"november twenty-fifth") convert to a complete date: 2015-11-25. Note
that this defaults to dates on or after the current date (see below
for more examples)."
For my application there is no way a future date would make sense so it wouldn't be too difficult to manually program this in but I just wondered if there was any other way of doing it?
No, you cannot change the behavior of built in slots, so if Alexa resolves user's answer as a date - before passing it to your further processing just subtract 7 from resolved value. It will give you the date in the past.

Search between two dates with ISO8601 format

Using angularjs, dynamodb as DB here.
I have a form where user saves some data. I save my "CreateOn" date in my dynamo db as:
DateTime.UtcNow.ToString("o");
//This saves date in DB as:2018-08-21T12:58:08.7823906Z
Storing like this because dynamo db requires dates (string) to stored in ISO8601 format if you want to use between operator to search for date range.
Now I have a search filters on my page which is basically an angular calendar. When the user selects the date in the calendar( start and end date) I want to get the data back based on the selected date. Here I am using moment to pass the calendar selected date to my api call as:
moment(createdOn).toISOString()
Eg: If they select the Today's date in the calendar I pass the selected date
(Tue Aug 21 2018 00:00:00 GMT-0400 (Eastern Daylight Time)) to the above function
The result of passing this date to moment(createdOn).toISOString() is
2018-08-21T04:00:00.000Z
The search condition at dynamo db is:
conditions.Add(new ScanCondition("CreatedOn", ScanOperator.Between, startDate, endDate ));
If the user selects from the calendar the start date as "08-20-2018" (2018-08-20T04:00:00.000Z) and the end date is "08-21-2018"(2018-08-21T04:00:00.000Z), the code all the data created b/w these 2 dates.
Now the issue is if they select same start and end date then the code does not returns any data, I believe because the start and end date is "2018-08-21T04:00:00.000Z" and the time part of this is all 0000 etc.
My question is how can I convert the date from my calendar ie my end date to correctly reflect the the end time which they select. I havent used ISO8601 format before so not sure how can I do so.
Thanks
You don't need moment for this. You can zero out the time using a Date in the following way.
const date = new Date('2018-08-21T12:58:08.7823906Z')
date.setUTCHours(0)
date.setUTCMinutes(0)
date.setUTCSeconds(0)
date.setUTCMilliseconds(0)
Then you can simply use toISOString() to format the date.
date.toISOString()
// returns '2018-08-21T00:00:00.000Z'
If you don't want to zero out the time, and instead want to set some specific time, you can use a similar approach, just substitute the 0 with whatever time you want.
Some other things to note: DynamoDB doesn't require any specific formatting for dates. DynamoDB simply does a string or number comparison depending on what the field is defined as. You could store your dates in DynamoDB as integers or another string format if you feel that would be easier to work with.
Also, I'm not sure how your table is setup but make sure that your "CreateOn" field is the Range key and that you are using Query, not Scan. Using the Scan operation doesn't scale well.

Keep PivotTable report filter after data refresh

I have a PivotTable (actually it is five PivotTables, each on its own separate sheet) that is created from a query of an outside database. Each of the PivotTables represents a day (i.e. Today, Tomorrow, Today+2, Today+3, and Today+4). For the report filter for the first two, we use a date range filter of today and tomorrow which automatically filters the data and allows it to roll over. We created custom date ranges for the other three days, but upon every external data refresh we have to go into each sheet and reselect the report filter from all to the specified time frame. This data rolls over every day so we can see the lineup for the next 96 hours out.
Is there a way to either keep the PivotTable report filter criteria (VBA and macros are both acceptable, although we are also fairly new to both)?
Or is there some super secret way to extend the report filter from just today and tomorrow to a time range (48 hours, 96 hours) instead of next month?
I need the days to be separated, so next week will not work because all the days will populate on one page.
Without seeing a real example it's hard to tell, but how about changing the query to a relative date index, i.e. something like
SELECT DATEDIFF('day', GETDATE(), report_dt) AS days_from_today FROM reporting_table
And then set your report filters on this relative date index (days_from_today = 1 for tomorrow, etc)? You can always create another Excel column in the report =TODAY() + days_from_today to get your absolute date back. (Assuming you are just dealing with one time zone for reporting purposes.)
I.e., instead of rolling filters, keep the filters on constant indices, and let the indices cover a rolling date range. I'm not sure Excel is smart enough to do the rolling filters thing.

how to convert a date into both European and American time zones in the same sql server report rdl?

I have a report which takes timezone as input parameter, picks date from a table and converts this date to the user selected time zone.
User can select timezones from a dropdown which contains both US and European timezones.
When I select the European timezones, I see #Error in the date cell in the report.
I have no clue what so ever about reports and I need to fix this error in the inherited report.
The conversion is done by a little VB script embedded in the report.
Shared Function ConvertTimeZone(ByVal systemDate As Date, ByVal timeZoneId As String) As Date
Dim timeZoneInfo As TimeZoneInfo
timeZoneInfo = timeZoneInfo.FindSystemTimeZoneById(timeZoneId)
Return (timeZoneInfo.ConvertTimeFromUtc(systemDate, timeZoneInfo))
End Function
If EET is passed as timezone id - I see #Error in the date cell.
Could this be because both European and US timezones cant be used together?
Can someone guide me through this issue?
If EET is passed as timezone id - I see #Error in the date cell
That's because "EET" is not a valid time zone identifier. You can see all of the valid identifiers by examining the output from TimeZoneInfo.GetSystemTimeZones(), which returns a collection of TimeZoneInfo objects. Each one has an Id and a DisplayName. The Id is what needs to be passed in your timeZoneId parameter, while the DisplayName can be shown to your end user in the dropdown list. (You probably don't want to use the StandardName or DaylightName properties, unless you have a specific reason to.)
You are probably looking for the identifier "E. Europe Standard Time". Don't get confused by the name, it's the correct identifier covering both Eastern European Time (EET) and Eastern European Summer Time (EEST). The Microsoft time zone database is a bit strange in that way.
You can also see the valid time zones by running tzutil /l on the command line. Each time zone will emit two lines, where the top line is the display name, and the bottom line is the ID.
EDIT
Another suggestion, VB is case insensitive, but you have your variable named timeZoneInfo, which is the same as the class TimeZoneInfo. This would normally work ok, but I see that you have the lower case form on the ConvertTimeFromUtc method, and it should be upper case. Since this is VBScript, you might not be seeing this error until runtime. Try changing the case, or just use a different variable name so you don't get them confused.
Shared Function ConvertTimeZone(ByVal systemDate As Date, ByVal timeZoneId As String) As Date
Dim tzi As TimeZoneInfo
tzi = timeZoneInfo.FindSystemTimeZoneById(timeZoneId)
Return (TimeZoneInfo.ConvertTimeFromUtc(systemDate, tzi))
End Function
Here's another idea you can check if that doesn't fix it. The input systemDate should have come from your data, which should have DateTimeKind.Unspecified when you examine it's .Kind property. If for some reason you are taking it from DateTime.Now instead, then it would have a DateTimeKind.Local, which would through an exception.
If you still get the error, please see if you can find out what exception or error is actually occurring. Check log files, event viewer, etc.

Validating Date Parameter in SQL Server Stored Procedure

I've written a stored procedure that takes in a date parameter. My concern is that there will be confusion between American and British date formats. What is the best way to ensure that there is no ambiguity between dates such as 02/12/2008. One possibility would be for users to enter a date in a format such as 20081202 (yyyymmdd). Is there any way to validate that without using sub strings? Alternatively dates could be entered as 02-Dec-2008(dd-mmm-yyyy), but again verification is not trivial and there are potential issues with users who do not use English.
Further to the first three answers . . . One issue is that I'm expecting this stored proc to be called directly without a front end so validation ouside of the proc is not an option. Is it a good idea to take the day, month and year as separate parameters?
You won't have any problems whatsoever if you'd use parameters in your sproc:
create proc dbo.Sproc
#date datetime
as
...
If you declare the parameter as being of type DATETIME or one of the other typed date/time types in SQL Server, which you should, then there is no ambiguity; it represents a particular date and time. The type of validation you're talking about should happen outside the stored procedure, not inside.
OK from your comments and edit, it appears the issue is with the way people call the SP rather than actually within it. To that end, you simply need to train your users to use sortable date format, i.e.
yyyy-MM-dd HH:mm:ss
And then there is no ambiguity. Anybody who is allowed near a database should be aware of localisation issues and should always be using a non-ambiguous format like this one when entering dates.
I've ended up taking a string paramater for the date and require users to enter the month as a word. I check the input is a valid date by converting it to date. To ensure the month is entered as a word, I use the like comparator to compare the input string with "%Jan%" or "%Feb%" or "%Mar%" etc.
If your proc accepts the date as a datetime parameter then there is little you can do to validate that the desired format is ddmmyyyy and not mmddyyyy. It all depends on how the user entered the date and how it was passed to SQL.
For example: On a web page i could add a parameter like this
command.Parameters.AddWithValue("#mydate",mydateVar.ToString("dd/MM/yyyy"));
OR
command.Parameters.AddWithValue("#mydate",mydateVar.ToString("MM/dd/yyyy"));
And SQL will just insert what its given as long as the string can be cast to a date correctly. It wont know the format you want to use so it will try to cast to its system default format.
A solution i use although it may not be applicable in your situation is to have users enter all dates in whatever frontend you have in the dd-MMM-yyyy format. I can then be sure of the format before i insert into the DB. I use that format everywhere to keep it all the same throughout the app.
You said that you are expecting this stored proc to be called directly without a front end and validation ouside of the proc is not an option.
In that case the users will be inserting data directly, I also believe that in this case it is for internal use only (as the stored proc is going to be called directly)
So I think you have 2 options
if you have disciplined users you can agree on one of the safe formats: ISO yyyyddmm, or ISO8601 yyyy-mm-dd Thh:mm:ss:mmm if you need a time part as well
otherwise take 3 parameters: year, month, year and perform some validation inside the stored procedure
I say take a datetime and train them to use the ODBC canonical form of a date as in this example:
EXECUTE uspMyProc {d '2009-02-11'}
If you take a date that you have to parse, whether it be a string or the year, month and day as separate integer arguments, then you have to deal with days out of range for the month and year. Some functions that take those automatically advance or move backwards the day on you. Thus the trick of sending 0 for the day and getting the last day of the previous month. Others return an error. But handling that stuff yourself is probably not worth reinventing the wheel.
If you absolutely have to because novices will be running it directly (why would novices be running stored procedures directly?), I'd take three separate arguments and pass the concatenated date as a string in the format YYYY-MM-DD through ISDATE to verify the parameters and exit if it isn't valid.

Resources