im using spotfire software and i have a datetime column like:
DateTime
21/07/2022 12:11:01
21/07/2022 14:32:01
04/12/2022 10:22:01
30/06/2022 16:22:01
how can i created a new calculated column where it instead changes the date to the monday of the week for all values?
many thanks
i can do this in power bi by dropping the time and using the function
Start of Week Monday = 'Data'[DateTime ]+1-WEEKDAY('Data'[DateTime ]-1)
this results in all the values changing to the monday of its given week/month/year
how can i do this in spotfire?
Assuming you have the following functions available to you: DateAdd, DayOfWeek (*)
You could try:
DateAdd("dd",1 - (If(DayOfWeek([original_Date])=0,7,DayOfWeek([original_Date]))),[original_Date])
This resets the date (including the time portion) to the previous Monday.
Initially I had tried the simpler formula:
DateAdd("dd",1 - DayOfWeek([original_Date]),[original_Date])
but Sunday is mapped to a zero, so whenever the original day was a Sunday, it was pushed to the following Monday.
It does depend on your original settings so you may have to play around with the numbers a bit.
(*) depending on what the source of your data is, equivalent functions may be available.
Related
I have an Excel table which contains thousands of incident tickets. Each tickets typically carried over few hours or few days, and I usually calculate the total duration by substracting opening date and time from closing date and time.
However I would like to take into account and not count the out of office hours (night time), week-ends and holidays.
I have therefore created two additional reference tables, one which contains the non-working hours (eg everyday after 7pm until 7am in the morning, saturday and sunday all day, and list of public holidays).
Now I need to find some sort of VB macro that would automatically calculate each ticket "real duration" by removing from the total ticket time any time that would fall under that list.
I had a look around this website and other forums, however I could not find what I am looking for. If someone can help me achieve this, I would be extremely grateful.
Best regards,
Alex
You can use the NETWORKDAYS function to calculate the number of working days in the interval. Actually you seem to be perfectly set up for it: it takes start date, end date and a pointer to a range of holidays. By default it counts all days non-weekend.
For calculating the intraday time, you will need some additional magic. assuming that tickets are only opened and closed in bussines hours, it would look like this:
first_day_hrs := dayend - ticketstart
last_day_hrs := ticketend - daystart
inbeetween_hrs := (NETWORKDAYS(ticketstart, ticketend, rng_holidays) - 2) * (dayend - daystart)
total_hrs := first_day_hrs + inbetween_hrs + last_day_hrs
Of course the names should in reality refer to Excel cells. I recommend using lists and/or names.
In MySQL I am using
week(date,3)
to get correct values of week grouping.
How to translate this to PL/SQL? I'v tried the following but what about this 3 from week function in mysql?
TRUNC (created_dt, 'IW')
Oracle is using the NLS setting of the database to determinate how the week number should be calculated and therefor there is no need (according to Oracle) for the '3' part pf the MySQL function. I can image that there still should be useful to have this option but this is once again a sign of the fact that Oracle does not fully understand the needs of working outside USA.
Based on your MYSQL statment above, it returns the week of the specified date e.g. 2012-12-07, 3 as the second argument defines that the third day of the week is assumed as Monday...
If you look at this article it says there are 8 ways MYSQL WEEK() function can behave. So you gotta let us know what results you are trying to achieve by looking for MYSQL Week equivalent function in PL/SQL.
In most staright forward manner, MYSQL WEEK(date[mode]) returns the week number for a given date.
From re-reading your question, the only thing I grabbed that you want to achieve the first feature within PL/SQL and so you are looking for an equivalent function.
And with Oracle it gets slightly RAMEN...
W Week of month (1-5) where week 1 starts on the first day of the month and ends on the seventh. It goes on with how the year starts. E.g. 2012 started on a Sunday, ORACLE THINKS.............. that weeks are Sundays to Saturday.
iw Week of year (1-52, 1-53) based on the ISO standard. Hence the weeks do not necessarily start on Sunday.
WW Week of the year (1-53) where week 1 starts on the first day of the year and continues to the seventh day of the year.
By default Oracle NLS settings are set to following:
NLS_CALENDAR : Gregorian
NLS_DATE_LANGUAGE: AMERICAN
NLS_TERRITORY: AMERICA
So you can suggest Oracle to follow the calendar by manipulating your query level....
You could something like this:
select trunc('2012-12-07','YY') AS week_number,
to_number(to_char(trunc('2012-12-07','YY')+rownum-1,'D')) AS dayNumber_in_week
from dual connect by level <= 365
where to_char('2012-12-07','IW') = 3
and to_char('2012-12-07','DY') = 'MON';
I need to set a chart to start at midnight of the current day and end just before midnight of the next day...
I'm trying to do something like this:
minChartDate = currentDate.fullYear,currentDate.month,currentDate.date,0,0,0,0;
where currentDate:Date; is the day currently selected.
I'm getting an implicit coercion error between the Number to Date type, as if currentDate.fullYear is a Date, but according to the documentation it should be a number. Or is my syntax defining this incorrect? Also wondering if there's a simpler way to get the min and max dates than this!
(the reason I am setting this is so that it starts at midnight rather than at the first data point in the series).
I'm also getting a weird error 'maximum' values of type Date cannot be represented in text.. it said I need a Date type object for the minimum and maximum so I'm really not sure what it's talking about...
this code will make a date object set to 0:00 on today.
var minChartdate:Date= new Date();
minChartdate.hours=0;
minChartdate.minutes=0;
minChartdate.seconds=0;
minChartdate.milliseconds=0;
trace(minChartdate)
To make one for the next day:
var minChartdate:Date= new Date();
minChartdate.time = minChartdate.time+1000*60*60*24 // one day in milliseconds
minChartdate.hours=0;
minChartdate.minutes=0;
minChartdate.seconds=0;
minChartdate.milliseconds=0;
trace(minChartdate);
This script moves the date object forward by 24 hours, and then sets hours, mins,sec,milisecs to 0.
Note: This is not 100% correct solution, it can fail on days, when the hours are adjusted because of daylight saving time changes.
Dates in DB2 AS/400 are an integer, containing the number of days since sometime around the turn of the 20th century.
Question 1: Does anyone know the IBM DB2/AS400 "zero" date? e.g.:
12/30/1899
12/31/1899
1/1/1900
Question 2: Given an "AS/400" date (e.g. 40010) how can you convert that to a CLR DateTime?
DateTime d = new DateTime(40010); //invalid
Some other "zero" dates are:
OLE Automation: 12/30/1899
SQL Server: 1/1/1900
I don't think AS/400 dates are stored internally as some number of days from an epoch date1 (this is the more common term for what you are calling "zero date"). As Tracy Probst said, this is definitely NOT what date fields in native AS/400 physical files look like.2
But that's immaterial if whatever method you are using to extract the data is giving it to you as the number of days since an epoch. Ideally, you should find out what the intended date is by looking directly at the AS/400, or asking someone who can. If the date on the AS/400 is 2009-07-30 and what you are getting is 40022, then you can be pretty confident the epoch date is Jan 1, 1900. If you are getting 40024, then the epoch is Dec 30, 1899. (Though it's of course best to compare a bunch of dates, preferably from different years to guard against possible use of Julian dates.)
Also, as Tracy commented on his own answer, it's exceedingly common for dates to be stored in generic numeric fields (which is what I would guess if your retrieval method is reporting Decimal as the data type), in which case it really has nothing to do with DB2's internal date format anyway. You should be aware that by far the most common date formats stored in AS/400 numeric fields are the following, or variations thereof:
yyyymmdd (Gregorian, ISO 4-digit year)
mmddyy (Gregorian, U.S. 2-digit year)
yyyyddd (so-called Julian, 4-digit year)
yyddd (so-called Julian, 2-digit year)
yymmdd
cyymmdd (IBM's crazy invention with century flag)
The ddd in the Julian dates is the number of days from the beginning of year. The c in IBM's crazy date is 0 for 19yy or 1 for 20yy. I have not heard of anyone who stores days-since-epoch on "The Four Hundred" but maybe you've encountered a convert from another platform. The mainframe heritage of the AS/400 strongly favors human-readable dates.
1The AS/400 (now called IBM i) does have its own data type for dates, and this data type actually does consist internally of a number of days from an epoch. But that epoch is many thousands of years in the past, not somewhere near the turn of the 20th century, and not even near the beginning of the Common Era. IBM likes to call this number of days the Scaliger number, but for most people who study this stuff, it's called the Julian Day Number. As you may have noticed from the main part of my answer, IBM uses the word "Julian" to mean something completely different (and not even related to the Julian calendar). Namely, IBM's so-called "Julian date" is really the ordinal date from ISO 8601.
2The internal format of the date data type is very low-level and mostly hidden from the user (including most programmers). The DSPPFM command, which ostensibly shows the "actual contents" of a file, is at least one step "too late": the value it reports has already been converted from the internal, 4-byte "Scaliger number" to a human-readable form.
Question 1:
I have no idea what the start date is for DB2. Google isn't very helpful anyway. Don't you have any sample data you could use to figure it out?
Update: are you sure the date is stored as a number of days? I found this page that suggests otherwise.
Question 2:
Assuming 1900-01-01 as the start date in this example, where days is the AS/400 date value.
DateTime myDate = new DateTime(1900, 1, 1).AddDays(days);
I don't know the answer for 1. But for 2, you can do something like this:
private DateTime AS400 = new DateTime(1900, 1, 1);
...
DateTime myClrDT = AS400.AddDays(days);
Question 1:
As far as I can tell, there is no "zero date" in an AS/400 phsyical file. If I do a DSPPFM on a phsyical file with a timestamp field in it, the value is stored as a readable timestamp in the format yyyy-MM-ddhh.mm.ss. For example: "2005-08-0207.06.33" for 08/02/2005 at 7:06:33 AM. There can be a zero-date within a particular programming language and that's really where you need to focus. The AS/400 ODBC driver returns the date in a SQL_TYPE_TIMESTAMP field.
Question 2:
It should be as simple as:
DateTime d = Convert.ToDateTime(reader["DateField"]);
I invite other C# experts to edit the response with better C# code.
I've just 5 months of experience in DB2(working on AS400), so i just can show you something
about the way we work with dates. It's true that we consider the 'zero' date in our calculation of the date fields. In our system, the 'zero' date =12/31/1971 0:00.
I don't know if this is the 'only' 'zero' date in AS400.
In our system files, the date we use is stored as the number of days from the 'zero' date(length=5).
So, every time we have to get the date field, from a specified file, we convert this field to get the date in the format : dd/mm/yyyy or yyyy-mm-dd(it depends from the environment where we execute the query). The function is:
date(field+719892), where field is the field where we store the date and 719892 is the number of days we add after each unconverted date we use(it seems like it is the number of days between x-12/31/1971, you can calculate x).
I'll give you on more example:
select date(15+719892) as date1 from library1.file1
The result is: date1=1972-01-15
marc_s had a comment that confused the "zero" dates with "minimum" dates in SQL Server. Just so everyone gets to see the example:
SELECT
CAST(0 AS datetime) AS dateTimeZero,
CAST(0 AS smalldatetime) AS smallDateTimeZero
dateTimeZero smallDateTimeZero
======================= ===================
1900-01-01 00:00:00.000 1900-01-01 00:00:00
Essentially, I have a query that is responsible for fetching all records (with specific filters) within the last month. I'm using Oracle's interval keyword and all was working great until today (December 31st, 2009). The code I'm using is
select (sysdate - interval '1' month) from dual
and the error I get it
ORA-01839: date not valid for month specified
How can I use the interval keyword to be compatible with any date? Or if anyone has a better way of approaching the issue, I'm all ears.
Thank you.
try
select add_months(sysdate,-1) from dual
Being pedantic...
The requirements are not quite specified perfectly unambiguously. What does the business mean by "within the last month"? Most people would take that to mean "within the current calendar month" in which case I'd use:
TRUNC(SYSDATE,'MM')
Otherwise, perhaps they want an arbitrary period of 1 month prior to the current date - but then how do you define that? As you've found, INTERVAL '1' MONTH simply subtracts one from the month portion of the date - e.g. 15-JAN-2009 - INTERVAL '1' MONTH returns 15-DEC-1999. For some dates, this results in an invalid date because not all months have the same number of days.
ADD_MONTHS resolves this by returning the last day in the month, e.g. ADD_MONTHS(31-DEC-2009,-1) returns 30-NOV-2009.
Another possibility is that the business actually wants to use an average month period - e.g. 365/12 which is approximately 30.4. They might want you to use SYSDATE-30, although of course twelve iterations of this will only cover 360 days of the year.